diff --git a/analyses/cell-type-wilms-tumor-14/README.md b/analyses/cell-type-wilms-tumor-14/README.md index ba9ff9346..e962b3c2e 100644 --- a/analyses/cell-type-wilms-tumor-14/README.md +++ b/analyses/cell-type-wilms-tumor-14/README.md @@ -31,7 +31,7 @@ This would include: ## Usage -* Run Rscripts with command line +* Run main pipeline with command line ```bash cd /path/to/OpenScPCA-analysis cd analyses/cell-type-wilms-tumor-14 @@ -74,4 +74,7 @@ sudo apt install -y libglpk40 \ ## Computational resources -Analysis could be executed on a virtual computer ([Standard-4XL](https://openscpca.readthedocs.io/en/latest/aws/lsfr/creating-vcs/)) via AWS Lightsail for Research. \ No newline at end of file +Analysis could be executed on a virtual computer ([Standard-4XL](https://openscpca.readthedocs.io/en/latest/aws/lsfr/creating-vcs/)) via AWS Lightsail for Research. + +## Exploratory analysis +In addition to the main pipeline, some exploratory analysis in R notebooks are added into the `./exploratory_analysis` folder, including CNV analysis. Check `./exploratory_analysis/README.md` for more details. \ No newline at end of file diff --git a/analyses/cell-type-wilms-tumor-14/components/dependencies.R b/analyses/cell-type-wilms-tumor-14/components/dependencies.R index ae80dc0ac..774e95b61 100644 --- a/analyses/cell-type-wilms-tumor-14/components/dependencies.R +++ b/analyses/cell-type-wilms-tumor-14/components/dependencies.R @@ -1,2 +1,3 @@ # R dependencies not captured by `renv` # library("missing_package") +library(rtracklayer) diff --git a/analyses/cell-type-wilms-tumor-14/exploratory_analysis/03_cnv/03_copykat_SCPCL000850.Rmd b/analyses/cell-type-wilms-tumor-14/exploratory_analysis/03_cnv/03_copykat_SCPCL000850.Rmd new file mode 100644 index 000000000..e342a560d --- /dev/null +++ b/analyses/cell-type-wilms-tumor-14/exploratory_analysis/03_cnv/03_copykat_SCPCL000850.Rmd @@ -0,0 +1,124 @@ +--- +title: "Exploratory analysis using Copykat" +author: "Jingxuan Chen" +date: "`r Sys.Date()`" +output: html_document +--- + +## Introduction + +Here we test `CopyKat` to analyze the CNV profile for Wilms tumor sample (SCPCL000850), aiming to identify potential tumor cells from normal cells. + +Before running this notebook, one should first generate `CopyKat` outputs as in `03_runCopyKat.R`. + +## Setup + +### Packages + +```{r packages} +suppressPackageStartupMessages({ + library(dplyr) + library(Seurat) + library(copykat) + library(ggplot2) +}) +``` + +### Paths + + +#### Base directories + +```{r base paths} +# The base path for the OpenScPCA repository, found by its (hidden) .git directory +path_repo <- rprojroot::find_root(rprojroot::is_git_root) + +# The path to this module +path_anal <- file.path(path_repo,"analyses","cell-type-wilms-tumor-14") +``` + +#### Input and output files + +Only run for one sample + +```{r paths} +library_id <- "SCPCL000850" +scratch_out_dir <- file.path(path_anal, "scratch", "03_cnv","copykat") +dir.create(scratch_out_dir, showWarnings = FALSE, recursive = TRUE) +library_out_dir <- file.path(scratch_out_dir, library_id) +dir.create(library_out_dir, showWarnings = FALSE, recursive = TRUE) + +## Input files +# load pre-processed sample objs & anchor transfer results +obj <- SeuratObject::LoadSeuratRds( file.path(path_anal,"scratch","00_preprocessing_rds",paste0(library_id,".rdsSeurat")) ) +level <- "compartment" +predictions <- read.csv( file.path(path_anal, "results", "01_anchor_transfer_seurat", paste0(library_id, "_", level,".csv")) ) +obj <- AddMetaData(object = obj, metadata = predictions) +copykat_result <- readr::read_rds( file = file.path(library_out_dir, paste0(library_id, "_copykat_resultobj.rds")) ) +copykat_result_noref <- readr::read_rds( file = file.path(library_out_dir, paste0(library_id, "_noref_copykat_resultobj.rds")) ) + +``` + +```{r images} +heatmap_wref <- file.path(library_out_dir, paste0(library_id, "_copykat_heatmap.jpeg")) +heatmap_noref <- file.path(library_out_dir, paste0(library_id, "_noref_copykat_heatmap.jpeg")) +``` + +## Analysis content + +#### Run CopyKat with normal cells + +Here, "immune" cells annotated with anchor transfer were used as reference normal cells. Here is the heatmap generated by the software: + +```{r, echo=FALSE, out.width = '100%'} +knitr::include_graphics(heatmap_wref) +``` + +Frequency of predicted `aneuploid`, `diploid`, and `not.defined` categories. + +```{r} +copykat_df <- copykat_result$prediction %>% + select(copykat.pred) %>% + rename(c("ref.copykat" = "copykat.pred")) +table(copykat_df) +``` + +Plot CopyKat identifications onto UMAP. + +```{r} +obj <- AddMetaData(object = obj, metadata = copykat_df) +DimPlot(obj, group.by = "ref.copykat", alpha = 0.3) +``` + +#### Run CopyKat without normal cells + +Here, no normal cells were provided to CopyKat. + +```{r, echo=FALSE, out.width = '100%'} +knitr::include_graphics(heatmap_noref) +``` + +Frequency of predicted `aneuploid`, `diploid`, and `not.defined` categories. + +```{r} +copykat_noref_df <- copykat_result_noref$prediction %>% + select(copykat.pred) %>% + rename(c("noref.copykat" = "copykat.pred")) +table(copykat_noref_df) +``` + +Plot CopyKat identifications onto UMAP. + +```{r} +obj <- AddMetaData(object = obj, metadata = copykat_noref_df) +DimPlot(obj, group.by = "noref.copykat", alpha = 0.3) +``` + +In this Wilms tumor sample (SCPCL000850), it's likely that CopyKat is not working well: (i) The result with or without specifying normal cells are not consistent; (ii) From the heatmap, no much differences in CNV profile could be observed. + +## Session Info + +```{r session info} +# record the versions of the packages used in this analysis and other environment information +sessionInfo() +``` diff --git a/analyses/cell-type-wilms-tumor-14/exploratory_analysis/03_cnv/03_copykat_SCPCL000850.html b/analyses/cell-type-wilms-tumor-14/exploratory_analysis/03_cnv/03_copykat_SCPCL000850.html new file mode 100644 index 000000000..0fe0c828c --- /dev/null +++ b/analyses/cell-type-wilms-tumor-14/exploratory_analysis/03_cnv/03_copykat_SCPCL000850.html @@ -0,0 +1,574 @@ + + + + +
+ + + + + + + + + + +Here we test CopyKat
to analyze the CNV profile for
+Wilms tumor sample (SCPCL000850), aiming to identify potential tumor
+cells from normal cells.
Before running this notebook, one should first generate
+CopyKat
outputs as in 03_runCopyKat.R
.
suppressPackageStartupMessages({
+ library(dplyr)
+ library(Seurat)
+ library(copykat)
+ library(ggplot2)
+})
+# The base path for the OpenScPCA repository, found by its (hidden) .git directory
+path_repo <- rprojroot::find_root(rprojroot::is_git_root)
+
+# The path to this module
+path_anal <- file.path(path_repo,"analyses","cell-type-wilms-tumor-14")
+Only run for one sample
+library_id <- "SCPCL000850"
+scratch_out_dir <- file.path(path_anal, "scratch", "03_cnv","copykat")
+dir.create(scratch_out_dir, showWarnings = FALSE, recursive = TRUE)
+library_out_dir <- file.path(scratch_out_dir, library_id)
+dir.create(library_out_dir, showWarnings = FALSE, recursive = TRUE)
+
+## Input files
+# load pre-processed sample objs & anchor transfer results
+obj <- SeuratObject::LoadSeuratRds( file.path(path_anal,"scratch","00_preprocessing_rds",paste0(library_id,".rdsSeurat")) )
+level <- "compartment"
+predictions <- read.csv( file.path(path_anal, "results", "01_anchor_transfer_seurat", paste0(library_id, "_", level,".csv")) )
+obj <- AddMetaData(object = obj, metadata = predictions)
+copykat_result <- readr::read_rds( file = file.path(library_out_dir, paste0(library_id, "_copykat_resultobj.rds")) )
+copykat_result_noref <- readr::read_rds( file = file.path(library_out_dir, paste0(library_id, "_noref_copykat_resultobj.rds")) )
+heatmap_wref <- file.path(library_out_dir, paste0(library_id, "_copykat_heatmap.jpeg"))
+heatmap_noref <- file.path(library_out_dir, paste0(library_id, "_noref_copykat_heatmap.jpeg"))
+Here, “immune” cells annotated with anchor transfer were used as +reference normal cells. Here is the heatmap generated by the +software:
+ +Frequency of predicted aneuploid
, diploid
,
+and not.defined
categories.
copykat_df <- copykat_result$prediction %>%
+ select(copykat.pred) %>%
+ rename(c("ref.copykat" = "copykat.pred"))
+table(copykat_df)
+## ref.copykat
+## aneuploid diploid not.defined
+## 1089 1276 578
+Plot CopyKat identifications onto UMAP.
+obj <- AddMetaData(object = obj, metadata = copykat_df)
+DimPlot(obj, group.by = "ref.copykat", alpha = 0.3)
+
+Here, no normal cells were provided to CopyKat.
+ +Frequency of predicted aneuploid
, diploid
,
+and not.defined
categories.
copykat_noref_df <- copykat_result_noref$prediction %>%
+ select(copykat.pred) %>%
+ rename(c("noref.copykat" = "copykat.pred"))
+table(copykat_noref_df)
+## noref.copykat
+## aneuploid diploid not.defined
+## 1458 907 578
+Plot CopyKat identifications onto UMAP.
+obj <- AddMetaData(object = obj, metadata = copykat_noref_df)
+DimPlot(obj, group.by = "noref.copykat", alpha = 0.3)
+
+In this Wilms tumor sample (SCPCL000850), it’s likely that CopyKat is +not working well: (i) The result with or without specifying normal cells +are not consistent; (ii) From the heatmap, no much differences in CNV +profile could be observed.
+# record the versions of the packages used in this analysis and other environment information
+sessionInfo()
+## R version 4.4.0 (2024-04-24)
+## Platform: x86_64-pc-linux-gnu
+## Running under: Ubuntu 22.04.4 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.20.so; LAPACK version 3.10.0
+##
+## locale:
+## [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
+## [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
+## [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
+## [10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
+##
+## time zone: Etc/UTC
+## tzcode source: system (glibc)
+##
+## attached base packages:
+## [1] stats graphics grDevices datasets utils methods base
+##
+## other attached packages:
+## [1] ggplot2_3.5.1 copykat_1.1.0 Seurat_5.1.0 SeuratObject_5.0.2
+## [5] sp_2.1-4 dplyr_1.1.4
+##
+## loaded via a namespace (and not attached):
+## [1] RColorBrewer_1.1-3 jsonlite_1.8.9 magrittr_2.0.3
+## [4] spatstat.utils_3.1-0 farver_2.1.2 rmarkdown_2.28
+## [7] vctrs_0.6.5 ROCR_1.0-11 spatstat.explore_3.3-2
+## [10] htmltools_0.5.8.1 sass_0.4.9 sctransform_0.4.1
+## [13] parallelly_1.38.0 KernSmooth_2.23-22 bslib_0.8.0
+## [16] htmlwidgets_1.6.4 ica_1.0-3 plyr_1.8.9
+## [19] plotly_4.10.4 zoo_1.8-12 cachem_1.1.0
+## [22] igraph_2.0.3 mime_0.12 lifecycle_1.0.4
+## [25] pkgconfig_2.0.3 Matrix_1.7-0 R6_2.5.1
+## [28] fastmap_1.2.0 fitdistrplus_1.2-1 future_1.34.0
+## [31] shiny_1.9.1 digest_0.6.37 colorspace_2.1-1
+## [34] patchwork_1.3.0 rprojroot_2.0.4 tensor_1.5
+## [37] RSpectra_0.16-2 irlba_2.3.5.1 labeling_0.4.3
+## [40] progressr_0.14.0 fansi_1.0.6 spatstat.sparse_3.1-0
+## [43] httr_1.4.7 polyclip_1.10-7 abind_1.4-8
+## [46] compiler_4.4.0 withr_3.0.1 fastDummies_1.7.4
+## [49] highr_0.11 MASS_7.3-60.2 tools_4.4.0
+## [52] lmtest_0.9-40 httpuv_1.6.15 future.apply_1.11.2
+## [55] goftest_1.2-3 glue_1.8.0 nlme_3.1-164
+## [58] promises_1.3.0 grid_4.4.0 Rtsne_0.17
+## [61] cluster_2.1.6 reshape2_1.4.4 generics_0.1.3
+## [64] gtable_0.3.5 spatstat.data_3.1-2 tzdb_0.4.0
+## [67] tidyr_1.3.1 data.table_1.16.0 hms_1.1.3
+## [70] utf8_1.2.4 spatstat.geom_3.3-3 RcppAnnoy_0.0.22
+## [73] ggrepel_0.9.6 RANN_2.6.2 pillar_1.9.0
+## [76] stringr_1.5.1 spam_2.10-0 RcppHNSW_0.6.0
+## [79] later_1.3.2 splines_4.4.0 lattice_0.22-6
+## [82] renv_1.0.7 survival_3.5-8 deldir_2.0-4
+## [85] tidyselect_1.2.1 miniUI_0.1.1.1 pbapply_1.7-2
+## [88] knitr_1.48 gridExtra_2.3 scattermore_1.2
+## [91] xfun_0.47 matrixStats_1.4.1 stringi_1.8.4
+## [94] lazyeval_0.2.2 yaml_2.3.10 evaluate_1.0.0
+## [97] codetools_0.2-20 tibble_3.2.1 BiocManager_1.30.25
+## [100] cli_3.6.3 uwot_0.2.2 xtable_1.8-4
+## [103] reticulate_1.39.0 munsell_0.5.1 jquerylib_0.1.4
+## [106] Rcpp_1.0.13 globals_0.16.3 spatstat.random_3.3-2
+## [109] png_0.1-8 spatstat.univar_3.0-1 parallel_4.4.0
+## [112] readr_2.1.5 dotCall64_1.1-1 listenv_0.9.1
+## [115] viridisLite_0.4.2 scales_1.3.0 ggridges_0.5.6
+## [118] leiden_0.4.3.1 purrr_1.0.2 rlang_1.1.4
+## [121] cowplot_1.1.3
+Here we test inferCNV
to analyze the CNV profile for
+Wilms tumor sample (SCPCL000850), aiming to identify potential tumor
+cells from normal cells.
Before running this notebook, one should first generate
+inferCNV
outputs as in 03_runInferCNV.R
.
suppressPackageStartupMessages({
+ library(dplyr)
+ library(Seurat)
+ library(infercnv)
+ library(ggplot2)
+})
+# The base path for the OpenScPCA repository, found by its (hidden) .git directory
+path_repo <- rprojroot::find_root(rprojroot::is_git_root)
+
+# The path to this module
+path_anal <- file.path(path_repo,"analyses","cell-type-wilms-tumor-14")
+Only run for one sample
+library_id <- "SCPCL000850"
+scratch_out_dir <- file.path(path_anal, "scratch", "03_cnv","infercnv")
+dir.create(scratch_out_dir, showWarnings = FALSE, recursive = TRUE)
+library_out_dir <- file.path(scratch_out_dir, library_id)
+dir.create(library_out_dir, showWarnings = FALSE, recursive = TRUE)
+
+## Input files
+# load pre-processed sample objs & anchor transfer results
+obj <- SeuratObject::LoadSeuratRds( file.path(path_anal,"scratch","00_preprocessing_rds",paste0(library_id,".rdsSeurat")) )
+level <- "compartment"
+predictions <- read.csv( file.path(path_anal, "results", "01_anchor_transfer_seurat", paste0(library_id, "_", level,".csv")) )
+obj <- AddMetaData(object = obj, metadata = predictions)
+infercnv_result <- readr::read_rds( file = file.path(library_out_dir, "run.final.infercnv_obj") )
+# add infercnv output to seurat object
+obj_cnv <- infercnv::add_to_seurat(
+ seurat_obj = obj,
+ infercnv_output_path = library_out_dir
+)
+heatmap_wref <- file.path(library_out_dir, "infercnv.png")
+normal_level <- "immune"
+Here, “immune” cells annotated with anchor transfer were used as +reference normal cells. Here is the heatmap generated by the +software:
+ +We could observe some different CNV profiles between “fetal_nephron” +and “stroma”, especially chr1 and chr11. However, it’s hard to observe +any different CNV profiles within the “fetal_nephron” subgroups.
+inferCNV
outputs results for each Chromosome. Thus, I
+applied several ways to summarize the overall CNV profile.
Based on this
+Biostars discussion, I calculated a cnv_score
, which
+basically indicates the proportion of CNVs across all genes.
## summary strategy 1 https://www.biostars.org/p/9573777/
+scores <- apply(infercnv_result@expr.data, 2 ,function(x){ sum(x < 0.95 | x > 1.05)/length(x) }) %>%
+ as.data.frame() %>%
+ mutate(pred = obj$predicted.id) %>%
+ mutate(cnv_score = ifelse(
+ pred == normal_level,
+ NA,
+ .
+ ))
+Ideally, we should observe bimodal distribution for this score, +indicating the CNV difference between normal and tumor cells. However, +here we could get a distribution close to normal.
+hist(scores$cnv_score, breaks = 100)
+
+By plotting the CNV score onto UMAP, no clear pattern is shown.
+obj <- AddMetaData(object = obj, metadata = scores)
+FeaturePlot(obj, features = "cnv_score", alpha = 0.3) +
+ scale_color_viridis_c()
+## Scale for colour is already present.
+## Adding another scale for colour, which will replace the existing scale.
+
+This strategy to summary CNV results is based on cell-type-ewings
+module.
## summary strategy 2 ewings analysis, based on number of chr that have cnv
+cnv_df <- obj_cnv@meta.data %>%
+ select(matches("predicted.id") | starts_with("has_cnv_chr") & !matches("has_cnv_chrMT")) %>%
+ mutate(count_cnv_chr = ifelse(predicted.id == normal_level,
+ NA,
+ rowSums(across(starts_with("has_cnv_chr")))
+ ) )
+hist(cnv_df$count_cnv_chr)
+
+obj <- AddMetaData(object = obj, metadata = cnv_df)
+FeaturePlot(obj, features = "count_cnv_chr", alpha = 0.3) +
+ scale_color_viridis_c()
+## Scale for colour is already present.
+## Adding another scale for colour, which will replace the existing scale.
+
+This strategy to summary CNV results is based on cell-type-ewings
+module.
## summary strategy 3 ewings analysis, based on number of chr that have cn
+chr_weights <- infercnv_result@gene_order |>
+ as.data.frame() |>
+ dplyr::count(chr) |>
+ # only keep chr 1-22, drops MT and GL chr
+ dplyr::filter(chr %in% glue::glue("chr{seq(1,22)}")) |>
+ dplyr::pull(n)
+
+cnv_df <- obj_cnv@meta.data %>%
+ select(matches("predicted.id") | starts_with("proportion_scaled_cnv_chr") & !ends_with("chrMT")) %>%
+ rowwise() %>%
+ mutate(weight_mean = ifelse(
+ predicted.id == normal_level,
+ NA,
+ weighted.mean(across(starts_with("proportion_scaled_cnv_chr")), chr_weights/sum(chr_weights))
+ ) )
+hist(cnv_df$weight_mean)
+
+obj <- AddMetaData(object = obj, metadata = cnv_df)
+## Warning: Setting row names on a tibble is deprecated.
+FeaturePlot(obj, features = "weight_mean", alpha = 0.3) +
+ scale_color_viridis_c()
+## Scale for colour is already present.
+## Adding another scale for colour, which will replace the existing scale.
+
+In conclusion, the heatmap generated by inferCNV
+indicates different CNV profiles between fetal_nephron
and
+stroma
, especially in Chr1. However, none of the three
+summary strategies seem working.
# record the versions of the packages used in this analysis and other environment information
+sessionInfo()
+## R version 4.4.0 (2024-04-24)
+## Platform: x86_64-pc-linux-gnu
+## Running under: Ubuntu 22.04.4 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.20.so; LAPACK version 3.10.0
+##
+## locale:
+## [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
+## [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
+## [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
+## [10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
+##
+## time zone: Etc/UTC
+## tzcode source: system (glibc)
+##
+## attached base packages:
+## [1] stats graphics grDevices datasets utils methods base
+##
+## other attached packages:
+## [1] ggplot2_3.5.1 infercnv_1.20.0 Seurat_5.1.0 SeuratObject_5.0.2
+## [5] sp_2.1-4 dplyr_1.1.4
+##
+## loaded via a namespace (and not attached):
+## [1] RcppAnnoy_0.0.22 splines_4.4.0
+## [3] later_1.3.2 bitops_1.0-8
+## [5] tibble_3.2.1 polyclip_1.10-7
+## [7] fastDummies_1.7.4 lifecycle_1.0.4
+## [9] rprojroot_2.0.4 fastcluster_1.2.6
+## [11] edgeR_4.2.1 doParallel_1.0.17
+## [13] globals_0.16.3 lattice_0.22-6
+## [15] MASS_7.3-60.2 magrittr_2.0.3
+## [17] limma_3.60.4 plotly_4.10.4
+## [19] sass_0.4.9 rmarkdown_2.28
+## [21] jquerylib_0.1.4 yaml_2.3.10
+## [23] httpuv_1.6.15 sctransform_0.4.1
+## [25] spam_2.10-0 spatstat.sparse_3.1-0
+## [27] reticulate_1.39.0 cowplot_1.1.3
+## [29] pbapply_1.7-2 RColorBrewer_1.1-3
+## [31] multcomp_1.4-26 abind_1.4-8
+## [33] zlibbioc_1.50.0 Rtsne_0.17
+## [35] GenomicRanges_1.56.1 purrr_1.0.2
+## [37] BiocGenerics_0.50.0 TH.data_1.1-2
+## [39] sandwich_3.1-1 GenomeInfoDbData_1.2.12
+## [41] IRanges_2.38.1 S4Vectors_0.42.1
+## [43] ggrepel_0.9.6 irlba_2.3.5.1
+## [45] listenv_0.9.1 spatstat.utils_3.1-0
+## [47] goftest_1.2-3 RSpectra_0.16-2
+## [49] spatstat.random_3.3-2 fitdistrplus_1.2-1
+## [51] parallelly_1.38.0 leiden_0.4.3.1
+## [53] codetools_0.2-20 coin_1.4-3
+## [55] DelayedArray_0.30.1 tidyselect_1.2.1
+## [57] futile.logger_1.4.3 UCSC.utils_1.0.0
+## [59] farver_2.1.2 rjags_4-16
+## [61] matrixStats_1.4.1 stats4_4.4.0
+## [63] spatstat.explore_3.3-2 jsonlite_1.8.9
+## [65] progressr_0.14.0 ggridges_0.5.6
+## [67] survival_3.5-8 iterators_1.0.14
+## [69] foreach_1.5.2 tools_4.4.0
+## [71] ica_1.0-3 Rcpp_1.0.13
+## [73] glue_1.8.0 gridExtra_2.3
+## [75] SparseArray_1.4.8 xfun_0.47
+## [77] MatrixGenerics_1.16.0 GenomeInfoDb_1.40.1
+## [79] withr_3.0.1 formatR_1.14
+## [81] BiocManager_1.30.25 fastmap_1.2.0
+## [83] fansi_1.0.6 caTools_1.18.3
+## [85] digest_0.6.37 parallelDist_0.2.6
+## [87] R6_2.5.1 mime_0.12
+## [89] colorspace_2.1-1 scattermore_1.2
+## [91] gtools_3.9.5 tensor_1.5
+## [93] spatstat.data_3.1-2 utf8_1.2.4
+## [95] tidyr_1.3.1 generics_0.1.3
+## [97] renv_1.0.7 data.table_1.16.0
+## [99] httr_1.4.7 htmlwidgets_1.6.4
+## [101] S4Arrays_1.4.1 uwot_0.2.2
+## [103] pkgconfig_2.0.3 gtable_0.3.5
+## [105] modeltools_0.2-23 lmtest_0.9-40
+## [107] SingleCellExperiment_1.26.0 XVector_0.44.0
+## [109] htmltools_0.5.8.1 dotCall64_1.1-1
+## [111] scales_1.3.0 Biobase_2.64.0
+## [113] png_0.1-8 phyclust_0.1-34
+## [115] spatstat.univar_3.0-1 knitr_1.48
+## [117] lambda.r_1.2.4 tzdb_0.4.0
+## [119] reshape2_1.4.4 coda_0.19-4.1
+## [121] nlme_3.1-164 cachem_1.1.0
+## [123] zoo_1.8-12 stringr_1.5.1
+## [125] KernSmooth_2.23-22 parallel_4.4.0
+## [127] miniUI_0.1.1.1 libcoin_1.0-10
+## [129] pillar_1.9.0 grid_4.4.0
+## [131] vctrs_0.6.5 gplots_3.1.3.1
+## [133] RANN_2.6.2 promises_1.3.0
+## [135] xtable_1.8-4 cluster_2.1.6
+## [137] evaluate_1.0.0 readr_2.1.5
+## [139] locfit_1.5-9.10 mvtnorm_1.3-1
+## [141] cli_3.6.3 compiler_4.4.0
+## [143] futile.options_1.0.1 rlang_1.1.4
+## [145] crayon_1.5.3 future.apply_1.11.2
+## [147] labeling_0.4.3 argparse_2.2.3
+## [149] plyr_1.8.9 stringi_1.8.4
+## [151] viridisLite_0.4.2 deldir_2.0-4
+## [153] munsell_0.5.1 lazyeval_0.2.2
+## [155] spatstat.geom_3.3-3 Matrix_1.7-0
+## [157] RcppHNSW_0.6.0 hms_1.1.3
+## [159] patchwork_1.3.0 future_1.34.0
+## [161] statmod_1.5.0 shiny_1.9.1
+## [163] highr_0.11 SummarizedExperiment_1.34.0
+## [165] ROCR_1.0-11 igraph_2.0.3
+## [167] RcppParallel_5.1.9 bslib_0.8.0
+## [169] ape_5.8
+