Figure S5

Figure S5 showcases the geomeTriD package, demonstrating how it presents 3D models along with multiple genomic signals mapped onto single-cell 3D structures.

Load Libraries

Present single cell 3D structure for ChAIR data

Here we present 3D genome models with integrated genomic signals derived from Tri-omic, also known as ChAIR (capture of chromatin Accessibility, Interaction, and RNA profiles). This method enables simultaneous mapping of chromatin accessibility, chromatin interactions, and gene expression. Paired-end tag (PET) data are used to reconstruct 3D genome structures, while the accompanying RNA-seq and ATAC-seq signals are visualized along these models.

## plot region
range <- GRanges('chrX:1-20000000')
## prepare features
feature.gr <- getFeatureGR(txdb = TxDb.Mmusculus.UCSC.mm10.knownGene,
                           org = org.Mm.eg.db,
                           range = range)
##   66 genes were dropped because they have exons located on both strands of the
##   same reference sequence or on more than one reference sequence, so cannot be
##   represented by a single genomic range.
##   Use 'single.strand.genes.only=FALSE' to get all the genes in a GRangesList
##   object, or use suppressMessages() to suppress this message.
## 'select()' returned 1:1 mapping between keys and columns
## load the 3D structure for PET data
stage <- c('G1', 'S', 'G2M')
extdata <- system.file('extdata', 'ChAIR', package = 'geomeTriD.documentation')
ChAIR_PET_m <- import3dg(file.path(extdata, 'PET', paste0('patski.allele.', stage, '_2_m.pairs.chrX.3dg.gz')))
ChAIR_PET_p <- import3dg(file.path(extdata, 'PET', paste0('patski.allele.', stage, '_2_p.pairs.chrX.3dg.gz')))
## get the chrX coordinates for maternal and paternal
ChAIR_PET_m <- lapply(ChAIR_PET_m, function(.ele) {
  seqlevelsStyle(.ele) <- 'UCSC'
  .ele$parental <- NULL
  subsetByOverlaps(.ele, range)
  })
ChAIR_PET_p <- lapply(ChAIR_PET_p, function(.ele) {
  seqlevelsStyle(.ele) <- 'UCSC'
  .ele$parental <- NULL
  subsetByOverlaps(.ele, range)
})
# import the signals for ATAC-seq and RNA-seq for maternal and paternal
M <- lapply(stage, function(cc){ ## maternal
  importGenomicSigs(c(ATAC=file.path(extdata, 'ATAC', paste0('patski.allele.', cc, '_2.M.bw')),
                      RNA=file.path(extdata, 'RNA', paste0('patski.allele.', cc, '_2.M.bw'))),
                      range = range,
                    cols = c('darkgreen', 'darkred'),
                    format = 'BigWig')
  })
P <- lapply(stage, function(cc){ ## paternal
  importGenomicSigs(c(ATAC=file.path(extdata, 'ATAC', paste0('patski.allele.', cc, '_2.P.bw')),
                      RNA=file.path(extdata, 'RNA', paste0('patski.allele.', cc, '_2.P.bw'))),
                      range = range,
                    cols = c('darkgreen', 'darkred'),
                    format = 'BigWig')
})
## set backbone color, make it easy to catch the genomic coordinates
resolution <- 3
backbone_colors <- rev(rainbow(n=resolution*length(ChAIR_PET_m[[1]])))
## only label the genes with high expression
labelHighExpGene <- function(sig){
  this.feature.gr <- feature.gr
  expressed <- sig$RNA$dat[sig$RNA$dat$score>100]
  this.feature.gr$label[countOverlaps(feature.gr, expressed)==0] <- NA
  ## remove the genes with big size
  this.feature.gr$label[width(this.feature.gr)>100000] <- NA
  ## only show the first gene label if multiple high expressed gene
  ## in the same region
  l.rle <- rle(!is.na(this.feature.gr$label))
  l.rle$values[l.rle$lengths<=5] <- TRUE ## merge the region with small gap
  l.rle <- rle(inverse.rle(l.rle))
  l <- cumsum(l.rle$lengths)
  this.feature.gr$label[-l[l.rle$values]] <- NA
  return(this.feature.gr)
}

## create threeJsGeometry objects for maternal and paternal cells
M_cells <- mapply(ChAIR_PET_m, M, FUN=function(model, sig){
  cell <- view3dStructure(model,
                  feature.gr = labelHighExpGene(sig),
                  genomicSigs = sig,
                  signalTransformFun = log1p,
                  lwd.maxGenomicSigs = 8,
                  reverseGenomicSigs = FALSE,
                  renderer = 'none',
                  resolution = resolution,
                  col.backbone = rev(rainbow(n=resolution*length(model))),
                  lwd.backbone = 0.25,
                  lwd.gene = 1,
                  region = range,
                  show_coor = FALSE,
                  cluster3Dpoints = TRUE)
}, SIMPLIFY = FALSE)
P_cells <- mapply(ChAIR_PET_p, P, FUN=function(model, sig){
  cell <- view3dStructure(model,
                  feature.gr = labelHighExpGene(sig),
                  genomicSigs = sig,
                  signalTransformFun = log1p,
                  lwd.maxGenomicSigs = 8,
                  reverseGenomicSigs = FALSE,
                  renderer = 'none',
                  resolution = resolution,
                  col.backbone = rev(rainbow(n=resolution*length(model))),
                  lwd.backbone = 0.25,
                  lwd.gene = 1,
                  region = range,
                  show_coor = FALSE,
                  cluster3Dpoints = TRUE)
}, SIMPLIFY = FALSE)

## show the maternal and paternal structures side by side
showPairs(M_cells[[1]], P_cells[[1]], title=c('mat G1', 'pat G1')) #G1
showPairs(M_cells[[2]], P_cells[[2]], title=c('mat S', 'pat S')) #S
showPairs(M_cells[[3]], P_cells[[3]], title=c('mat G2M', 'pat G2M')) #G2M
## check the size 
getV <- function(points){
  vol <- convhulln(as.matrix(mcols(points)), options='Fa')$vol
}
sapply(ChAIR_PET_m, getV)
## [1] 1.3883935 2.1113253 0.6169364
sapply(ChAIR_PET_p, getV)
## [1] 0.7920844 1.2108770 0.3453040

SessionInfo

## R version 4.5.2 (2025-10-31)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.3 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so;  LAPACK version 3.12.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: Etc/UTC
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] grid      stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] GenomeInfoDb_1.46.0                      
##  [2] geometry_0.5.2                           
##  [3] org.Mm.eg.db_3.22.0                      
##  [4] TxDb.Mmusculus.UCSC.mm10.knownGene_3.10.0
##  [5] GenomicFeatures_1.62.0                   
##  [6] AnnotationDbi_1.72.0                     
##  [7] Biobase_2.70.0                           
##  [8] colorRamps_2.3.4                         
##  [9] GenomicRanges_1.62.0                     
## [10] Seqinfo_1.0.0                            
## [11] IRanges_2.44.0                           
## [12] S4Vectors_0.48.0                         
## [13] BiocGenerics_0.56.0                      
## [14] generics_0.1.4                           
## [15] geomeTriD.documentation_0.0.6            
## [16] geomeTriD_1.5.0                          
## 
## loaded via a namespace (and not attached):
##   [1] BiocIO_1.20.0               bitops_1.0-9               
##   [3] filelock_1.0.3              tibble_3.3.0               
##   [5] R.oo_1.27.1                 XML_3.99-0.20              
##   [7] rpart_4.1.24                lifecycle_1.0.4            
##   [9] httr2_1.2.1                 aricode_1.0.3              
##  [11] globals_0.18.0              lattice_0.22-7             
##  [13] ensembldb_2.34.0            MASS_7.3-65                
##  [15] backports_1.5.0             magrittr_2.0.4             
##  [17] Hmisc_5.2-4                 sass_0.4.10                
##  [19] rmarkdown_2.30              jquerylib_0.1.4            
##  [21] yaml_2.3.10                 plotrix_3.8-4              
##  [23] Gviz_1.54.0                 DBI_1.2.3                  
##  [25] RColorBrewer_1.1-3          abind_1.4-8                
##  [27] R.utils_2.13.0              AnnotationFilter_1.34.0    
##  [29] biovizBase_1.58.0           RCurl_1.98-1.17            
##  [31] rgl_1.3.24                  nnet_7.3-20                
##  [33] VariantAnnotation_1.56.0    rappdirs_0.3.3             
##  [35] grImport_0.9-7              listenv_0.10.0             
##  [37] parallelly_1.45.1           pkgdown_2.2.0              
##  [39] codetools_0.2-20            DelayedArray_0.36.0        
##  [41] tidyselect_1.2.1            UCSC.utils_1.6.0           
##  [43] farver_2.1.2                matrixStats_1.5.0          
##  [45] BiocFileCache_3.0.0         base64enc_0.1-3            
##  [47] GenomicAlignments_1.46.0    jsonlite_2.0.0             
##  [49] trackViewer_1.47.0          progressr_0.18.0           
##  [51] Formula_1.2-5               systemfonts_1.3.1          
##  [53] dbscan_1.2.3                tools_4.5.2                
##  [55] progress_1.2.3              ragg_1.5.0                 
##  [57] strawr_0.0.92               Rcpp_1.1.0                 
##  [59] glue_1.8.0                  gridExtra_2.3              
##  [61] SparseArray_1.10.1          xfun_0.54                  
##  [63] MatrixGenerics_1.22.0       dplyr_1.1.4                
##  [65] fastmap_1.2.0               latticeExtra_0.6-31        
##  [67] rhdf5filters_1.22.0         digest_0.6.38              
##  [69] R6_2.6.1                    textshaping_1.0.4          
##  [71] colorspace_2.1-2            jpeg_0.1-11                
##  [73] dichromat_2.0-0.1           biomaRt_2.66.0             
##  [75] RSQLite_2.4.4               cigarillo_1.0.0            
##  [77] R.methodsS3_1.8.2           data.table_1.17.8          
##  [79] rtracklayer_1.70.0          prettyunits_1.2.0          
##  [81] InteractionSet_1.38.0       httr_1.4.7                 
##  [83] htmlwidgets_1.6.4           S4Arrays_1.10.0            
##  [85] pkgconfig_2.0.3             gtable_0.3.6               
##  [87] blob_1.2.4                  S7_0.2.0                   
##  [89] XVector_0.50.0              htmltools_0.5.8.1          
##  [91] ProtGenerics_1.42.0         clue_0.3-66                
##  [93] scales_1.4.0                png_0.1-8                  
##  [95] knitr_1.50                  rstudioapi_0.17.1          
##  [97] rjson_0.2.23                magic_1.6-1                
##  [99] checkmate_2.3.3             curl_7.0.0                 
## [101] cachem_1.1.0                rhdf5_2.54.0               
## [103] stringr_1.6.0               parallel_4.5.2             
## [105] foreign_0.8-90              restfulr_0.0.16            
## [107] desc_1.4.3                  pillar_1.11.1              
## [109] vctrs_0.6.5                 RANN_2.6.2                 
## [111] dbplyr_2.5.1                cluster_2.1.8.1            
## [113] htmlTable_2.4.3             evaluate_1.0.5             
## [115] cli_3.6.5                   compiler_4.5.2             
## [117] Rsamtools_2.26.0            rlang_1.1.6                
## [119] crayon_1.5.3                future.apply_1.20.0        
## [121] interp_1.1-6                fs_1.6.6                   
## [123] stringi_1.8.7               deldir_2.0-4               
## [125] BiocParallel_1.44.0         txdbmaker_1.6.0            
## [127] Biostrings_2.78.0           lazyeval_0.2.2             
## [129] Matrix_1.7-4                BSgenome_1.78.0            
## [131] hms_1.1.4                   bit64_4.6.0-1              
## [133] future_1.67.0               ggplot2_4.0.0              
## [135] Rhdf5lib_1.32.0             KEGGREST_1.50.0            
## [137] SummarizedExperiment_1.40.0 igraph_2.2.1               
## [139] memoise_2.0.1               bslib_0.9.0                
## [141] bit_4.6.0