OSCR

Spatial transcriptomics reveals distinct cell type dynamics following opioid dependence in female mice with the common human μ-opioid receptor variant Oprm1 A118G.

Code ↔ Paper

40 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 40 matches
  1. [1] § Methods › Data analysis › WGCNA module detection and analysis › Consensus (Pooled) WGCNA: network construction across all groups ↔ R/mod7-wgcna.R, lines 122–226 · score 0.99 · Soft thresholding power, dynamic tree cutting, deepSplit, goodSamplesGenes, mergeCutHeight, minModuleSize
  2. [2] § Methods › Data analysis › Clustering and cell-type identification ↔ R/mod3-celltyping.R, lines 12–64 · score 0.92 · Neighborhood graph construction, random forest classifier, Annoy algorithm, Louvain clustering, reference clusters, training
  3. [3] § Methods › Data analysis › Neurotransmitter and glial cell-type classification ↔ vignettes/cell-typing.Rmd, lines 85–107 · score 0.89 · Slc18a3, Slc6a4, Slc6a3, Slc17a6, Slc32a1, Slc17a7
  4. [4] § Methods › Data analysis › Clustering and cell-type identification ↔ R/mod2-preprocessing.R, lines 7–128 · score 0.85 · quality control filters, nCount_RNA, nFeature_RNA, removed cells, generalized clustering, CellDynamicST
  5. [5] § Methods › Data analysis › Spatial registration and anatomical annotation ↔ R/mod1-registration.R, lines 133–240 · score 0.84 · structure ID, atlas registration, Allen CCFv3, brain atlas, CellDynamicST, ontology
  6. [6] § Results › Spatially resolved gene network and pathway remodeling in opioid-exposed AA and GG brains ↔ inst/python/wgcna_network_plot.py, lines 1–49 · score 0.80 · sky blue, gene coexpression, WGCNA modules, Hub gene, Brain Atlas, gold
  7. [7] § Methods › Data analysis › Gene expression quantification ↔ R/mod2-preprocessing.R, lines 7–128 · score 0.79 · quality control filter, QC pipeline, QC thresholds, flagged, FOVs, fewer
  8. [8] § Methods › Data analysis › Treatment-associated transcriptional disproportionality across cell types (Fig. 2 F, G) ↔ R/mod6-deg.R, lines 7–53 · score 0.72 · log2 fold change, log2FC, GG SAL, AA SAL, absolute, DEGs
  9. [9] § Methods › Data analysis › WGCNA module detection and analysis › Consensus (Pooled) WGCNA: network construction across all groups ↔ vignettes/wgcna.Rmd, lines 74–95 · score 0.72 · scale free topology, Soft thresholding, signed R2, power, WGCNA
  10. [10] § Methods › Data analysis › Cell-type distribution dynamics in opioid dependence ↔ inst/python/celltype_distribution_heatmap.py, lines 1–36 · score 0.72 · Gini coefficients, Shannon diversity, mesostructural, composition, receptor, dynamics
  11. [11] § Methods › Data analysis › Spatial and regional gene ontology enrichment ↔ R/mod4-viz-enrichment.R, lines 57–74 · score 0.71 · UCell, scores relative, enrichment scores, GO term, depleted, enriched
  12. [12] § Methods › Data analysis › WGCNA module detection and analysis › Module–trait correlation and anatomical heatmaps ↔ R/mod7-wgcna.R, lines 229–308 · score 0.70 · module trait correlations, Pearson correlations, Module Eigengenes, component, heatmaps, exported
  13. [13] § Methods › Data analysis › Clustering and cell-type identification ↔ R/mod3-celltyping.R, lines 12–64 · score 0.68 · nCount_RNA, generalized clustering, CellDynamicST, variation, workflow, propagation
  14. [14] § Methods › Data analysis › Spatial and regional gene ontology enrichment ↔ R/mod7-wgcna.R, lines 444–534 · score 0.67 · enrichGO, clusterProfiler, GO enrichment, BP, enriched, gene
  15. [15] § Methods › Data analysis › Spatial and regional gene ontology enrichment ↔ R/mod4-viz-extra.R, lines 8–35 · score 0.66 · enrichGO, clusterProfiler, GO enrichment, enriched, treatment, genotype
  16. [16] § Methods › Data analysis › WGCNA module detection and analysis › Differential module dynamics and circos visualization (Fig. 6A) ↔ inst/python/wgcna_network_plot.py, lines 553–624 · score 0.66 · inner rings, outer ring, circos, colormaps, DEG, enrichment
  17. [17] § Results › Pathway and functional analysis ↔ R/mod4-viz-extra.R, lines 8–35 · score 0.66 · score magnitude, log2FC, GO Enrichment, GO terms, log10, Bar
  18. [18] § Results › Opioid-dependent transcriptome differs by genotype ↔ vignettes/cell-typing.Rmd, lines 85–107 · score 0.65 · Slc17a6, Slc32a1, Slc17a7, GABAergic, mouse brain, Gad2
  19. [19] § Methods › Data analysis › WGCNA module detection and analysis › Inter-regional differential co-expression networks (Fig. 6B–E) ↔ R/mod7-wgcna.R, lines 444–534 · score 0.63 · clusterProfiler, enriched pathway, pathway enrichment, db, mm, module
  20. [20] § Methods › Data analysis › Neurotransmitter and glial cell-type classification ↔ vignettes/cell-typing.Rmd, lines 109–143 · score 0.63 · Cx3cr1, P2ry12, Mbp, Tmem119, Aqp4, Gfap
  21. [21] § Results › Cell type distribution in Oprm1 AA and GG opioid dependent mice ↔ inst/python/celltype_distribution_heatmap.py, lines 81–118 · score 0.63 · GABAergic, olfactory, hippocampus, hypothalamus, striatum, isocortex
  22. [22] § Methods › Data analysis › Validation and refinement of spatial cell-type annotations ↔ R/mod3-celltyping.R, lines 668–722 · score 0.62 · CellMarker2, min.pct, database, cross, Validation, cluster
  23. [23] § Methods › Data analysis › Neurotransmitter and glial cell-type classification ↔ R/mod3-celltyping.R, lines 253–368 · score 0.60 · GABAergic, Glycinergic, Histaminergic, Noradrenergic, Cholinergic, Serotonergic
  24. [24] § Methods › Data analysis › Spatial and regional gene ontology enrichment ↔ vignettes/complete-pipeline-walkthrough.Rmd, lines 547–579 · score 0.60 · weighted enrichment scores, log2 fold change, GO term, bar, genotype
  25. [25] § Results › Spatially resolved gene network and pathway remodeling in opioid-exposed AA and GG brains ↔ R/mod7-wgcna.R, lines 1–6 · score 0.60 · module detection, trait correlation, gene co expression, pathways, weighted, WGCNA
  26. [26] § Methods › Data analysis › Spatial and regional gene ontology enrichment ↔ R/mod6-deg.R, lines 281–360 · score 0.59 · log2 fold change, enrichment scores, GO term, gene
  27. [27] § Methods › Data analysis › Neurotransmitter and glial cell-type classification ↔ R/mod3-celltyping.R, lines 253–368 · score 0.59 · log2CPM, assign neurotransmitter, transporter, classification, threshold, gene
  28. [28] § Results › Cell type distribution in Oprm1 AA and GG opioid dependent mice ↔ inst/scripts/generate_sample_data.R, lines 13–51 · score 0.58 · GABAergic, olfactory, hippocampus, hypothalamus, striatum, serotonergic
  29. [29] § Methods › Data analysis › Validation and refinement of spatial cell-type annotations ↔ inst/scripts/generate_sample_data.R, lines 13–51 · score 0.58 · meso structure, brainstem, cerebrum, interbrain, MB, midbrain
  30. [30] § Results › Opioid-dependent transcriptome differs by genotype ↔ vignettes/complete-pipeline-walkthrough.Rmd, lines 491–545 · score 0.57 · Cell Adhesion, apoptotic, channel, myelination, synaptic, Signaling
  31. [31] § Methods › Data analysis › WGCNA module detection and analysis › Inter-regional differential co-expression networks (Fig. 6B–E) ↔ inst/python/wgcna_network_plot.py, lines 188–240 · score 0.57 · AllenSDK, Allen Brain Atlas, edges, sagittal, Node, weight
  32. [32] § Methods › Data analysis › Treatment-associated transcriptional disproportionality across cell types (Fig. 2 F, G) ↔ R/mod4-viz-disproportion.R, lines 70–99 · score 0.56 · disproportionality scores, t-SNE, coolwarm, background, cell
  33. [33] § Methods › Data analysis › Differential expression and functional enrichment analysis ↔ R/mod6-deg.R, lines 54–131 · score 0.56 · FindMarkers, min.pct, Seurat, threshold, gene, cells
  34. [34] § Methods › Data analysis › Spatial registration and anatomical annotation ↔ R/mod5-dynamics.R, lines 75–177 · score 0.56 · anatomical hierarchy, parent regions, matched, Seurat, exported, atlas
  35. [35] § Methods › Data analysis › WGCNA module detection and analysis › Python packages ↔ inst/python/wgcna_network_plot.py, lines 98–124 · score 0.53 · Allen Mouse Brain, structure tree, allensdk, networkx, Python, overlay
  36. [36] § Methods › Data analysis › WGCNA module detection and analysis › R Packages ↔ R/mod6-deg.R, lines 417–433 · score 0.53 · AnnotationDbi, go db, ID
  37. [37] § Methods › Data analysis › Cell-type distribution dynamics in opioid dependence ↔ inst/python/celltype_distribution_heatmap.py, lines 320–331 · score 0.52 · log transformation, clipped, max, heatmap, min
  38. [38] § Results › Pathway and functional analysis ↔ vignettes/complete-pipeline-walkthrough.Rmd, lines 491–545 · score 0.52 · opioid receptors, pathway enrichment, binding, myelination, signaling, glutamatergic
  39. [39] § Methods › Data analysis › Clustering and cell-type identification ↔ R/mod3-celltyping.R, lines 106–161 · score 0.51 · technical bias, PCA, component, Seurat, log2, correlation
  40. [40] § Methods › Data analysis › Hierarchical cell-type annotation ↔ R/mod3-celltyping.R, lines 522–552 · score 0.51 · cluster identity, superclasses, neuronal, hierarchically, classification, glial

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

R · 722 lines · 26 KB · other · 7 matches

  1. #' @title Module 3: Cell Type Annotation
  2. #' @description Functions for reference-based generalized clustering with
  3. #' Random Forest label propagation, neurotransmitter classification,
  4. #' glial cell classification, and hierarchical cell type annotation.
  5. #' @name celltyping
  6. NULL
  7. # ============================================================================
  8. # 3A. Generalized Clustering
  9. # ============================================================================
  10. #' Reference-Based Generalized Clustering
  11. #'
  12. #' Implements the core CellDynamicST clustering algorithm. The workflow:
  13. #' (1) Subset the reference group, (2) run PCA, (3) detect and exclude
  14. #' technical bias PCs, (4) build a neighborhood graph, (5) cluster at high
  15. #' resolution, (6) train a Random Forest classifier on reference clusters,
  16. #' (7) propagate labels to all cells.
  17. #'
  18. #' This function generalizes the logic from \code{generalized_clustering.R}
  19. #' and \code{generalized_clustering_randomforest.R}, replacing all hardcoded
  20. #' paths, group names, and parameters with configurable arguments.
  21. #'
  22. #' @param seurat_obj A Seurat object (normalized and scaled).
  23. #' @param config A \code{\link{CdstConfig}} object.
  24. #' @param n_pcs Integer. Number of PCs to compute. Default: from config.
  25. #' @param bias_threshold Numeric. PCs with |correlation| > this threshold
  26. #' with log2(nCount_RNA) are excluded as technical bias. Default: from config.
  27. #' @param annoy_trees Integer. Number of trees for Annoy algorithm. Default: from config.
  28. #' @param k_neighbors Integer. Number of neighbors for graph construction.
  29. #' Default: from config.
  30. #' @param resolution Numeric. Louvain clustering resolution. Default: from config.
  31. #' @param rf_ntree Integer. Number of trees in the Random Forest. Default: from config.
  32. #' @param seed Integer. Random seed for reproducibility. Default: 42.
  33. #' @param verbose Logical. Default: TRUE.
  34. #'
  35. #' @return The Seurat object with new metadata columns:
  36. #' \code{cdst_cluster} (cluster assignment for all cells),
  37. #' \code{cdst_ref_cluster} (reference-only cluster, NA for non-reference),
  38. #' \code{cdst_pcs_used} (stored in misc).
  39. #'
  40. #' @details
  41. #' The technical bias detection step computes the Pearson correlation between
  42. #' each PC and log2(nCount_RNA + 1). PCs exceeding the bias threshold are
  43. #' excluded from downstream neighborhood graph construction. This is critical
  44. #' for spatial transcriptomic data where PC1 often captures library size
  45. #' variation rather than biological signal.
  46. #'
  47. #' The Random Forest label propagation step trains a classifier on the
  48. #' reference group's cluster assignments and applies it to all cells,
  49. #' ensuring consistent cluster labels across experimental conditions.
  50. #'
  51. #' @examples
  52. #' \dontrun{
  53. #' config <- cdst_load_config("experiment_config.yaml")
  54. #' obj <- cdst_load_seurat("data.rds", config)
  55. #' obj <- cdst_run_qc(obj, config)
  56. #' obj <- cdst_normalize(obj)
  57. #' obj <- cdst_cluster(obj, config)
  58. #' table(obj$cdst_cluster)
  59. #' }
  60. #'
  61. #' @export
  62. cdst_cluster <- function(seurat_obj, config,
  63. n_pcs = NULL,
  64. bias_threshold = NULL,
  65. annoy_trees = NULL,
  66. k_neighbors = NULL,
  67. resolution = NULL,
  68. rf_ntree = NULL,
  69. seed = 42L,
  70. verbose = TRUE) {
  71. checkmate::assert_class(config, "CdstConfig")
  72. validate_seurat(seurat_obj, required_metadata = "experiment_group")
  73. start_time <- Sys.time()
  74. set.seed(seed)
  75. # Resolve parameters from config or overrides
  76. n_pcs <- n_pcs %||% config@clustering$n_pcs
  77. bias_threshold <- bias_threshold %||% config@clustering$bias_threshold
  78. annoy_trees <- annoy_trees %||% config@clustering$annoy_trees
  79. k_neighbors <- k_neighbors %||% config@clustering$k_neighbors
  80. resolution <- resolution %||% config@clustering$resolution
  81. rf_ntree <- rf_ntree %||% config@clustering$rf_ntree
  82. if (verbose) {
  83. cli::cli_inform(c(
  84. "Starting reference-based generalized clustering...",
  85. "i" = "Reference group: {.val {config@reference_group}}",
  86. "i" = "PCs: {n_pcs}, Resolution: {resolution}, RF trees: {rf_ntree}"
  87. ))
  88. }
  89. # ---- Step 1: Subset reference group ----
  90. ref_cells <- which(seurat_obj$experiment_group == config@reference_group)
  91. if (length(ref_cells) < 100) {
  92. cli::cli_abort(c(
  93. "Reference group {.val {config@reference_group}} has only {length(ref_cells)} cells.",
  94. "i" = "At least 100 cells are required for reliable clustering."
  95. ))
  96. }
  97. ref_obj <- seurat_obj[, ref_cells]
  98. if (verbose) cli::cli_inform("Reference subset: {.val {ncol(ref_obj)}} cells")
  99. # ---- Step 2: Scale and PCA on reference ----
  100. all_genes <- rownames(ref_obj)
  101. ref_obj <- Seurat::ScaleData(ref_obj, features = all_genes, verbose = FALSE)
  102. if (verbose) cli::cli_inform("Running PCA ({n_pcs} components)...")
  103. ref_obj <- Seurat::RunPCA(ref_obj, npcs = n_pcs, features = all_genes,
  104. verbose = FALSE)
  105. # ---- Step 3: Detect technical bias PCs ----
  106. ref_obj[["log2GeneCount"]] <- log2(ref_obj$nCount_RNA + 1)
  107. pc_embeddings <- Seurat::Embeddings(ref_obj, reduction = "pca")[, seq_len(n_pcs)]
  108. pc_correlations <- stats::cor(
  109. ref_obj$log2GeneCount,
  110. pc_embeddings
  111. )
  112. bias_pcs <- which(abs(pc_correlations[1, ]) > bias_threshold)
  113. good_pcs <- setdiff(seq_len(n_pcs), bias_pcs)
  114. if (length(good_pcs) < 10) {
  115. cli::cli_warn(c(
  116. "Only {length(good_pcs)} PCs passed bias filter.",
  117. "i" = "Consider lowering {.arg bias_threshold} (currently {bias_threshold})."
  118. ))
  119. }
  120. if (verbose) {
  121. cli::cli_inform(c(
  122. "i" = "Bias PCs excluded (|r| > {bias_threshold}): {.val {paste(bias_pcs, collapse = ', ')}}",
  123. "i" = "Using {length(good_pcs)} PCs for clustering"
  124. ))
  125. }
  126. # ---- Step 4: Neighborhood graph and clustering ----
  127. if (verbose) cli::cli_inform("Building neighborhood graph...")
  128. ref_obj <- Seurat::FindNeighbors(
  129. ref_obj,
  130. dims = good_pcs,
  131. nn.method = "annoy",
  132. n.trees = annoy_trees,
  133. k.param = k_neighbors,
  134. verbose = FALSE
  135. )
  136. if (verbose) cli::cli_inform("Clustering at resolution {resolution}...")
  137. ref_obj <- Seurat::FindClusters(
  138. ref_obj,
  139. resolution = resolution,
  140. algorithm = 2, # Louvain with multilevel refinement
  141. group.singletons = TRUE,
  142. verbose = FALSE
  143. )
  144. ref_clusters <- Seurat::Idents(ref_obj)
  145. n_clusters <- length(unique(ref_clusters))
  146. if (verbose) cli::cli_inform("Found {.val {n_clusters}} clusters in reference group")
  147. # ---- Step 5: Train Random Forest ----
  148. if (verbose) cli::cli_inform("Training Random Forest classifier ({rf_ntree} trees)...")
  149. ref_data <- t(as.matrix(Seurat::GetAssayData(ref_obj, layer = "data")))
  150. ref_labels <- factor(ref_clusters)
  151. # Drop unused levels
  152. ref_labels <- droplevels(ref_labels)
  153. rf_model <- randomForest::randomForest(
  154. x = ref_data,
  155. y = ref_labels,
  156. ntree = rf_ntree,
  157. mtry = floor(sqrt(ncol(ref_data))),
  158. importance = FALSE,
  159. keep.forest = TRUE,
  160. keep.inbag = FALSE,
  161. proximity = FALSE
  162. )
  163. # ---- Step 6: Propagate labels to all cells ----
  164. if (verbose) cli::cli_inform("Propagating labels to all {.val {ncol(seurat_obj)}} cells...")
  165. all_data <- t(as.matrix(Seurat::GetAssayData(seurat_obj, layer = "data")))
  166. predictions <- predict(rf_model, all_data)
  167. seurat_obj$cdst_cluster <- as.character(predictions)
  168. # Store reference-only cluster info
  169. seurat_obj$cdst_ref_cluster <- NA_character_
  170. seurat_obj$cdst_ref_cluster[ref_cells] <- as.character(ref_clusters)
  171. # ---- Step 7: Run PCA and dimensionality reduction on full dataset ----
  172. if (verbose) cli::cli_inform("Running PCA on full dataset...")
  173. all_genes_full <- rownames(seurat_obj)
  174. seurat_obj <- Seurat::ScaleData(seurat_obj, features = all_genes_full, verbose = FALSE)
  175. seurat_obj <- Seurat::RunPCA(seurat_obj, npcs = n_pcs, features = all_genes_full,
  176. verbose = FALSE)
  177. # Detect bias PCs for full dataset
  178. seurat_obj[["log2GeneCount"]] <- log2(seurat_obj$nCount_RNA + 1)
  179. full_pc_corr <- stats::cor(
  180. seurat_obj$log2GeneCount,
  181. Seurat::Embeddings(seurat_obj, reduction = "pca")[, seq_len(n_pcs)]
  182. )
  183. full_bias_pcs <- which(abs(full_pc_corr[1, ]) > bias_threshold)
  184. full_good_pcs <- setdiff(seq_len(n_pcs), full_bias_pcs)
  185. # Store PCs used for downstream analyses
  186. seurat_obj@misc$cdst_pcs_used <- full_good_pcs
  187. seurat_obj@misc$cdst_bias_pcs <- full_bias_pcs
  188. seurat_obj@misc$cdst_rf_model <- rf_model
  189. # Run UMAP and tSNE
  190. if (verbose) cli::cli_inform("Running UMAP and tSNE...")
  191. seurat_obj <- Seurat::RunUMAP(seurat_obj, dims = full_good_pcs,
  192. n.neighbors = 25, min.dist = 0.4,
  193. verbose = FALSE)
  194. seurat_obj <- Seurat::RunTSNE(seurat_obj, dims = full_good_pcs,
  195. verbose = FALSE)
  196. # ---- Provenance ----
  197. seurat_obj@misc$cdst_provenance_clustering <- cdst_provenance_entry(
  198. "clustering",
  199. params = list(
  200. n_pcs = n_pcs, bias_threshold = bias_threshold,
  201. annoy_trees = annoy_trees, k_neighbors = k_neighbors,
  202. resolution = resolution, rf_ntree = rf_ntree,
  203. bias_pcs_excluded = bias_pcs,
  204. n_clusters = n_clusters, seed = seed
  205. ),
  206. start_time = start_time
  207. )
  208. if (verbose) {
  209. cli::cli_inform(c(
  210. "v" = "Clustering complete.",
  211. "i" = "Clusters: {.val {n_clusters}}",
  212. "i" = "All cells labeled via RF propagation."
  213. ))
  214. }
  215. seurat_obj
  216. }
  217. # ============================================================================
  218. # 3B. Neurotransmitter Classification
  219. # ============================================================================
  220. #' Classify Neurotransmitter Types
  221. #'
  222. #' Assigns neurotransmitter type labels to each cell based on marker gene
  223. #' expression in the log2CPM assay. Supports 8 neurotransmitter types:
  224. #' Glutamatergic, GABAergic, Glycinergic, Cholinergic, Dopaminergic,
  225. #' Serotonergic, Noradrenergic, and Histaminergic.
  226. #'
  227. #' This function generalizes \code{Neural_Transmitter_Process.R}, replacing
  228. #' the cell-by-cell loop with vectorized operations for performance, and
  229. #' making the marker gene criteria configurable via YAML.
  230. #'
  231. #' @param seurat_obj A Seurat object with a log2CPM assay.
  232. #' @param criteria_path Character. Path to a YAML file defining NT marker
  233. #' criteria. If NULL, uses the built-in default criteria for the species.
  234. #' @param threshold Numeric. log2CPM expression threshold. Default: from criteria file.
  235. #' @param min_fraction Numeric. Minimum fraction of cluster cells expressing
  236. #' a marker for cluster-level assignment. Default: from criteria file.
  237. #' @param verbose Logical. Default: TRUE.
  238. #'
  239. #' @return The Seurat object with new metadata column \code{cdst_nt_type}.
  240. #'
  241. #' @details
  242. #' The classification logic follows the original CellDynamicST approach:
  243. #' \enumerate{
  244. #' \item For each cell, check if any marker gene for each NT type exceeds
  245. #' the log2CPM threshold.
  246. #' \item For complex NT types (GABA, Dopamine, Serotonin, Noradrenaline),
  247. #' require both a transporter AND an enzyme to be expressed.
  248. #' \item Cells expressing markers for multiple NT types receive a combined
  249. #' label (e.g., "Glut-GABA").
  250. #' \item Cells with no NT markers are labeled "Undefined".
  251. #' }
  252. #'
  253. #' @examples
  254. #' \dontrun{
  255. #' obj <- cdst_classify_nt(obj)
  256. #' table(obj$cdst_nt_type)
  257. #' }
  258. #'
  259. #' @export
  260. cdst_classify_nt <- function(seurat_obj,
  261. criteria_path = NULL,
  262. threshold = NULL,
  263. min_fraction = NULL,
  264. verbose = TRUE) {
  265. validate_seurat(seurat_obj)
  266. start_time <- Sys.time()
  267. # Load criteria
  268. criteria <- cdst_default_nt_criteria(criteria_path)
  269. threshold <- threshold %||% criteria$threshold
  270. min_fraction <- min_fraction %||% criteria$min_fraction
  271. if (verbose) {
  272. cli::cli_inform(c(
  273. "Classifying neurotransmitter types...",
  274. "i" = "Threshold: log2CPM > {threshold}",
  275. "i" = "NT types: {length(criteria$neurotransmitter_types)}"
  276. ))
  277. }
  278. # Get log2CPM data
  279. if ("log2CPM" %in% Seurat::Assays(seurat_obj)) {
  280. expr_data <- Seurat::GetAssayData(seurat_obj, assay = "log2CPM", layer = "data")
  281. } else {
  282. if (verbose) cli::cli_inform("log2CPM assay not found. Computing from counts...")
  283. seurat_obj <- .compute_log2cpm(seurat_obj)
  284. expr_data <- Seurat::GetAssayData(seurat_obj, assay = "log2CPM", layer = "data")
  285. }
  286. # Effective threshold (accounting for log2(x+1) transform)
  287. effective_threshold <- log2(2^threshold + 1)
  288. available_genes <- rownames(expr_data)
  289. # ---- Vectorized classification ----
  290. n_cells <- ncol(expr_data)
  291. nt_labels <- character(n_cells)
  292. for (i in seq_len(n_cells)) {
  293. cell_expr <- expr_data[, i, drop = FALSE]
  294. types_found <- character(0)
  295. for (nt in criteria$neurotransmitter_types) {
  296. markers <- nt$markers
  297. markers_present <- intersect(markers, available_genes)
  298. if (length(markers_present) == 0) next
  299. # Check if any marker exceeds threshold
  300. expressed <- any(cell_expr[markers_present, 1] > effective_threshold,
  301. na.rm = TRUE)
  302. if (expressed) {
  303. types_found <- c(types_found, nt$abbreviation)
  304. }
  305. }
  306. if (length(types_found) > 0) {
  307. nt_labels[i] <- paste(types_found, collapse = "-")
  308. } else {
  309. nt_labels[i] <- "Undefined"
  310. }
  311. }
  312. seurat_obj$cdst_nt_type <- nt_labels
  313. if (verbose) {
  314. nt_table <- table(nt_labels)
  315. cli::cli_inform(c(
  316. "v" = "NT classification complete.",
  317. "i" = "Defined: {sum(nt_labels != 'Undefined')} cells ({round(sum(nt_labels != 'Undefined')/n_cells*100, 1)}%)",
  318. "i" = "Undefined: {sum(nt_labels == 'Undefined')} cells"
  319. ))
  320. }
  321. seurat_obj
  322. }
  323. #' Load Default Neurotransmitter Classification Criteria
  324. #'
  325. #' Loads the built-in or user-specified neurotransmitter marker gene criteria
  326. #' from a YAML file.
  327. #'
  328. #' @param criteria_path Character. Path to a YAML criteria file. If NULL,
  329. #' loads the built-in default for mouse.
  330. #'
  331. #' @return A list with fields: threshold, min_fraction, neurotransmitter_types.
  332. #'
  333. #' @export
  334. cdst_default_nt_criteria <- function(criteria_path = NULL) {
  335. if (is.null(criteria_path)) {
  336. criteria_path <- system.file("extdata", "default_nt_criteria_mouse.yaml",
  337. package = "CellDynamicST")
  338. }
  339. checkmate::assert_file_exists(criteria_path)
  340. yaml::read_yaml(criteria_path)
  341. }
  342. # ============================================================================
  343. # 3C. Glial Cell Classification
  344. # ============================================================================
  345. #' Classify Glial and Non-Neuronal Cell Types
  346. #'
  347. #' Identifies glial and non-neuronal cell types (astrocytes, microglia,
  348. #' oligodendrocytes, OPCs, ependymal, endothelial, pericytes) based on
  349. #' marker gene expression. Uses a case-insensitive matching approach against
  350. #' the top marker genes for each cluster.
  351. #'
  352. #' This function generalizes \code{annotate_glia_type.R}, replacing hardcoded
  353. #' criteria with a configurable YAML file and making the classification
  354. #' compatible with any spatial transcriptomic dataset.
  355. #'
  356. #' @param seurat_obj A Seurat object with cluster assignments.
  357. #' @param criteria_path Character. Path to a YAML file defining glial marker
  358. #' criteria. If NULL, uses the built-in default.
  359. #' @param cluster_column Character. Metadata column with cluster IDs.
  360. #' Default: "cdst_cluster".
  361. #' @param verbose Logical. Default: TRUE.
  362. #'
  363. #' @return The Seurat object with new metadata column \code{cdst_glia_type}.
  364. #'
  365. #' @export
  366. cdst_classify_glia <- function(seurat_obj,
  367. criteria_path = NULL,
  368. cluster_column = "cdst_cluster",
  369. verbose = TRUE) {
  370. validate_seurat(seurat_obj, required_metadata = cluster_column)
  371. start_time <- Sys.time()
  372. # Load criteria
  373. criteria <- cdst_default_glia_criteria(criteria_path)
  374. if (verbose) {
  375. cli::cli_inform(c(
  376. "Classifying glial/non-neuronal cell types...",
  377. "i" = "Glial types: {length(criteria$glial_types)}"
  378. ))
  379. }
  380. # Get expression data
  381. if ("log2CPM" %in% Seurat::Assays(seurat_obj)) {
  382. expr_data <- Seurat::GetAssayData(seurat_obj, assay = "log2CPM", layer = "data")
  383. } else {
  384. expr_data <- Seurat::GetAssayData(seurat_obj, layer = "data")
  385. }
  386. available_genes <- rownames(expr_data)
  387. threshold <- criteria$threshold %||% 3.0
  388. # ---- Find top marker genes per cluster ----
  389. clusters <- unique([email hidden][[cluster_column]])
  390. # For each cluster, find the top expressed genes
  391. cluster_markers <- list()
  392. for (cl in clusters) {
  393. cells_in_cluster <- which([email hidden][[cluster_column]] == cl)
  394. if (length(cells_in_cluster) < 5) next
  395. # Mean expression per gene in this cluster
  396. mean_expr <- Matrix::rowMeans(expr_data[, cells_in_cluster, drop = FALSE])
  397. top_genes <- names(sort(mean_expr, decreasing = TRUE))[1:20]
  398. cluster_markers[[as.character(cl)]] <- top_genes
  399. }
  400. # ---- Classify each cluster ----
  401. cluster_glia_type <- stats::setNames(
  402. rep("Neuronal", length(clusters)),
  403. as.character(clusters)
  404. )
  405. for (cl in names(cluster_markers)) {
  406. top_markers <- toupper(cluster_markers[[cl]])
  407. types_found <- character(0)
  408. for (glia in criteria$glial_types) {
  409. glia_markers <- toupper(glia$markers)
  410. if (any(top_markers %in% glia_markers)) {
  411. types_found <- c(types_found, glia$name)
  412. }
  413. }
  414. if (length(types_found) > 0) {
  415. cluster_glia_type[cl] <- paste(types_found, collapse = "-")
  416. }
  417. }
  418. # Map cluster-level labels to cells
  419. seurat_obj$cdst_glia_type <- cluster_glia_type[
  420. as.character([email hidden][[cluster_column]])
  421. ]
  422. if (verbose) {
  423. glia_table <- table(seurat_obj$cdst_glia_type)
  424. n_glia <- sum(seurat_obj$cdst_glia_type != "Neuronal")
  425. cli::cli_inform(c(
  426. "v" = "Glial classification complete.",
  427. "i" = "Neuronal: {sum(seurat_obj$cdst_glia_type == 'Neuronal')} cells",
  428. "i" = "Non-neuronal: {n_glia} cells"
  429. ))
  430. }
  431. seurat_obj
  432. }
  433. #' Load Default Glial Classification Criteria
  434. #'
  435. #' @param criteria_path Character. Path to a YAML criteria file. If NULL,
  436. #' loads the built-in default for mouse.
  437. #'
  438. #' @return A list with fields: threshold, min_fraction, glial_types.
  439. #'
  440. #' @export
  441. cdst_default_glia_criteria <- function(criteria_path = NULL) {
  442. if (is.null(criteria_path)) {
  443. criteria_path <- system.file("extdata", "default_glia_criteria_mouse.yaml",
  444. package = "CellDynamicST")
  445. }
  446. checkmate::assert_file_exists(criteria_path)
  447. yaml::read_yaml(criteria_path)
  448. }
  449. # ============================================================================
  450. # 3D. Hierarchical Cell Type Annotation
  451. # ============================================================================
  452. #' Build Hierarchical Cell Type Annotations
  453. #'
  454. #' Constructs a multi-level cell type hierarchy by combining cluster identity,
  455. #' neurotransmitter type, glial classification, top marker genes, and brain
  456. #' region information. This produces the full annotation string used in the
  457. #' CellDynamicST paper (e.g., "Glut Slc17a7-Camk2a Isocortex-Hippocampus").
  458. #'
  459. #' This function generalizes \code{annotate_cell_type.R}, replacing hardcoded
  460. #' column names and thresholds with configurable parameters.
  461. #'
  462. #' @param seurat_obj A Seurat object with cluster, NT, and glia annotations.
  463. #' @param cluster_column Character. Cluster column. Default: "cdst_cluster".
  464. #' @param nt_column Character. NT type column. Default: "cdst_nt_type".
  465. #' @param glia_column Character. Glia type column. Default: "cdst_glia_type".
  466. #' @param region_column Character. Brain region column. Default: "brain_region_L3".
  467. #' @param nt_threshold Numeric. Minimum proportion of cells in a cluster with
  468. #' a given NT type to include it in the annotation. Default: 0.30.
  469. #' @param region_threshold Numeric. Minimum proportion for region annotation.
  470. #' Default: 0.30.
  471. #' @param n_top_nt Integer. Maximum number of NT types per cluster. Default: 3.
  472. #' @param n_top_regions Integer. Maximum number of regions per cluster. Default: 2.
  473. #' @param verbose Logical. Default: TRUE.
  474. #'
  475. #' @return The Seurat object with new metadata columns:
  476. #' \code{cdst_cell_type} (full annotation string),
  477. #' \code{cdst_superclass} (broadest classification: Neuronal/Glial/Other),
  478. #' \code{cdst_top_nt} (dominant NT type per cluster),
  479. #' \code{cdst_top_region} (dominant region per cluster).
  480. #'
  481. #' @export
  482. cdst_annotate_hierarchy <- function(seurat_obj,
  483. cluster_column = "cdst_cluster",
  484. nt_column = "cdst_nt_type",
  485. glia_column = "cdst_glia_type",
  486. region_column = "brain_region_L3",
  487. nt_threshold = 0.30,
  488. region_threshold = 0.30,
  489. n_top_nt = 3L,
  490. n_top_regions = 2L,
  491. verbose = TRUE) {
  492. required_cols <- c(cluster_column, nt_column)
  493. validate_seurat(seurat_obj, required_metadata = required_cols)
  494. start_time <- Sys.time()
  495. meta <- [email hidden]
  496. clusters <- unique(meta[[cluster_column]])
  497. if (verbose) {
  498. cli::cli_inform("Building hierarchical annotations for {length(clusters)} clusters...")
  499. }
  500. # ---- Compute per-cluster summaries ----
  501. cluster_annotations <- data.frame(
  502. cluster = character(0),
  503. top_nt = character(0),
  504. top_region = character(0),
  505. cell_type = character(0),
  506. superclass = character(0),
  507. stringsAsFactors = FALSE
  508. )
  509. for (cl in clusters) {
  510. cl_cells <- meta[meta[[cluster_column]] == cl, ]
  511. n_cl <- nrow(cl_cells)
  512. # --- NT type summary ---
  513. nt_expanded <- unlist(strsplit(cl_cells[[nt_column]], "-"))
  514. nt_counts <- table(nt_expanded)
  515. nt_props <- nt_counts / n_cl
  516. top_nts <- names(sort(nt_props[nt_props > nt_threshold], decreasing = TRUE))
  517. top_nts <- utils::head(top_nts, n_top_nt)
  518. top_nt_str <- if (length(top_nts) > 0) paste(top_nts, collapse = "-") else "Undefined"
  519. # --- Region summary ---
  520. if (region_column %in% colnames(cl_cells)) {
  521. region_counts <- table(cl_cells[[region_column]])
  522. region_props <- region_counts / n_cl
  523. top_regions <- names(sort(region_props[region_props > region_threshold],
  524. decreasing = TRUE))
  525. top_regions <- utils::head(top_regions, n_top_regions)
  526. top_region_str <- if (length(top_regions) > 0) {
  527. paste(top_regions, collapse = "-")
  528. } else {
  529. ""
  530. }
  531. } else {
  532. top_region_str <- ""
  533. }
  534. # --- Glia type ---
  535. if (glia_column %in% colnames(cl_cells)) {
  536. glia_vals <- cl_cells[[glia_column]]
  537. glia_mode <- names(sort(table(glia_vals), decreasing = TRUE))[1]
  538. } else {
  539. glia_mode <- "Neuronal"
  540. }
  541. # --- Superclass ---
  542. if (glia_mode != "Neuronal") {
  543. superclass <- "Non-Neuronal"
  544. } else if (top_nt_str != "Undefined") {
  545. superclass <- "Neuronal"
  546. } else {
  547. superclass <- "Unclassified"
  548. }
  549. # --- Full annotation ---
  550. parts <- c(top_nt_str, top_region_str)
  551. parts <- parts[nchar(parts) > 0]
  552. cell_type_str <- paste(parts, collapse = " ")
  553. cluster_annotations <- rbind(cluster_annotations, data.frame(
  554. cluster = as.character(cl),
  555. top_nt = top_nt_str,
  556. top_region = top_region_str,
  557. cell_type = cell_type_str,
  558. superclass = superclass,
  559. stringsAsFactors = FALSE
  560. ))
  561. }
  562. # ---- Map annotations to cells ----
  563. rownames(cluster_annotations) <- cluster_annotations$cluster
  564. cell_clusters <- as.character(meta[[cluster_column]])
  565. seurat_obj$cdst_cell_type <- cluster_annotations[cell_clusters, "cell_type"]
  566. seurat_obj$cdst_superclass <- cluster_annotations[cell_clusters, "superclass"]
  567. seurat_obj$cdst_top_nt <- cluster_annotations[cell_clusters, "top_nt"]
  568. seurat_obj$cdst_top_region <- cluster_annotations[cell_clusters, "top_region"]
  569. # Store annotation table in misc
  570. seurat_obj@misc$cdst_cluster_annotations <- cluster_annotations
  571. if (verbose) {
  572. n_types <- length(unique(cluster_annotations$cell_type))
  573. cli::cli_inform(c(
  574. "v" = "Hierarchical annotation complete.",
  575. "i" = "Unique cell types: {.val {n_types}}",
  576. "i" = "Superclasses: {.val {paste(unique(cluster_annotations$superclass), collapse = ', ')}}"
  577. ))
  578. }
  579. seurat_obj
  580. }
  581. #' Validate Cell Type Annotations Against Known Markers
  582. #'
  583. #' Cross-validates the assigned cell type annotations against a reference
  584. #' database of known cell type markers (e.g., CellMarker2). Reports
  585. #' concordance statistics and flags potential misannotations.
  586. #'
  587. #' @param seurat_obj A Seurat object with cell type annotations.
  588. #' @param marker_db Character. Path to a marker database file (CSV). If NULL,
  589. #' uses a minimal built-in reference.
  590. #' @param cluster_column Character. Default: "cdst_cluster".
  591. #' @param n_top_markers Integer. Number of top markers per cluster to check.
  592. #' Default: 10.
  593. #' @param verbose Logical. Default: TRUE.
  594. #'
  595. #' @return A data.frame with validation results per cluster.
  596. #'
  597. #' @export
  598. cdst_validate_markers <- function(seurat_obj,
  599. marker_db = NULL,
  600. cluster_column = "cdst_cluster",
  601. n_top_markers = 10L,
  602. verbose = TRUE) {
  603. validate_seurat(seurat_obj, required_metadata = cluster_column)
  604. if (verbose) cli::cli_inform("Validating cell type markers...")
  605. # Find markers for each cluster
  606. Seurat::Idents(seurat_obj) <- cluster_column
  607. markers <- Seurat::FindAllMarkers(
  608. seurat_obj,
  609. only.pos = TRUE,
  610. min.pct = 0.25,
  611. logfc.threshold = 0.25,
  612. verbose = FALSE
  613. )
  614. # Get top markers per cluster
  615. top_markers <- markers |>
  616. dplyr::group_by(.data$cluster) |>
  617. dplyr::slice_max(order_by = .data$avg_log2FC, n = n_top_markers) |>
  618. dplyr::summarise(
  619. top_genes = paste(.data$gene, collapse = ", "),
  620. n_markers = dplyr::n(),
  621. .groups = "drop"
  622. )
  623. if (verbose) {
  624. cli::cli_inform(c(
  625. "v" = "Marker validation complete.",
  626. "i" = "Clusters analyzed: {nrow(top_markers)}"
  627. ))
  628. }
  629. as.data.frame(top_markers)
  630. }

mod3-celltyping.R at commit 7110118, under other · at the source

Overview

Authors: Yihan Xie1,2, Anna K Leonard1, Omar Guessoum3, Kyle A Windisch1, Johnathan Schug3, Hilana El-Mekkoussi3, Adrienne Jo1, D Kacy Cullen2,4, Klaus H Kaestner3, Julie A Blendy1
  1. Departments of System Pharmacology and Translational Therapeutics, Perelman School of Medicine, University of Pennsylvania, Philadelphia, PA USA
  2. Department of Bioengineering, School of Engineering and Applied Science, University of Pennsylvania, Philadelphia, PA USA
  3. Department of Genetics, Perelman School of Medicine, University of Pennsylvania, Philadelphia, PA USA
  4. Department of Neurosurgery, Perelman School of Medicine, University of Pennsylvania, Philadelphia, PA USA
Institutions: University of Pennsylvania (United States)
Journal: Nature communications, volume 17, issue 1, article 8965
Dates: received 7 August 2025; accepted 9 July 2026; published online 23 July 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1038/s41467-026-75723-0 · PMID 42637754 · PMCID PMC13503859 · OpenAlex W7170095722
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: genetics / omics (modality), human (organism), mouse (organism), other condition (population), pain (population), cellular / molecular (subfield)
Methods: Connectivity, Statistics, Smoothing, state filtering, decompositions, Machine learning, Preprocessing, Graphs, Spectral & time-frequency
Keywords: Addiction, Genetics of the nervous system
MeSH: Opioid-Related Disorders*, Receptors, Opioid, mu*, Animals, Female, Genotype, Humans, Mice, Mice, Inbred C57BL, Neuroglia, Neurons, Polymorphism, Single Nucleotide, Spatial Transcriptomics, Transcriptome (* major topic)
Topic: Neuropeptides and Animal Physiology (Cellular and Molecular Neuroscience, Neuroscience), according to OpenAlex
Funding: U.S. Department of Health &amp; Human Services | NIH | National Institute of General Medical Sciences (GM159555); U.S. Department of Health &amp; Human Services | NIH | National Institute on Drug Abuse (DA054374, DA056599); U.S. Department of Health & Human Services | NIH | National Institute on Drug Abuse (NIDA) (DA056599, DA054374); U.S. Department of Health & Human Services | NIH | National Institute of General Medical Sciences (NIGMS) (GM159555); NIDA NIH HHS (R01 DA054374, R01 DA056599)
Citations: not cited yet (Europe PMC); 54 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repository

Its files are read in the Code ↔ Paper reader above, with 40 matches between paragraphs and lines of code.

GoogleXie/CellDynamicST

License: other
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 7110118ec6a355594aa27d14cfd0e639a6f1b4d3, 11 May 2026
Languages: R (31), Python (2), Quarto (1)
Size: 70 files, 34 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, CITATION.cff, environment (DESCRIPTION, docker-compose.yml, Dockerfile), tests, documentation, 7 notebooks
Not found: continuous integration
Tools: ggplot2 (12 files), Seurat (9 files), tidyverse (7 files), pheatmap (4 files), patchwork (3 files), Matplotlib (2 files), NumPy (2 files), pandas (2 files), AllenSDK (1 file), clusterProfiler (1 file), data.table (1 file), igraph (1 file), NetworkX (1 file), randomForest (1 file), reticulate (1 file), scikit-learn (1 file), SciPy (1 file), WGCNA (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
36 files

Code availability statement

The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-75723-0.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 34 scripts, each with its path and the digest of its content;
  • 40 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data availability statement

The paper has a data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-75723-0.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 10 authors, 2 keywords, 13 MeSH terms, 5 funders, 54 references.

Cite

This paper

Xie, Y., Leonard, A. K., Guessoum, O., Windisch, K. A., Schug, J., El-Mekkoussi, H., Jo, A., Cullen, D. K., Kaestner, K. H., & Blendy, J. A. (2026). Spatial transcriptomics reveals distinct cell type dynamics following opioid dependence in female mice with the common human μ-opioid receptor variant Oprm1 A118G. Nature communications, 17(1), 8965. https://doi.org/10.1038/s41467-026-75723-0

BibTeX

@article{xie2026spatial,
author = {Xie, Yihan and Leonard, Anna K and Guessoum, Omar and Windisch, Kyle A and Schug, Johnathan and El-Mekkoussi, Hilana and Jo, Adrienne and Cullen, D Kacy and Kaestner, Klaus H and Blendy, Julie A},
title = {{Spatial transcriptomics reveals distinct cell type dynamics following opioid dependence in female mice with the common human μ-opioid receptor variant Oprm1 A118G}},
journal = {Nature communications},
year = {2026},
month = jul,
volume = {17},
number = {1},
pages = {8965},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/s41467-026-75723-0},
url = {https://doi.org/10.1038/s41467-026-75723-0},
pmid = {42637754},
pmcid = {PMC13503859}
}

RIS

TY - JOUR
AU - Xie, Yihan
AU - Leonard, Anna K
AU - Guessoum, Omar
AU - Windisch, Kyle A
AU - Schug, Johnathan
AU - El-Mekkoussi, Hilana
AU - Jo, Adrienne
AU - Cullen, D Kacy
AU - Kaestner, Klaus H
AU - Blendy, Julie A
TI - Spatial transcriptomics reveals distinct cell type dynamics following opioid dependence in female mice with the common human μ-opioid receptor variant Oprm1 A118G
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/07/23
VL - 17
IS - 1
SP - 8965
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/s41467-026-75723-0
UR - https://doi.org/10.1038/s41467-026-75723-0
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41467-026-75723-0",
"type": "article-journal",
"title": "Spatial transcriptomics reveals distinct cell type dynamics following opioid dependence in female mice with the common human μ-opioid receptor variant Oprm1 A118G",
"container-title": "Nature communications",
"author": [
{
"family": "Xie",
"given": "Yihan"
},
{
"family": "Leonard",
"given": "Anna K"
},
{
"family": "Guessoum",
"given": "Omar"
},
{
"family": "Windisch",
"given": "Kyle A"
},
{
"family": "Schug",
"given": "Johnathan"
},
{
"family": "El-Mekkoussi",
"given": "Hilana"
},
{
"family": "Jo",
"given": "Adrienne"
},
{
"family": "Cullen",
"given": "D Kacy"
},
{
"family": "Kaestner",
"given": "Klaus H"
},
{
"family": "Blendy",
"given": "Julie A"
}
],
"container-title-short": "Nat Commun",
"volume": "17",
"issue": "1",
"page": "8965",
"DOI": "10.1038/s41467-026-75723-0",
"PMID": "42637754",
"PMCID": "PMC13503859",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41467-026-75723-0",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
23
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: randomForest, WGCNA, reticulate, 14 other tools, mouse, cellular / molecular, 1 reference
[2] doi:10.1093/bioinformatics/btag592 [code]
Network-based stratification of allele-specific expression reveals patient subgroups in Huntington's disease.
Journal: Bioinformatics (Oxford, England)
In common: randomForest, WGCNA, reticulate, 13 other tools, genetics / omics, other condition
[3] doi:10.1016/j.xcrm.2026.102766 [code]
A longitudinal single-cell and spatial multiomic atlas of pediatric high-grade glioma.
Journal: Cell reports. Medicine
In common: WGCNA, igraph, clusterProfiler, 12 other tools, genetics / omics, other condition, cellular / molecular, 2 references
[4] doi:10.1111/adb.70179 [code]
Transcriptional Response to Chronic Long-Access Fentanyl Self-Administration in Rat Habenula and Amygdala.
Journal: Addiction biology
In common: clusterProfiler, pheatmap, Seurat, 3 other tools, pain, genetics / omics, other condition, 1 other category, 6 references
[5] doi:10.1038/s41467-026-76675-1 [code]
Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms.
Journal: Nature communications
In common: WGCNA, reticulate, igraph, 12 other tools, genetics / omics
[6] doi:10.1126/sciadv.aeg3223 [code]
The extreme diversity of retinal amacrine cells has deep evolutionary roots.
Journal: Science advances
In common: WGCNA, reticulate, igraph, 11 other tools, genetics / omics, cellular / molecular, 1 reference
[7] doi:10.1186/s13059-026-04177-w [code]
Genomic sequence evolution underlying human neocortical interareal diversification.
Journal: Genome biology
In common: AllenSDK, reticulate, igraph, 10 other tools, genetics / omics, mouse, cellular / molecular, 1 reference
[8] doi:10.1038/s41467-026-73305-8 [code]
Comparative analysis of the cellular landscape in mammalian striatum.
Journal: Nature communications
In common: WGCNA, clusterProfiler, pheatmap, 8 other tools, genetics / omics, mouse, cellular / molecular, 3 references
[9] doi:10.1038/s41586-026-10629-x [code]
Whole-genome duplication shaped cell-type evolution in the vertebrate brain.
Journal: Nature
In common: reticulate, igraph, clusterProfiler, 11 other tools, genetics / omics, mouse, cellular / molecular
[10] doi:10.1038/s41586-026-10214-2 [code]
Multidimensional profiling of heterogeneity in supratentorial ependymomas.
Journal: Nature
In common: reticulate, igraph, clusterProfiler, 11 other tools, genetics / omics, other condition, mouse

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.