Figure S5 showcases the geomeTriD package, demonstrating
how it presents 3D models along with multiple genomic signals mapped
onto single-cell 3D structures.
library(geomeTriD)
library(geomeTriD.documentation)
library(GenomicRanges)
library(GenomeInfoDb)
library(colorRamps)
library(TxDb.Mmusculus.UCSC.mm10.knownGene)
library(org.Mm.eg.db)
library(geometry)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
## 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
## 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