Mouse Brain Open Problem preview

Preamble

# Util libs
library(assertthat)
library(ggplot2)
library(zeallot)
library(conflicted)
library(Matrix)
library(stringr)
# Data processing libs
if (!suppressWarnings(require(COTAN))) {
  devtools::load_all("~/dev/COTAN/COTAN/")
}
library(SingleCellExperiment)
library(S4Vectors)
library(hdf5r)
library(hdf5r.Extra)

conflicts_prefer(zeallot::`%->%`, zeallot::`%<-%`)
conflicts_prefer(base::setdiff)
conflicts_prefer(Matrix::unname)

options(parallelly.fork.enable = TRUE)

setLoggingLevel(2L)
setLoggingFile(file.path(".", "Dataset_Cleanup.log"))

List input files

Data come from site.

A murine brain atlas with adjacent cell types as assumed benchmark truth, inferred from deconvolution proportion correlations using matching 10x Visium slides (see Dimitrov et al., 2022).

The sequencing is SMARTer (Smart-seq–type full-length scRNA-seq, plate-based) so it is micro-wells based (no UMI).

inDir <- file.path("MouseBrainOpenProblem/")
outDir <- file.path("MouseBrainOpenProblem/")

list.files(path = inDir)
[1] "dataset.h5ad"                  "DatasetCleaning.log"          
[3] "Mouse.MitoCarta3.0.xls"        "MouseBrainOP_COTAN_raw.RDS"   
[5] "MouseBrainOPCOTAN-Cleaned.RDS" "Note"                         
h5adFile <- "MouseBrainOpenProblem/dataset.h5ad"

Inspect h5ad file

h5 <- H5File$new(h5adFile, mode = "r")

for (nm in names(h5)) {
  cat("Name:", nm, " -> class:", class(h5[[nm]]), "\n")
}
Name: layers  -> class: H5Group H5RefClass R6 
Name: obs  -> class: H5Group H5RefClass R6 
Name: obsm  -> class: H5Group H5RefClass R6 
Name: obsp  -> class: H5Group H5RefClass R6 
Name: uns  -> class: H5Group H5RefClass R6 
Name: var  -> class: H5Group H5RefClass R6 
Name: varm  -> class: H5Group H5RefClass R6 
Name: varp  -> class: H5Group H5RefClass R6 
h5$close_all()

Load matrices and genes/cells meta-data

## 1) counts: layers/counts -> genes × cells
counts <- h5Read(h5adFile, name = "layers/counts", transpose = FALSE)
# counts: rows = genes, cols = cells

## 2) obs / var (you already handled categoricals)
obs <- h5Read(h5adFile, name = "obs")
var <- h5Read(h5adFile, name = "var")

nGenes <- nrow(var)
nCells <- nrow(obs)

stopifnot(
  nGenes == nrow(counts),
  nCells == ncol(counts)
)

## Ensure row/colnames are consistent
# AnnData convention: obs index = cell IDs, var index = gene IDs
if (is.null(rownames(obs))) {
  # if needed, derive from a specific column
  # rownames(obs) <- obs$some_cell_id_column
}

if (is.null(rownames(var))) {
  # rownames(var) <- var$some_gene_id_column
}

# Now align the matrix names to metadata
if (is.null(colnames(counts))) colnames(counts) <- rownames(obs)
if (is.null(rownames(counts))) rownames(counts) <- rownames(var)

assert_that(
  identical(colnames(counts), rownames(obs)),
  identical(rownames(counts), rownames(var))
)
[1] TRUE

Retrieve clusterizations as factors

table(obs$cell_type, useNA = "ifany")

       Vip      Lamp5        Sst       Sncg   Serpinf1      Pvalb       Endo 
      1728       1122       1741        125         27       1337         94 
      Peri      L6.CT        L6b      L6.IT    L2.3.IT         CR      L5.PT 
        32        960        358       1872        982          7        544 
        NP         L4      L5.IT      Oligo      Meis2      Astro Macrophage 
       362       1401        880         91         45        368         51 
      VLMC        SMC 
        67         55 

Create SingleCellExperiment

sce <- SingleCellExperiment(
  assays = list(
    counts = counts
  )
)

# Attach metadata
colData(sce) <- DataFrame(obs)  # cells metadata
rowData(sce) <- DataFrame(var)  # genes metadata

# load processed matrices
if (FALSE) {
  X <- h5Read(h5adFile, name = "X", transpose = FALSE)  # genes × cells

  assert_that(all(dim(X) == dim(counts)))

  assays(sce)[["logcounts"]] <- X  # or "normcounts", depending on what X really is
}

if (FALSE) {
  obsm <- h5Read(h5adFile, name = "obsm")

  names(obsm)
  # e.g. "X_pca", "X_umap", "X_tsne", ...
  
  # Simple mapping from AnnData keys to SCE reducedDim names
  rdMap <- c(
    X_pca  = "PCA",
    X_umap = "UMAP",
    X_tsne = "TSNE",
    X_mde  = "MDE",
    X_scvi = "SCVI"
  )

  for (key in intersect(names(obsm), names(rdMap))) {
    mat <- obsm[[key]]  # cells × k
    # sanity check
    stopifnot(nrow(mat) == ncol(sce))
    reducedDims(sce)[[ rdMap[[key]] ]] <- as.matrix(mat)
  }
}

uns <- h5Read(h5adFile, name = "uns")

# root-level attributes
h5 <- H5File$new(h5adFile, mode = "r")
rootAttrs <- h5attributes(h5)
h5$close_all()

# Store them in SCE metadata
metadata(sce)$uns           <- uns
metadata(sce)$h5ad_attrs    <- rootAttrs
metadata(sce)$source_file   <- h5adFile
metadata(sce)$source_format <- "AnnData h5ad"

Check all OK

sce
class: SingleCellExperiment 
dim: 34617 14249 
metadata(4): uns h5ad_attrs source_file source_format
assays(1): counts
rownames(34617): 0610005C13Rik 0610006L08Rik ... l7Rn6 n-R5s136
rowData names(4): n_cells feature_name hvg hvg_score
colnames(14249): F1S4_160108_001_A01 F1S4_160108_001_B01 ...
  FYS4_171004_104_G01 FYS4_171004_104_H01
colData names(6): label sizeFactor ... cell_type size_factors
reducedDimNames(0):
mainExpName: NULL
altExpNames(0):
assayNames(sce)
[1] "counts"
colData(sce)[1:3, ]
DataFrame with 3 rows and 6 columns
                       label sizeFactor subclass  n_counts cell_type
                    <factor>  <numeric> <factor> <numeric>  <factor>
F1S4_160108_001_A01    Vip      1.08531    Vip     1730700     Vip  
F1S4_160108_001_B01    Lamp5    1.19750    Lamp5   1909605     Lamp5
F1S4_160108_001_C01    Lamp5    1.24475    Lamp5   1984948     Lamp5
                    size_factors
                       <numeric>
F1S4_160108_001_A01      1730700
F1S4_160108_001_B01      1909605
F1S4_160108_001_C01      1984948
rowData(sce)[1:3, ]
DataFrame with 3 rows and 4 columns
                n_cells  feature_name       hvg hvg_score
              <integer>   <character> <logical> <numeric>
0610005C13Rik       334 0610005C13Rik     FALSE  0.133368
0610006L08Rik        17 0610006L08Rik     FALSE  1.367953
0610007P14Rik     13189 0610007P14Rik     FALSE -0.991799
reducedDimNames(sce)
character(0)
names(metadata(sce))
[1] "uns"           "h5ad_attrs"    "source_file"   "source_format"

Convert SCE objects to COTAN

## helper: convert a single SCE + its global attrs into a COTAN object
sceToCotan <- function(sce, globalAttrs = list()) {
  # 1. SCE -> COTAN (handles counts, rowData, colData, cluster columns, etc.)
  objCOTAN <- convertFromSingleCellExperiment(objSCE = sce)

  # 2. Initialize metaDataset with standard tags (use whatever you have)
  #    If your globalAttrs already contain these, pick from there.
  geoVal   <-
    if ("GEO"   %in% names(globalAttrs)) globalAttrs[["GEO"]]   else ""
  seqVal   <- 
    if ("method" %in% names(globalAttrs)) globalAttrs[["method"]] else ""
  condVal  <- 
    if ("condition" %in% names(globalAttrs)) globalAttrs[["condition"]] else ""

  objCOTAN <- initializeMetaDataset(
    objCOTAN,
    GEO              = as.character(geoVal),
    sequencingMethod = as.character(seqVal),
    sampleCondition  = as.character(condVal)
  )

  # 3. Add all remaining global attributes as extra metadata rows
  usedTags <- c("GEO", "method", "condition")
  extraTags <- base::setdiff(names(globalAttrs), usedTags)

  for (tag in extraTags) {
    val <- globalAttrs[[tag]]
    # COTAN expects a character vector; coerce anything else
    objCOTAN <- addElementToMetaDataset(
      objCOTAN,
      tag   = tag,
      value = as.character(val)
    )
  }

  objCOTAN
}
metadata <- metadata(sce)
metadata_cells <- NA
metadata_genes <- NA
metadata_dataset <- NA

for (n in c(1:length(metadata$uns))) {
  label <- names(metadata$uns[n])
  #print(length(metadata$uns[[n]]))
  if (length(metadata$uns[[n]]) == dim(colData(sce))[1]) {
   metadata_cells <- cbind(metadata_cells, metadata$uns[[n]])
   metadata_cells <- as.data.frame(metadata_cells)
   colnames(metadata_cells)[length(colnames(metadata_cells))] <- label
  }else if(length(metadata$uns[[n]]) == dim(rowData(sce))[1]) {
   metadata_genes <- cbind(metadata_genes, metadata$uns[[n]])
   metadata_genes <- as.data.frame(metadata_genes)
   colnames(metadata_genes)[length(colnames(metadata_genes))] <- label
  }else{
    print(label)
    metadata_dataset <- c(metadata_dataset,metadata$uns[[n]])
    names(metadata_dataset)[length(metadata_dataset)] <- label 
  }
  
  
}
[1] "_from_cache"
[1] "ccc_target"
[1] "data_reference"
[1] "data_url"
[1] "dataset_description"
[1] "dataset_id"
[1] "dataset_name"
[1] "dataset_organism"
[1] "dataset_reference"
[1] "dataset_summary"
[1] "dataset_url"
[1] "knn"
[1] "normalization_id"
[1] "pca_variance"
[1] "target_organism"
metadata_cells$metadata_cells <- rownames(colData(sce))

identical(str_split(metadata_cells$metadata_cells,pattern = "_",simplify = T)[,1],metadata_cells$orig.ident)
[1] TRUE
head(metadata_cells)
       metadata_cells age_days brain_hemisphere brain_region brain_subregion
1 F1S4_160108_001_A01       53                L         VISp            L2/3
2 F1S4_160108_001_B01       53                L         VISp            L2/3
3 F1S4_160108_001_C01       53                L         VISp            L2/3
4 F1S4_160108_001_D01       53                L         VISp            L2/3
5 F1S4_160108_001_E01       53                L         VISp            L2/3
6 F1S4_160108_001_F01       53                L         VISp            L2/3
      class            cluster cluster_correlation complexity_cg
1 GABAergic Vip Arhgap36 Hmcn1           0.8372286     0.3549598
2 GABAergic         Lamp5 Lsp1           0.8787432     0.3506406
3 GABAergic         Lamp5 Lsp1           0.8870837     0.3608883
4 GABAergic Vip Crispld2 Htr2c           0.8435516     0.3689915
5 GABAergic  Lamp5 Plch2 Dock5           0.8549944     0.3785353
6 GABAergic     Sst Tac1 Tacr3           0.8560629     0.3575420
  confusion_score core_intermediate_call  donor     driver_lines eye_condition
1          0.4385           Intermediate 225675 Slc32a1-IRES-Cre        Normal
2          0.1025                   Core 225675 Slc32a1-IRES-Cre        Normal
3          0.0195                   Core 225675 Slc32a1-IRES-Cre        Normal
4          0.2734                   Core 225675 Slc32a1-IRES-Cre        Normal
5          0.7532                   Core 225675 Slc32a1-IRES-Cre        Normal
6          0.4291                   Core 225675 Slc32a1-IRES-Cre        Normal
   facs_container facs_date facs_sort_criteria genes_detected_cpm_criterion
1 F1S4_160108_001  1/8/2016       RFP-positive                        10445
2 F1S4_160108_001  1/8/2016       RFP-positive                        11600
3 F1S4_160108_001  1/8/2016       RFP-positive                        11848
4 F1S4_160108_001  1/8/2016       RFP-positive                         9494
5 F1S4_160108_001  1/8/2016       RFP-positive                        10012
6 F1S4_160108_001  1/8/2016       RFP-positive                        10696
  genes_detected_fpkm_criterion                             genotype gfp_cpm
1                          9222 Slc32a1-IRES-Cre/wt;Ai14(RCL-tdT)/wt  248.86
2                         10370 Slc32a1-IRES-Cre/wt;Ai14(RCL-tdT)/wt  289.61
3                         10734 Slc32a1-IRES-Cre/wt;Ai14(RCL-tdT)/wt  281.06
4                          8561 Slc32a1-IRES-Cre/wt;Ai14(RCL-tdT)/wt  390.02
5                          8791 Slc32a1-IRES-Cre/wt;Ai14(RCL-tdT)/wt  253.92
6                          9145 Slc32a1-IRES-Cre/wt;Ai14(RCL-tdT)/wt  195.80
  injection_exclusion_criterion injection_label_direction injection_material
1                  No Injection              No Injection       No Injection
2                  No Injection              No Injection       No Injection
3                  No Injection              No Injection       No Injection
4                  No Injection              No Injection       No Injection
5                  No Injection              No Injection       No Injection
6                  No Injection              No Injection       No Injection
  injection_primary injection_secondary injection_tract
1      No Injection        No Injection    No Injection
2      No Injection        No Injection    No Injection
3      No Injection        No Injection    No Injection
4      No Injection        No Injection    No Injection
5      No Injection        No Injection    No Injection
6      No Injection        No Injection    No Injection
  library_prep_avg_size_bp   library_prep_set nCount_RNA nFeature_RNA
1                      436 L8S4_160205_01_A02    1730700         9029
2                      445 L8S4_160205_01_B02    1909605        10207
3                      441 L8S4_160205_01_C02    1984948        10578
4                      489 L8S4_160205_01_D02    2291552         8482
5                      424 L8S4_160205_01_E02    1757463         8697
6                      432 L8S4_160205_01_F02    1837003         8990
      organism orig.ident percent_aligned_reads_total percent_ecoli_reads
1 Mus musculus       F1S4                         100          0.01961939
2 Mus musculus       F1S4                         100          0.01472401
3 Mus musculus       F1S4                         100          0.01271205
4 Mus musculus       F1S4                         100          0.01806790
5 Mus musculus       F1S4                         100          0.03056065
6 Mus musculus       F1S4                         100          0.02158139
  percent_exon_reads percent_intergenic_reads percent_intron_reads
1           74.16672                 4.909982            20.923297
2           77.55741                 5.064451            17.378139
3           83.13226                 4.254840            12.612901
4           89.32453                 3.051048             7.624426
5           84.23305                 4.425087            11.341862
6           74.88262                 5.324116            19.793264
  percent_mt_exon_reads percent_reads_unique percent_rrna_reads
1           0.000104709             83.76778         0.13552879
2           0.000401765             84.28387         0.11711441
3           0.000312293             84.28835         0.11565239
4           0.000226192             83.99171         0.25740658
5           0.000380690             80.91289         0.16015630
6           0.000227679             81.93723         0.09208001
  percent_synth_reads reporter_lines rna_amplification_set sample_id
1         0.004889926  Ai14(RCL-tdT)        A8S4_160202_01 527128530
2         0.003900800  Ai14(RCL-tdT)        A8S4_160202_01 527128536
3         0.003320712  Ai14(RCL-tdT)        A8S4_160202_01 527128542
4         0.005803442  Ai14(RCL-tdT)        A8S4_160202_01 527128548
5         0.005922395  Ai14(RCL-tdT)        A8S4_160202_01 527128554
6         0.004896081  Ai14(RCL-tdT)        A8S4_160202_01 527128560
  sample_type   seq_batch           seq_name seq_tube sex subclass tdt_cpm
1       Cells R8S4-160225 LS-15006_S09_E1-50 LS-15006   M      Vip  248.86
2       Cells R8S4-160225 LS-15006_S10_E1-50 LS-15006   M    Lamp5  289.61
3       Cells R8S4-160225 LS-15006_S11_E1-50 LS-15006   M    Lamp5  281.06
4       Cells R8S4-160225 LS-15006_S12_E1-50 LS-15006   M      Vip  390.02
5       Cells R8S4-160225 LS-15006_S13_E1-50 LS-15006   M    Lamp5  253.92
6       Cells R8S4-160225 LS-15006_S14_E1-50 LS-15006   M      Sst  195.80
  total_reads
1     2865074
2     2986823
3     2881912
4     3094715
5     2626809
6     3074500

Create the COTAN object

objCOTAN <- sceToCotan(sce, globalAttrs = metadata_dataset[6:14])
objCOTAN@metaDataset[2,2] <-"SMARTer" 

identical(rownames(objCOTAN@metaCells),metadata_cells$metadata_cells)
[1] TRUE
objCOTAN@metaCells <- cbind(objCOTAN@metaCells,metadata_cells)


metaCellsNames <- colnames(getMetadataCells(objCOTAN))
metaCellsNames
 [1] "label"                         "sizeFactor"                   
 [3] "subclass"                      "n_counts"                     
 [5] "cell_type"                     "size_factors"                 
 [7] "metadata_cells"                "age_days"                     
 [9] "brain_hemisphere"              "brain_region"                 
[11] "brain_subregion"               "class"                        
[13] "cluster"                       "cluster_correlation"          
[15] "complexity_cg"                 "confusion_score"              
[17] "core_intermediate_call"        "donor"                        
[19] "driver_lines"                  "eye_condition"                
[21] "facs_container"                "facs_date"                    
[23] "facs_sort_criteria"            "genes_detected_cpm_criterion" 
[25] "genes_detected_fpkm_criterion" "genotype"                     
[27] "gfp_cpm"                       "injection_exclusion_criterion"
[29] "injection_label_direction"     "injection_material"           
[31] "injection_primary"             "injection_secondary"          
[33] "injection_tract"               "library_prep_avg_size_bp"     
[35] "library_prep_set"              "nCount_RNA"                   
[37] "nFeature_RNA"                  "organism"                     
[39] "orig.ident"                    "percent_aligned_reads_total"  
[41] "percent_ecoli_reads"           "percent_exon_reads"           
[43] "percent_intergenic_reads"      "percent_intron_reads"         
[45] "percent_mt_exon_reads"         "percent_reads_unique"         
[47] "percent_rrna_reads"            "percent_synth_reads"          
[49] "reporter_lines"                "rna_amplification_set"        
[51] "sample_id"                     "sample_type"                  
[53] "seq_batch"                     "seq_name"                     
[55] "seq_tube"                      "sex"                          
[57] "subclass"                      "tdt_cpm"                      
[59] "total_reads"                  
for (clName in metaCellsNames[c(5,7:13)]) {
  clusters <- factor(getMetadataCells(objCOTAN)[[clName]])
  levels(clusters)[is.na(levels(clusters))] <- "NA"
  names(clusters) <- getCells(objCOTAN)
  objCOTAN <- addClusterization(objCOTAN, clName = clName, clusters = clusters)
}

for (condName in metaCellsNames[c(7:13,19:23,26,27,49:56)]) {
  condition <- getMetadataCells(objCOTAN)[[condName]]
  names(condition) <- getCells(objCOTAN)
  objCOTAN <- addCondition(objCOTAN, condName = condName, conditions = condition)
}

getMetadataDataset(objCOTAN)
                        V1
1                     GEO:
2         scRNAseq method:
3        condition sample:
4    starting n. of cells:
5  genes' COEX is in sync:
6  cells' COEX is in sync:
7           data_reference
8                 data_url
9      dataset_description
10              dataset_id
11            dataset_name
12        dataset_organism
13       dataset_reference
14         dataset_summary
15             dataset_url
                                                                                                                                                                                            V2
1                                                                                                                                                                                             
2                                                                                                                                                                                      SMARTer
3                                                                                                                                                                                             
4                                                                                                                                                                                        14249
5                                                                                                                                                                                        FALSE
6                                                                                                                                                                                        FALSE
7                                                                                                                                                                               tasic2016adult
8                                                                                                                                              https://figshare.com/ndownloader/files/36509385
9  A murine brain atlas with adjacent cell types as assumed benchmark truth, inferred from deconvolution proportion correlations using matching 10x Visium slides (see Dimitrov et al., 2022).
10                                                                                                                                                           openproblems_v1/allen_brain_atlas
11                                                                                                                                                                           Mouse Brain Atlas
12                                                                                                                                                                                mus_musculus
13                                                                                                                                                                              tasic2016adult
14                                                                                                                                                           Adult mouse primary visual cortex
15                                                                                                                                  http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE71585
fileOut <- "MouseBrainOpenProblem/MouseBrainOP_COTAN_raw.RDS"
saveRDS(objCOTAN, file = fileOut)
Sys.time()
[1] "2026-01-26 10:59:21 CET"
sessionInfo()
R version 4.5.2 (2025-10-31)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.5 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0 
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0  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: Europe/Rome
tzcode source: system (glibc)

attached base packages:
[1] stats4    stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
 [1] hdf5r.Extra_0.1.0           hdf5r_1.3.12               
 [3] SingleCellExperiment_1.32.0 SummarizedExperiment_1.38.1
 [5] Biobase_2.70.0              GenomicRanges_1.62.1       
 [7] Seqinfo_1.0.0               IRanges_2.44.0             
 [9] S4Vectors_0.48.0            BiocGenerics_0.56.0        
[11] generics_0.1.3              MatrixGenerics_1.22.0      
[13] matrixStats_1.5.0           COTAN_2.11.1               
[15] stringr_1.6.0               Matrix_1.7-4               
[17] conflicted_1.2.0            zeallot_0.2.0              
[19] ggplot2_4.0.1               assertthat_0.2.1           

loaded via a namespace (and not attached):
  [1] RcppAnnoy_0.0.22        splines_4.5.2           later_1.4.2            
  [4] tibble_3.3.0            polyclip_1.10-7         fastDummies_1.7.5      
  [7] lifecycle_1.0.4         doParallel_1.0.17       globals_0.18.0         
 [10] lattice_0.22-7          MASS_7.3-65             backports_1.5.0        
 [13] ggdist_3.3.3            dendextend_1.19.0       magrittr_2.0.4         
 [16] plotly_4.12.0           rmarkdown_2.29          yaml_2.3.12            
 [19] httpuv_1.6.16           otel_0.2.0              Seurat_5.4.0           
 [22] sctransform_0.4.2       spam_2.11-1             sp_2.2-0               
 [25] spatstat.sparse_3.1-0   reticulate_1.44.1       cowplot_1.2.0          
 [28] pbapply_1.7-2           RColorBrewer_1.1-3      abind_1.4-8            
 [31] Rtsne_0.17              purrr_1.2.0             circlize_0.4.16        
 [34] GenomeInfoDbData_1.2.14 ggrepel_0.9.6           irlba_2.3.5.1          
 [37] listenv_0.10.0          spatstat.utils_3.2-1    goftest_1.2-3          
 [40] RSpectra_0.16-2         spatstat.random_3.4-3   fitdistrplus_1.2-2     
 [43] parallelly_1.46.0       codetools_0.2-20        DelayedArray_0.36.0    
 [46] tidyselect_1.2.1        shape_1.4.6.1           UCSC.utils_1.4.0       
 [49] farver_2.1.2            ScaledMatrix_1.16.0     viridis_0.6.5          
 [52] spatstat.explore_3.7-0  jsonlite_2.0.0          GetoptLong_1.1.0       
 [55] progressr_0.18.0        ggridges_0.5.6          survival_3.8-3         
 [58] iterators_1.0.14        foreach_1.5.2           tools_4.5.2            
 [61] ica_1.0-3               Rcpp_1.1.0              glue_1.8.0             
 [64] gridExtra_2.3           SparseArray_1.10.8      xfun_0.52              
 [67] distributional_0.6.0    ggthemes_5.2.0          GenomeInfoDb_1.44.0    
 [70] dplyr_1.1.4             withr_3.0.2             fastmap_1.2.0          
 [73] digest_0.6.37           rsvd_1.0.5              parallelDist_0.2.6     
 [76] R6_2.6.1                mime_0.13               colorspace_2.1-1       
 [79] scattermore_1.2         tensor_1.5              spatstat.data_3.1-9    
 [82] tidyr_1.3.1             data.table_1.18.0       httr_1.4.7             
 [85] htmlwidgets_1.6.4       S4Arrays_1.10.1         uwot_0.2.3             
 [88] pkgconfig_2.0.3         gtable_0.3.6            ComplexHeatmap_2.26.0  
 [91] lmtest_0.9-40           S7_0.2.1                XVector_0.50.0         
 [94] htmltools_0.5.8.1       dotCall64_1.2           zigg_0.0.2             
 [97] clue_0.3-66             SeuratObject_5.3.0      scales_1.4.0           
[100] png_0.1-8               spatstat.univar_3.1-6   knitr_1.50             
[103] reshape2_1.4.4          rjson_0.2.23            checkmate_2.3.2        
[106] nlme_3.1-168            proxy_0.4-29            cachem_1.1.0           
[109] zoo_1.8-14              GlobalOptions_0.1.2     KernSmooth_2.23-26     
[112] parallel_4.5.2          miniUI_0.1.2            pillar_1.11.1          
[115] grid_4.5.2              vctrs_0.7.0             RANN_2.6.2             
[118] promises_1.5.0          BiocSingular_1.26.1     beachmat_2.26.0        
[121] xtable_1.8-4            cluster_2.1.8.1         evaluate_1.0.5         
[124] cli_3.6.5               compiler_4.5.2          rlang_1.1.7            
[127] crayon_1.5.3            future.apply_1.20.0     easy.utils_0.1.0       
[130] plyr_1.8.9              stringi_1.8.7           viridisLite_0.4.2      
[133] deldir_2.0-4            BiocParallel_1.44.0     lazyeval_0.2.2         
[136] spatstat.geom_3.7-0     RcppHNSW_0.6.0          patchwork_1.3.2        
[139] bit64_4.6.0-1           future_1.69.0           shiny_1.12.1           
[142] ROCR_1.0-11             Rfast_2.1.5.1           igraph_2.2.1           
[145] memoise_2.0.1           RcppParallel_5.1.10     fastmatch_1.1-6        
[148] bit_4.6.0