Dual tumour-myeloid targeting of glioblastoma with GPNMB CAR-T cells.
The 5 matches
- [1] § scRNA-seq atlas of GPNMB+ CNS myeloid cells ↔ 03_gpnmb_scRNA_methods_reproducibility.Rmd, lines 436–561 · score 0.69 · Kruskal Wallis, polarization state, BH, M0, pairwise, M1
- [2] § GPNMB supports MES states and immune recruitment ↔ 01_export_gpnmb_wtko_publishable.Rmd, lines 340–393 · score 0.59 · FindMarkers, Seurat, enrichment, Neftel, DEGs, OPC
- [3] § GPNMB supports MES states and immune recruitment ↔ 03_gpnmb_scRNA_methods_reproducibility.Rmd, lines 300–355 · score 0.59 · FindMarkers, Seurat, enrichment, Neftel, DEGs, OPC
- [4] § Methods › GSEA and enrichment mapping ↔ 03_gpnmb_scRNA_methods_reproducibility.Rmd, lines 300–355 · score 0.52 · enrichment scores, GSEA, regenerated, pathway, filtering, RNA
- [5] § scRNA-seq atlas of GPNMB+ CNS myeloid cells ↔ 03_gpnmb_scRNA_methods_reproducibility.Rmd, lines 436–561 · score 0.51 · polarization states, simplified, signatures, M1, M2, GPNMB expression
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 Markdown · 607 lines · 27 KB · no license · 4 matches
- ---
- title: "GPNMB scRNA-seq methods reproducibility notebook"
- output:
- html_document:
- toc: true
- toc_float: false
- ---
- ```{r setup, include=FALSE}
- knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)
- ```
- ## 1. Inputs and provenance
- ```{r libraries}
- suppressPackageStartupMessages({
- library(Seurat)
- library(Matrix)
- library(parallel)
- library(foreach)
- library(doParallel)
- library(dplyr)
- library(tidyr)
- library(tibble)
- library(readr)
- library(readxl)
- library(stringr)
- library(ggplot2)
- library(patchwork)
- library(fgsea)
- })
- ```
- ```{r helpers}
- submission_dir <- normalizePath(getwd(), winslash = "/", mustWork = TRUE)
- analysis_dir <- normalizePath(file.path(submission_dir, ".."), winslash = "/", mustWork = TRUE)
- output_dir <- file.path(submission_dir, "outputs")
- stats_dir <- file.path(output_dir, "stats")
- fig_dir <- file.path(output_dir, "figures")
- dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)
- dir.create(stats_dir, recursive = TRUE, showWarnings = FALSE)
- dir.create(fig_dir, recursive = TRUE, showWarnings = FALSE)
- worker_count <- max(1L, parallel::detectCores() - 1L)
- doParallel::registerDoParallel(cores = worker_count)
- pick_first_match <- function(x, candidates) {
- hit <- candidates[candidates %in% x]
- if (length(hit) == 0) {
- return(NA_character_)
- }
- hit[[1]]
- }
- pick_feature_name <- function(object, candidates) {
- feat <- rownames(object)
- hit <- feat[toupper(feat) %in% toupper(candidates)]
- if (length(hit) == 0) {
- return(NA_character_)
- }
- hit[[1]]
- }
- pick_umap_reduction <- function(object, preferred = character()) {
- reduction_names <- names(object@reductions)
- preferred_hit <- preferred[preferred %in% reduction_names]
- if (length(preferred_hit) > 0) {
- return(preferred_hit[[1]])
- }
- umap_hit <- reduction_names[grepl("umap", reduction_names, ignore.case = TRUE)]
- if (length(umap_hit) > 0) {
- return(umap_hit[[1]])
- }
- two_dim_hit <- reduction_names[vapply(
- reduction_names,
- function(reduction_name) {
- embedding <- tryCatch(SeuratObject::Embeddings(object[[reduction_name]]), error = function(e) NULL)
- !is.null(embedding) && ncol(embedding) >= 2
- },
- logical(1)
- )]
- if (length(two_dim_hit) > 0) {
- return(two_dim_hit[[1]])
- }
- stop("No UMAP-like or other 2D reduction found in the Seurat object.")
- }
- save_plot_pair <- function(plot_handle, stem, width = 8, height = 6) {
- ggsave(filename = paste0(stem, ".pdf"), plot = plot_handle, width = width, height = height, units = "in")
- ggsave(filename = paste0(stem, ".png"), plot = plot_handle, width = width, height = height, units = "in", dpi = 300)
- }
- extract_named_list <- function(x) {
- if (is.list(x) && !is.data.frame(x)) {
- out <- lapply(x, function(y) unique(as.character(stats::na.omit(y))))
- out <- out[lengths(out) > 0]
- return(out)
- }
- if (is.data.frame(x)) {
- out <- lapply(x, function(y) unique(as.character(stats::na.omit(y))))
- out <- out[lengths(out) > 0]
- return(out)
- }
- stop("Could not coerce the gene set container into a named list.")
- }
- wide_df_to_named_list <- function(df) {
- out <- lapply(df, function(col) {
- col <- as.character(col)
- col <- col[!is.na(col) & nzchar(col)]
- unique(col)
- })
- out[lengths(out) > 0]
- }
- normalize_condition <- function(existing, barcode, sample_id) {
- out <- rep(NA_character_, length(barcode))
- if (!is.null(existing)) {
- out <- as.character(existing)
- }
- joined <- paste(barcode, sample_id, out)
- out[grepl("gpnmb|ko", joined, ignore.case = TRUE)] <- "KO"
- out[grepl("ctrl|wt|gl261", joined, ignore.case = TRUE)] <- "WT"
- out[grepl("pbs|sham", joined, ignore.case = TRUE)] <- "Sham"
- out
- }
- extract_named_vector <- function(x, cell_ids) {
- if (is.atomic(x) && !is.null(names(x))) {
- return(x[names(x) %in% cell_ids])
- }
- if (is.data.frame(x)) {
- id_col <- pick_first_match(colnames(x), c("cell_id", "cell", "barcode", "sample", "rownames"))
- value_col <- pick_first_match(colnames(x), c("state", "subtype", "label", "assignment", "class"))
- if (!is.na(id_col) && !is.na(value_col)) {
- out <- x[[value_col]]
- names(out) <- x[[id_col]]
- return(out[names(out) %in% cell_ids])
- }
- }
- if (is.list(x)) {
- for (element in x) {
- current <- tryCatch(extract_named_vector(element, cell_ids), error = function(e) NULL)
- if (!is.null(current) && length(current) > 0) {
- return(current)
- }
- }
- }
- NULL
- }
- run_safe_fgsea <- function(pathways, stats_tbl) {
- stats_vec <- stats_tbl$avg_log2FC
- names(stats_vec) <- stats_tbl$gene
- stats_vec <- stats_vec[!is.na(stats_vec)]
- stats_vec <- stats_vec[!duplicated(names(stats_vec))]
- stats_vec <- sort(stats_vec, decreasing = TRUE)
- fgsea::fgsea(pathways = pathways, stats = stats_vec, minSize = 5, maxSize = 500)
- }
- ```
- ```{r manifest}
- manifest <- tibble::tribble(
- ~domain, ~label, ~path, ~notes,
- "tumor", "Local tumor-side Seurat object", file.path(analysis_dir, "GPNMB_seurat_object_GL261_and_myeloid_111024.rds"), "Primary local tumor object for reproducible release",
- "tumor", "Legacy Reboot2 upstream object", "C:/Users/n mikolajewicz/Dropbox/PDF Projects - JM/Data/scRNA-seq/01_sci-RNA-seq3_Hong_Kevin_Jason/NM_HH/Data/Preprocessed_Datasets/R727_M02_HH_SET4_GL261_Gpnmb_reboot_rPCA_integration_240322.Rdata", "Documented provenance from Reboot2",
- "tumor", "Legacy GPNMB_02 upstream object", "R760_M01_NM2_r18_Neil_Gpnmb_Mm_081023.Rdata", "Documented provenance from GPNMB_02",
- "tumor", "Reference atlas", file.path(analysis_dir, "R726_M02_HH_SET1_allGBM_reboot_rPCA_integration_ANNOTATED_220422.rds"), "Documented provenance",
- "myeloid", "Integrated myeloid object", file.path(analysis_dir, "seurat_all_myeloid_160523.rds"), "Primary local myeloid object for reproducible release",
- "myeloid", "Myeloid NMF object", file.path(analysis_dir, "NMF_myeloid_v1_160523.rds"), "Program context",
- "myeloid", "Inferred-state object", file.path(analysis_dir, "ZM_myeloid_inferred_states.rds"), "State context",
- "myeloid", "GPNMB CDI object", file.path(analysis_dir, "ZMyeloid_03_CDI_GPNMB_Myeloid_050524.rds"), "Associated genes"
- )
- readr::write_tsv(manifest, file.path(stats_dir, "methods_object_manifest.tsv"))
- manifest
- ```
- ## 2. GL261 WT vs KO tumor object overview
- ```{r load-tumor}
- tumor_object_path <- manifest$path[manifest$label == "Local tumor-side Seurat object"]
- stopifnot(file.exists(tumor_object_path))
- so_tumor_all <- readRDS(tumor_object_path)
- tumor_umap <- pick_umap_reduction(so_tumor_all)
- tumor_meta <- [email hidden] %>%
- tibble::rownames_to_column("cell_id")
- tumor_barcode_col <- pick_first_match(colnames(tumor_meta), c("Barcode", "barcode", "sample", "orig.ident"))
- tumor_sample_col <- pick_first_match(colnames(tumor_meta), c("sample", "Barcode", "orig.ident"))
- tumor_condition_col <- pick_first_match(colnames(tumor_meta), c("condition", "Condition"))
- tumor_class_col <- pick_first_match(colnames(tumor_meta), c("class", "Class"))
- tumor_subclass_col <- pick_first_match(colnames(tumor_meta), c("subclass", "Subclass"))
- tumor_meta$barcode_id <- if (!is.na(tumor_barcode_col)) as.character(tumor_meta[[tumor_barcode_col]]) else tumor_meta$cell_id
- tumor_meta$sample_id <- if (!is.na(tumor_sample_col)) as.character(tumor_meta[[tumor_sample_col]]) else tumor_meta$barcode_id
- tumor_meta$condition_clean <- normalize_condition(
- existing = if (!is.na(tumor_condition_col)) tumor_meta[[tumor_condition_col]] else NULL,
- barcode = tumor_meta$barcode_id,
- sample_id = tumor_meta$sample_id
- )
- tumor_meta$class_clean <- if (!is.na(tumor_class_col)) as.character(tumor_meta[[tumor_class_col]]) else NA_character_
- tumor_meta$subclass_clean <- if (!is.na(tumor_subclass_col)) as.character(tumor_meta[[tumor_subclass_col]]) else NA_character_
- tumor_meta$is_tumor <- if (!is.na(tumor_class_col)) {
- grepl("tumor|gbm|glia", tumor_meta$class_clean, ignore.case = TRUE)
- } else {
- TRUE
- }
- so_tumor_all$condition_clean <- tumor_meta$condition_clean
- so_tumor_all$class_clean <- tumor_meta$class_clean
- so_tumor_all$subclass_clean <- tumor_meta$subclass_clean
- so_tumor_all$is_tumor <- tumor_meta$is_tumor
- tumor_gene_feature <- pick_feature_name(so_tumor_all, c("GPNMB", "Gpnmb"))
- tumor_state_cols <- intersect(
- c("gbm.index", "Richards_Developmental", "Richards_Injury_Response", "Neftel_AC", "Neftel_MES1", "Neftel_MES2", "Neftel_OPC", "Neftel_NPC1", "Neftel_NPC2"),
- colnames(tumor_meta)
- )
- tumor_overview <- tibble::tribble(
- ~field, ~value,
- "Tumor object", basename(tumor_object_path),
- "UMAP reduction", tumor_umap,
- "Condition column", ifelse(is.na(tumor_condition_col), "derived from barcode/sample", tumor_condition_col),
- "Class column", ifelse(is.na(tumor_class_col), "not present", tumor_class_col),
- "Subclass column", ifelse(is.na(tumor_subclass_col), "not present", tumor_subclass_col),
- "Tumor-state columns detected", paste(tumor_state_cols, collapse = ", ")
- )
- readr::write_tsv(tumor_overview, file.path(stats_dir, "methods_tumor_overview.tsv"))
- tumor_overview
- ```
- ## 3. Tumor UMAP reproduction with key annotations
- ```{r tumor-umaps}
- p_tumor_condition <- DimPlot(so_tumor_all, reduction = tumor_umap, group.by = "condition_clean", raster = FALSE) +
- ggtitle("Tumor-side object", subtitle = "WT / KO / sham condition")
- save_plot_pair(p_tumor_condition, file.path(fig_dir, "methods_tumor_umap_condition"), width = 8, height = 6)
- if (!is.na(tumor_class_col)) {
- p_tumor_class <- DimPlot(so_tumor_all, reduction = tumor_umap, group.by = "class_clean", raster = FALSE, label = TRUE, repel = TRUE) +
- ggtitle("Tumor-side object", subtitle = "Class annotation")
- save_plot_pair(p_tumor_class, file.path(fig_dir, "methods_tumor_umap_class"), width = 9, height = 7)
- }
- if (!is.na(tumor_subclass_col)) {
- p_tumor_subclass <- DimPlot(so_tumor_all, reduction = tumor_umap, group.by = "subclass_clean", raster = FALSE, label = FALSE) +
- ggtitle("Tumor-side object", subtitle = "Subclass annotation")
- save_plot_pair(p_tumor_subclass, file.path(fig_dir, "methods_tumor_umap_subclass"), width = 10, height = 8)
- }
- if (!is.na(tumor_gene_feature)) {
- p_tumor_gpnmb <- FeaturePlot(so_tumor_all, reduction = tumor_umap, features = tumor_gene_feature, raster = FALSE) +
- ggtitle("Tumor-side object", subtitle = paste0(tumor_gene_feature, " expression"))
- save_plot_pair(p_tumor_gpnmb, file.path(fig_dir, "methods_tumor_umap_gpnmb"), width = 8, height = 6)
- }
- ```
- ## 4. WT vs KO Neftel / GBM-state summaries and sample-level statistics
- ```{r tumor-state-summary}
- if (length(tumor_state_cols) > 0) {
- tumor_state_cell <- tumor_meta %>%
- dplyr::filter(is_tumor, condition_clean %in% c("WT", "KO")) %>%
- dplyr::select(cell_id, sample_id, barcode_id, condition_clean, dplyr::all_of(tumor_state_cols)) %>%
- tidyr::pivot_longer(cols = dplyr::all_of(tumor_state_cols), names_to = "state", values_to = "score")
- } else {
- tumor_state_cell <- tibble::tibble()
- }
- if (nrow(tumor_state_cell) > 0) {
- tumor_state_sample <- tumor_state_cell %>%
- dplyr::group_by(sample_id, barcode_id, condition_clean, state) %>%
- dplyr::summarise(score_mean = mean(score, na.rm = TRUE), score_median = median(score, na.rm = TRUE), n_cells = dplyr::n(), .groups = "drop")
- tumor_state_stats <- tumor_state_sample %>%
- dplyr::group_by(state) %>%
- dplyr::summarise(
- p_value_t_test = tryCatch(t.test(score_mean ~ condition_clean)$p.value, error = function(e) NA_real_),
- wt_samples = dplyr::n_distinct(sample_id[condition_clean %in% "WT"]),
- ko_samples = dplyr::n_distinct(sample_id[condition_clean %in% "KO"]),
- wt_cells = sum(n_cells[condition_clean %in% "WT"], na.rm = TRUE),
- ko_cells = sum(n_cells[condition_clean %in% "KO"], na.rm = TRUE),
- .groups = "drop"
- )
- readr::write_tsv(tumor_state_sample, file.path(stats_dir, "methods_tumor_state_sample_level.tsv"))
- readr::write_tsv(tumor_state_stats, file.path(stats_dir, "methods_tumor_state_stats.tsv"))
- }
- ```
- ## 5. ED2-style GSEA ranking and plot regeneration
- ```{r tumor-gsea}
- so_tumor_only <- so_tumor_all[, tumor_meta$is_tumor & tumor_meta$condition_clean %in% c("WT", "KO")]
- so_tumor_only$condition_clean <- factor(tumor_meta$condition_clean[tumor_meta$is_tumor & tumor_meta$condition_clean %in% c("WT", "KO")])
- Idents(so_tumor_only) <- so_tumor_only$condition_clean
- if (length(unique(as.character(Idents(so_tumor_only)))) >= 2) {
- tumor_deg <- Seurat::FindMarkers(
- object = so_tumor_only,
- ident.1 = "WT",
- ident.2 = "KO",
- test.use = "wilcox",
- logfc.threshold = 0,
- min.pct = 0
- )
- tumor_deg$gene <- rownames(tumor_deg)
- tumor_deg <- tumor_deg %>% tibble::as_tibble() %>% dplyr::arrange(desc(avg_log2FC))
- readr::write_tsv(tumor_deg, file.path(stats_dir, "methods_tumor_wilcox_deg.tsv"))
- if (requireNamespace("scMiko", quietly = TRUE)) {
- gene_sets_raw <- scMiko::geneSets[["GBM_Hs_Neftel2019"]]
- gene_sets <- extract_named_list(gene_sets_raw)
- keep <- intersect(names(gene_sets), c("AC", "MES1", "MES2", "OPC", "NPC1", "NPC2", "Neftel_AC", "Neftel_MES1", "Neftel_MES2", "Neftel_OPC", "Neftel_NPC1", "Neftel_NPC2"))
- gene_sets <- gene_sets[keep]
- names(gene_sets) <- gsub("^Neftel_", "", names(gene_sets))
- gsea_tbl <- run_safe_fgsea(gene_sets, tumor_deg) %>%
- tibble::as_tibble() %>%
- dplyr::arrange(padj, pval)
- readr::write_tsv(gsea_tbl, file.path(stats_dir, "methods_tumor_neftel_gsea.tsv"))
- ranked_stats <- tumor_deg$avg_log2FC
- names(ranked_stats) <- tumor_deg$gene
- ranked_stats <- ranked_stats[!duplicated(names(ranked_stats))]
- ranked_stats <- sort(ranked_stats, decreasing = TRUE)
- for (current_pathway in intersect(c("AC", "MES1", "MES2", "OPC", "NPC1", "NPC2"), names(gene_sets))) {
- this_row <- gsea_tbl %>% dplyr::filter(pathway == current_pathway)
- p <- fgsea::plotEnrichment(gene_sets[[current_pathway]], ranked_stats) +
- labs(
- title = paste0("ED2-style WT vs KO GSEA: ", current_pathway),
- subtitle = if (nrow(this_row) > 0) {
- paste0("NES = ", signif(this_row$NES[[1]], 3), "; p = ", signif(this_row$pval[[1]], 3))
- } else {
- "FGSEA result"
- },
- x = "Ranked differential-expression statistic",
- y = "Enrichment score"
- ) +
- theme_bw()
- save_plot_pair(p, file.path(fig_dir, paste0("methods_ed2_neftel_gsea_", tolower(current_pathway))), width = 7, height = 5)
- }
- }
- }
- ```
- ## 6. Myeloid meta-atlas overview
- ```{r load-myeloid}
- myeloid_object_path <- manifest$path[manifest$label == "Integrated myeloid object"]
- stopifnot(file.exists(myeloid_object_path))
- so_myeloid <- readRDS(myeloid_object_path)
- # Prefer the stored BBKNN embedding ("b") for the integrated myeloid object.
- myeloid_umap <- pick_umap_reduction(so_myeloid, preferred = "b")
- myeloid_meta <- [email hidden] %>%
- tibble::rownames_to_column("cell_id")
- myeloid_sample_col <- pick_first_match(colnames(myeloid_meta), c("clean.id2", "clean.id", "sample", "Barcode", "orig.ident"))
- myeloid_study_col <- pick_first_match(colnames(myeloid_meta), c("study", "Study"))
- myeloid_etiology_col <- pick_first_match(colnames(myeloid_meta), c("etiology", "type", "diagnosis", "PR", "PR2"))
- myeloid_state_col <- pick_first_match(colnames(myeloid_meta), c("subtype", "state", "label", "assignment", "class", "G1"))
- myeloid_meta$sample_id <- if (!is.na(myeloid_sample_col)) as.character(myeloid_meta[[myeloid_sample_col]]) else myeloid_meta$cell_id
- myeloid_meta$study_clean <- if (!is.na(myeloid_study_col)) as.character(myeloid_meta[[myeloid_study_col]]) else "unspecified_study"
- myeloid_meta$etiology_clean <- if (!is.na(myeloid_etiology_col)) as.character(myeloid_meta[[myeloid_etiology_col]]) else "unspecified_etiology"
- myeloid_meta$state_clean <- if (!is.na(myeloid_state_col)) as.character(myeloid_meta[[myeloid_state_col]]) else NA_character_
- state_object_path <- manifest$path[manifest$label == "Inferred-state object"]
- if (file.exists(state_object_path)) {
- inferred_states <- readRDS(state_object_path)
- inferred_vector <- extract_named_vector(inferred_states, myeloid_meta$cell_id)
- if (!is.null(inferred_vector) && length(inferred_vector) > 0) {
- myeloid_meta$state_clean[match(names(inferred_vector), myeloid_meta$cell_id)] <- as.character(inferred_vector)
- }
- }
- so_myeloid$sample_id <- myeloid_meta$sample_id
- so_myeloid$study_clean <- myeloid_meta$study_clean
- so_myeloid$etiology_clean <- myeloid_meta$etiology_clean
- so_myeloid$state_clean <- myeloid_meta$state_clean
- myeloid_gene_feature <- pick_feature_name(so_myeloid, c("GPNMB", "Gpnmb"))
- myeloid_overview <- tibble::tribble(
- ~field, ~value,
- "Myeloid object", basename(myeloid_object_path),
- "UMAP reduction", myeloid_umap,
- "Study column", ifelse(is.na(myeloid_study_col), "not present", myeloid_study_col),
- "Etiology column", ifelse(is.na(myeloid_etiology_col), "not present", myeloid_etiology_col),
- "State column", ifelse(is.na(myeloid_state_col), "supplemented from inferred-state object when available", myeloid_state_col)
- )
- readr::write_tsv(myeloid_overview, file.path(stats_dir, "methods_myeloid_overview.tsv"))
- myeloid_overview
- ```
- ## 7. Myeloid UMAP reproduction with key annotations
- ```{r myeloid-umaps}
- if (!is.na(myeloid_study_col)) {
- p_myeloid_study <- DimPlot(so_myeloid, reduction = myeloid_umap, group.by = "study_clean", raster = FALSE) +
- ggtitle("Myeloid meta-atlas", subtitle = "Study / cohort")
- save_plot_pair(p_myeloid_study, file.path(fig_dir, "methods_myeloid_umap_study"), width = 10, height = 8)
- }
- if (!is.na(myeloid_etiology_col)) {
- p_myeloid_etiology <- DimPlot(so_myeloid, reduction = myeloid_umap, group.by = "etiology_clean", raster = FALSE) +
- ggtitle("Myeloid meta-atlas", subtitle = "Etiology / diagnosis")
- save_plot_pair(p_myeloid_etiology, file.path(fig_dir, "methods_myeloid_umap_etiology"), width = 10, height = 8)
- }
- if (any(!is.na(myeloid_meta$state_clean))) {
- p_myeloid_state <- DimPlot(so_myeloid, reduction = myeloid_umap, group.by = "state_clean", raster = FALSE) +
- ggtitle("Myeloid meta-atlas", subtitle = "Inferred state / subtype")
- save_plot_pair(p_myeloid_state, file.path(fig_dir, "methods_myeloid_umap_state"), width = 10, height = 8)
- }
- if (!is.na(myeloid_gene_feature)) {
- p_myeloid_gpnmb <- FeaturePlot(so_myeloid, reduction = myeloid_umap, features = myeloid_gene_feature, raster = FALSE) +
- ggtitle("Myeloid meta-atlas", subtitle = paste0(myeloid_gene_feature, " expression"))
- save_plot_pair(p_myeloid_gpnmb, file.path(fig_dir, "methods_myeloid_umap_gpnmb"), width = 8, height = 6)
- }
- ```
- ## 8. GPNMB expression across polarization states with manuscript-faithful tests
- ```{r myeloid-polarization}
- marker_dir <- "C:/Users/n mikolajewicz/Dropbox/PDF Projects - JM/Data/scRNA-seq/01_sci-RNA-seq3_Hong_Kevin_Jason/NM_HH/PR_GBM/Marker tables"
- smart_path <- file.path(marker_dir, "Smart_Signature.tsv")
- orecchioni_path <- file.path(marker_dir, "Orecchioni_2019_polarization_states.xlsx")
- buscher_path <- file.path(marker_dir, "Buscher_2017_polarization_states.xlsx")
- composite_polarization_cell <- tibble::tibble()
- composite_polarization_sample <- tibble::tibble()
- summary_tbl <- tibble::tibble()
- pairwise_tbl <- tibble::tibble()
- if (!is.na(myeloid_gene_feature) &&
- file.exists(smart_path) &&
- file.exists(orecchioni_path) &&
- file.exists(buscher_path) &&
- requireNamespace("scMiko", quietly = TRUE)) {
- smart.list <- wide_df_to_named_list(read.delim(smart_path) %>% dplyr::select(-tidyselect::any_of("X")))
- Orecchioni.2019.list <- wide_df_to_named_list(readxl::read_xlsx(orecchioni_path, "Sheet1"))
- Buscher.2017.list <- wide_df_to_named_list(readxl::read_xlsx(buscher_path, "Sheet1"))
- Jablonski.2015.list <- list(
- Jablonski.2015.M0 = c("Sh2d3c", "Slc13a3", "Rcan1", "4632428N05Rik", "Trp53inp1", "Nr1d2", "Fcgrt", "Slc40a1", "Nfxl1", "Il16"),
- Jablonski.2015.M1 = c("Cd38", "Cfb", "Slfn4", "H2-Q6", "Fpr1", "Slfn1", "Gpr18", "Ccrl2", "Fpr2", "Cxcl10", "Mpa2l", "Oasl1", "Tlr2", "Ms4a4c", "LOC100503664", "Irak3", "Hp", "Itgal", "Herc6", "Cd300lf", "Isf20", "Pstpip2", "Cp", "Isg15", "Probe 1452408_at", "E030037K03Rik", "Saa3", "Ifit1", "Marco", "F11r", "Rsad2", "Ddx60", "Pilr1", "Cpd", "Fam26f", "Aoah", "Gngt2", "Mx1", "Pyhin1", "Epb4.1l3", "Slfn8", "Arhgap24", "Nfkbiz", "Gbp6", "Stat1", "Zpb1", "D14Erd668e", "Ddx58", "Tuba4a", "Nfkbiz", "H2-T10", "Ebi3", "Stat1", "Fam176b", "Xaf1", "Gbp6", "Stat2", "Sepx1", "Ifit2"),
- Jablonski.2015.M2 = c("Ptgs1", "Egr2", "Olfm1", "Flrt2", "P2ry1", "Vwf", "Bcar3", "Il6st", "Tanc2", "Mmp12", "Tcfec", "Clec7a", "Matk", "Myc", "Clec10a", "Amz1", "Tmem158", "Tiam1", "Rhoj", "Mmp9", "Mrc1", "Atp6v0a1", "Lmna", "Chst7", "Atp6v0d2", "Gnb4", "Emp2", "Cd300ld", "Cd83", "Socs6", "Actn1", "Plk2", "Ptpla")
- )
- Colombo.2024.list <- list(
- Colombo.2024.M1 = c("Irf1", "Gbp5", "Batf2", "Gbp2", "Irgm1", "Igtp", "Gbp3", "Nampt", "Serpina3g", "Gbp7", "Cxcl10", "Nod1", "Gbp6", "Tap1", "Parp9", "Gbp9", "Casp4", "Gbp4", "Irgm2", "Pla2g4a", "Nlrc5", "Sp140", "Peli1", "Serpina3f", "Slco3a1", "Casp1", "Mlkl", "Il27"),
- Colombo.2024.M2 = c("Tmem26", "Slc7a2", "Arg1", "Smap2", "Flt1", "Chil3", "Mgl2", "Flrt2", "Cblb", "Ak2", "Irf4", "Klf4", "Nfil3", "Ap2m1", "Rnf19b", "Cish", "Batf3", "Il1rl2", "Plekhf1", "Mcf2l")
- )
- master.set <- c(smart.list, Jablonski.2015.list, Orecchioni.2019.list, Colombo.2024.list, Buscher.2017.list)
- master.set <- lapply(master.set, toupper)
- match.list <- list(
- Ghosh.2023 = c("Ghosh.2023.M1", "Ghosh.2023.M0", "Ghosh.2023.M2"),
- Becker.2015 = c("Becker.2015.M1", "Becker.2015.M2"),
- Bell.2016 = c("Bell.2016.M1", "Bell.2016.M2"),
- Coates.2008 = c("Coates.2008.M1", "Coates.2008.M2"),
- Martinez.2006 = c("Martinez.2006.M1", "Martinez.2006.M2"),
- LM22 = c("LM22.M0", "LM22.M1", "LM22.M2"),
- Murray.2017 = c("Murray.2017.M1", "Murray.2017.M2"),
- Jablonski.2015 = c("Jablonski.2015.M0", "Jablonski.2015.M1", "Jablonski.2015.M2"),
- Orecchioni.2019 = c("Orecchioni.2019.M1.invitro", "Orecchioni.2019.M2.invitro"),
- Buscher.2017 = c("Buscher.2017.M1.invivo", "Buscher.2017.M2.invivo"),
- Colombo.2024 = c("Colombo.2024.M1", "Colombo.2024.M2")
- )
- split_by <- if ("clean.id2" %in% colnames([email hidden])) "clean.id2" else "sample_id"
- so.hs <- SplitObject(so_myeloid, split.by = split_by)
- ms.res.list <- list()
- for (sname in names(so.hs)) {
- object <- so.hs[[sname]]
- ms.result <- scMiko::runMS(object = object, genelist = master.set, return.plots = FALSE, scale = FALSE)
- df.res <- ms.result[["data"]] %>% dplyr::select(-tidyselect::any_of("class.ms"))
- expr_df <- Seurat::FetchData(object, vars = myeloid_gene_feature)
- colnames(expr_df) <- "expr"
- df.res <- bind_cols(df.res, expr_df)
- df.res$sample_id <- sname
- ms.res.list[[sname]] <- df.res
- }
- df.expr <- bind_rows(ms.res.list)
- match.list <- lapply(match.list, function(x) x[x %in% colnames(df.expr)])
- match.list <- match.list[lengths(match.list) > 0]
- m0_cols <- unlist(match.list)[grepl("\\.M0", unlist(match.list))]
- m1_cols <- unlist(match.list)[grepl("\\.M1", unlist(match.list))]
- m2_cols <- unlist(match.list)[grepl("\\.M2", unlist(match.list))]
- if (length(m0_cols) > 0 && length(m1_cols) > 0 && length(m2_cols) > 0) {
- df.expr$composite.M0 <- Matrix::rowMeans(as.matrix(df.expr[, m0_cols, drop = FALSE]))
- df.expr$composite.M1 <- Matrix::rowMeans(as.matrix(df.expr[, m1_cols, drop = FALSE]))
- df.expr$composite.M2 <- Matrix::rowMeans(as.matrix(df.expr[, m2_cols, drop = FALSE]))
- composite_polarization_cell <- df.expr %>%
- dplyr::select(sample_id, expr, composite.M0, composite.M1, composite.M2) %>%
- dplyr::mutate(
- subtype = c("composite.M0", "composite.M1", "composite.M2")[max.col(as.matrix(dplyr::select(., composite.M0, composite.M1, composite.M2)), ties.method = "first")]
- )
- composite_polarization_sample <- composite_polarization_cell %>%
- dplyr::group_by(sample_id) %>%
- dplyr::mutate(expr_scaled = as.numeric(scale(expr))) %>%
- dplyr::group_by(sample_id, subtype) %>%
- dplyr::summarise(
- mean_expression = mean(expr_scaled, na.rm = TRUE),
- median_expression = median(expr_scaled, na.rm = TRUE),
- n_cells = dplyr::n(),
- .groups = "drop"
- )
- overall_kw <- tryCatch(kruskal.test(mean_expression ~ subtype, data = composite_polarization_sample)$p.value, error = function(e) NA_real_)
- pairwise_states <- sort(unique(composite_polarization_sample$subtype))
- if (length(pairwise_states) >= 2) {
- pairwise_tbl <- utils::combn(pairwise_states, 2, simplify = FALSE) %>%
- lapply(function(x) {
- current <- composite_polarization_sample %>% dplyr::filter(subtype %in% x)
- tibble::tibble(
- state_a = x[[1]],
- state_b = x[[2]],
- t_test_p = tryCatch(t.test(mean_expression ~ subtype, data = current)$p.value, error = function(e) NA_real_),
- wilcox_p = tryCatch(wilcox.test(mean_expression ~ subtype, data = current)$p.value, error = function(e) NA_real_)
- )
- }) %>%
- dplyr::bind_rows() %>%
- dplyr::mutate(t_test_p_adj_bh = p.adjust(t_test_p, method = "BH"))
- }
- summary_tbl <- tibble::tibble(
- test = c("kruskal_wallis_overall"),
- p_value = c(overall_kw)
- )
- readr::write_tsv(composite_polarization_cell, file.path(stats_dir, "methods_myeloid_polarization_composite_cell_level.tsv"))
- readr::write_tsv(composite_polarization_sample, file.path(stats_dir, "methods_myeloid_polarization_composite_sample_level.tsv"))
- readr::write_tsv(summary_tbl, file.path(stats_dir, "methods_myeloid_polarization_overall_tests.tsv"))
- readr::write_tsv(pairwise_tbl, file.path(stats_dir, "methods_myeloid_polarization_pairwise_tests.tsv"))
- }
- }
- ```
- ## 9. Sample-size summary generation for scRNA-seq panels
- ```{r sample-size-summary}
- sample_size_rows <- list()
- if (exists("composite_polarization_sample") && nrow(composite_polarization_sample) > 0) {
- sample_size_rows[["ED10D"]] <- composite_polarization_sample %>%
- dplyr::mutate(group = gsub("^composite\\.", "", subtype)) %>%
- dplyr::group_by(panel = "ED10D", group) %>%
- dplyr::summarise(
- dataset_object = basename(myeloid_object_path),
- biological_unit = "sample",
- biological_n = dplyr::n_distinct(sample_id),
- supporting_cell_count = sum(n_cells, na.rm = TRUE),
- note = "GPNMB expression across composite M0/M1/M2 polarization states",
- .groups = "drop"
- )
- }
- atlas_qc_rows <- myeloid_meta %>%
- dplyr::group_by(group = etiology_clean) %>%
- dplyr::summarise(
- dataset_object = basename(myeloid_object_path),
- biological_unit = "sample",
- biological_n = dplyr::n_distinct(sample_id),
- supporting_cell_count = dplyr::n(),
- note = "Atlas QC boxplots; attached PDF numbering differs from reviewer email",
- .groups = "drop"
- )
- sample_size_rows[["ED8D"]] <- atlas_qc_rows %>% dplyr::mutate(panel = "ED8D")
- sample_size_rows[["ED8E"]] <- atlas_qc_rows %>% dplyr::mutate(panel = "ED8E")
- sample_size_summary <- dplyr::bind_rows(sample_size_rows) %>%
- dplyr::select(panel, group, dataset_object, biological_unit, biological_n, supporting_cell_count, note)
- readr::write_tsv(sample_size_summary, file.path(output_dir, "sample_size_summary.tsv"))
- sample_size_summary
- ```
- ## 10. Session info and object manifest
- ```{r session-info}
- sessionInfo()
- ```
03_gpnmb_scRNA_methods_reproducibility.Rmd at commit f1d7843, no license · at the source
Overview
and 15 other authors
Nazanin Tatari1,2, Petar Miletic2,3, David Chen6,7, Sebastian Pacheco8, Abdelsimar T Omar10, Bill Wang10, Hong Han1,2, Jennifer A Chan4, Kevin R Brown6,7, Chitra Venugopal2,3, Thomas Kislinger11, Amy B Heimberger8, Jason Moffat6,7, Douglas J Mahoney4,12, Sheila K Singh1,2,3,1313 affiliations
- Department of Biochemistry and Biomedical Sciences, McMaster University, Hamilton, Ontario Canada
- Centre for Discovery in Cancer Research, McMaster University, Hamilton, Ontario Canada
- Department of Surgery, Faculty of Health Sciences, McMaster University, Hamilton, Ontario Canada
- Arnie Charbonneau Cancer Institute, Cumming School of Medicine, University of Calgary, Calgary, Alberta Canada
- Department of Biochemistry and Molecular Biology, University of Calgary, Calgary, Alberta Canada
- Department of Molecular Genetics, University of Toronto, Toronto, Ontario Canada
- Program in Genetics and Genome Biology, The Hospital for Sick Children, Toronto, Ontario Canada
- Feinberg School of Medicine, Northwestern University, Chicago, IL USA
- McMaster Immunology Research Centre, McMaster University, Hamilton, Ontario Canada
- Division of Neurosurgery, Department of Surgery, Faculty of Health Sciences, McMaster University, Hamilton, Ontario Canada
- Department of Medical Biophysics, University of Toronto, Toronto, Ontario Canada
- Department of Microbiology, Immunology and Infectious Disease, University of Calgary, Calgary, Alberta Canada
- School of Cancer and Pharmaceutical Sciences, Comprehensive Cancer Centre, King’s College London, London, UK
Abstract
Glioblastoma is a lethal brain tumour for which current multimodal treatment rarely prevents recurrence1. Therapeutic failure is driven by extensive intratumoural cellular heterogeneity2 with a microenvironment dominated by tumour-associated macrophages that sustain tumour growth and immunosuppression3. Although chimeric antigen receptor (CAR)-T cell therapies are being developed for glioblastoma, sustained response has been undermined by non-uniform antigen expression, antigen loss and microenvironmental barriers that are not directly engaged by tumour-targeting designs4. These limitations motivate new strategies that address the disease as a coupled tumour–immune system rather than a single malignant compartment. Here we use a multi-omic target discovery platform to identify GPNMB as a dual-compartment antigen in glioblastoma. Anti-GPNMB CAR-T cells showed potent anti-tumour activity, with long-term disease control in orthotopic patient-derived xenografts and syngeneic glioma models through concomitant depletion of GPNMB+ tumour and immunosuppressive myeloid populations. By collapsing tumour control and microenvironmental reprogramming, these findings provide a new strategy for antigen selection and targeting in heterogenous, myeloid-rich solid cancers.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repository
Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.
NMikolajewicz/Savage-2026
f1d784337ee3eb922be701bc03de2e72dd33ccff, 2 April 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
5 files
- 01_export_gpnmb_wtko_pub
lishable.Rmd , R, 418 lines, 1 match - 02_export_myeloid_meta_a
tlas_publishable.Rmd , R, 396 lines - 03_gpnmb_scRNA_methods_r
eproducibility.Rmd , R, 607 lines, 4 matches - 04_gpnmb_myeloid_meta_at
las_nmf_reproducibility. , R, 850 linesR - README.md, Text, 21 lines
Code availability
All analysis code is available at GitHub (https://
Reproduced under the paper's license (CC BY), from the paper cited above.
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;
- 4 scripts, each with its path and the digest of its content;
- 5 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
- arrayexpress:E-MTAB-8230
, at ArrayExpress; found in “Data availability” - figshare:25917628, at figshare; found in “Data availability”
- figshare:27643794, at figshare; found in the references
- geo:GSE177549, at NCBI GEO; found in “Data availability”
Data Availability Statement
Raw data for single-cell RNA experiments have been deposited as follows: primary and recurrent, 10.6084/
All analysis code is available at GitHub (https://
Reproduced under the paper's license (CC BY), from the paper cited above.
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 2, 28 September 2026
- Publisher: n/a → Nature Portfolio
Version 1, 27 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 35 authors, 3 keywords, 16 MeSH terms, 83 references.
Cite
This paper
Savage, N., Grewal, S., Shaikh, M. V., Zemp, F. J., Mckenna, D., Mikolajewicz, N., Najem, H., Pyczek, J., Wei, J., Taleb, M. A. B., Asselstine, L. C., Anand, A., Chafe, S. C., Zhai, K., Maich, W. T., Chokshi, C. R., Patel, H., Korman, T. E., Subapanditha, M., . . . Singh, S. K. (2026). Dual tumour-myeloid targeting of glioblastoma with GPNMB CAR-T cells. Nature, 656(8129), 1013-1022. https://
BibTeX
@article{savage2026dual,
author = {Savage, Neil and Grewal, Shan and Shaikh, Muhammad Vaseem and Zemp, Franz J and Mckenna, Dillon and Mikolajewicz, Nicholas and Najem, Hinda and Pyczek, Joanna and Wei, Jiuran and Taleb, Mohamed A B and Asselstine, Lucas C and Anand, Alisha and Chafe, Shawn C and Zhai, Kui and Maich, William T and Chokshi, Chirayu R and Patel, Hardikkumar and Korman, Tiegan E and Subapanditha, Minomi and Tabunshchyk, Zoya and Tatari, Nazanin and Miletic, Petar and Chen, David and Pacheco, Sebastian and Omar, Abdelsimar T and Wang, Bill and Han, Hong and Chan, Jennifer A and Brown, Kevin R and Venugopal, Chitra and Kislinger, Thomas and Heimberger, Amy B and Moffat, Jason and Mahoney, Douglas J and Singh, Sheila K},
title = {{Dual tumour-myeloid targeting of glioblastoma with GPNMB CAR-T cells}},
journal = {Nature},
year = {2026},
month = jul,
volume = {656},
number = {8129},
pages = {1013--1022},
publisher = {Nature Portfolio},
issn = {0028-0836},
doi = {10.1038/
url = {https://
pmid = {42386964},
pmcid = {PMC13518245}
}
RIS
TY - JOUR
AU - Savage, Neil
AU - Grewal, Shan
AU - Shaikh, Muhammad Vaseem
AU - Zemp, Franz J
AU - Mckenna, Dillon
AU - Mikolajewicz, Nicholas
AU - Najem, Hinda
AU - Pyczek, Joanna
AU - Wei, Jiuran
AU - Taleb, Mohamed A B
AU - Asselstine, Lucas C
AU - Anand, Alisha
AU - Chafe, Shawn C
AU - Zhai, Kui
AU - Maich, William T
AU - Chokshi, Chirayu R
AU - Patel, Hardikkumar
AU - Korman, Tiegan E
AU - Subapanditha, Minomi
AU - Tabunshchyk, Zoya
AU - Tatari, Nazanin
AU - Miletic, Petar
AU - Chen, David
AU - Pacheco, Sebastian
AU - Omar, Abdelsimar T
AU - Wang, Bill
AU - Han, Hong
AU - Chan, Jennifer A
AU - Brown, Kevin R
AU - Venugopal, Chitra
AU - Kislinger, Thomas
AU - Heimberger, Amy B
AU - Moffat, Jason
AU - Mahoney, Douglas J
AU - Singh, Sheila K
TI - Dual tumour-myeloid targeting of glioblastoma with GPNMB CAR-T cells
T2 - Nature
J2 - Nature
PY - 2026
DA - 2026/
VL - 656
IS - 8129
SP - 1013
EP - 1022
SN - 0028-0836
PB - Nature Portfolio
DO - 10.1038/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1038/
"type": "article-journal",
"title": "Dual tumour-myeloid targeting of glioblastoma with GPNMB CAR-T cells",
"container-title": "Nature",
"author": [
{
"family": "Savage",
"given": "Neil"
},
{
"family": "Grewal",
"given": "Shan"
},
{
"family": "Shaikh",
"given": "Muhammad Vaseem"
},
{
"family": "Zemp",
"given": "Franz J"
},
{
"family": "Mckenna",
"given": "Dillon"
},
{
"family": "Mikolajewicz",
"given": "Nicholas"
},
{
"family": "Najem",
"given": "Hinda"
},
{
"family": "Pyczek",
"given": "Joanna"
},
{
"family": "Wei",
"given": "Jiuran"
},
{
"family": "Taleb",
"given": "Mohamed A B"
},
{
"family": "Asselstine",
"given": "Lucas C"
},
{
"family": "Anand",
"given": "Alisha"
},
{
"family": "Chafe",
"given": "Shawn C"
},
{
"family": "Zhai",
"given": "Kui"
},
{
"family": "Maich",
"given": "William T"
},
{
"family": "Chokshi",
"given": "Chirayu R"
},
{
"family": "Patel",
"given": "Hardikkumar"
},
{
"family": "Korman",
"given": "Tiegan E"
},
{
"family": "Subapanditha",
"given": "Minomi"
},
{
"family": "Tabunshchyk",
"given": "Zoya"
},
{
"family": "Tatari",
"given": "Nazanin"
},
{
"family": "Miletic",
"given": "Petar"
},
{
"family": "Chen",
"given": "David"
},
{
"family": "Pacheco",
"given": "Sebastian"
},
{
"family": "Omar",
"given": "Abdelsimar T"
},
{
"family": "Wang",
"given": "Bill"
},
{
"family": "Han",
"given": "Hong"
},
{
"family": "Chan",
"given": "Jennifer A"
},
{
"family": "Brown",
"given": "Kevin R"
},
{
"family": "Venugopal",
"given": "Chitra"
},
{
"family": "Kislinger",
"given": "Thomas"
},
{
"family": "Heimberger",
"given": "Amy B"
},
{
"family": "Moffat",
"given": "Jason"
},
{
"family": "Mahoney",
"given": "Douglas J"
},
{
"family": "Singh",
"given": "Sheila K"
}
],
"container-title-short":
"volume": "656",
"issue": "8129",
"page": "1013-1022",
"DOI": "10.1038/
"PMID": "42386964",
"PMCID": "PMC13518245",
"ISSN": "0028-0836",
"publisher": "Nature Portfolio",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
1
]
]
}
}
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.1016/j.cell.2026.05.026 [code]
- The critical role of the endogenous immune compartment after CAR T cell therapy in recurrent GBM.Journal: CellIn common: Seurat, patchwork, ggplot2, 1 other tool, other condition, 8 references
- [2] doi:10.1038/s41586-026-10612-6 [code]
- Acquired genetic and cell-state changes in IDH-mutant glioma progression.Journal: NatureIn common: Seurat, patchwork, ggplot2, 1 other tool, other condition, cellular / molecular, 7 references
- [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. MedicineIn common: Seurat, patchwork, ggplot2, 1 other tool, other condition, cellular / molecular, 6 references
- [4] doi:10.1093/neuonc/noag119 [code]
- Single-nucleus profiling of postmortem diffuse midline gliomas identifies mitochondrial biogenesis as a resistance mechanism to imipridone therapy.Journal: Neuro-oncologyIn common: Seurat, patchwork, ggplot2, 1 other tool, other condition, 4 references
- [5] doi:10.1038/s41467-026-74058-0
- IQGAP3 bridges matrix stiffness with glioma stem cell maintenance and radioresistance by stabilizing SOX2.Journal: Nature communicationsIn common: other condition, mouse, cellular / molecular, 6 references
- [6] doi:10.1038/s41593-026-02316-x [code]
- Single-cell multi-omic atlas and morphogen screening informs midbrain and hindbrain organoid engineering.Journal: Nature neuroscienceIn common: Seurat, patchwork, ggplot2, 1 other tool, mouse, 3 references
- [7] doi:10.1371/journal.pbio.3003757 [code]
- Cell type-agnostic transcriptomic signatures enable uniform comparisons of neural maturation.Journal: PLoS biologyIn common: Seurat, ggplot2, tidyverse, mouse, 3 references
- [8] doi:10.1038/s41586-026-10310-3 [code]
- DNA damage burden causes selective CUX2 neuron loss in neuroinflammation.Journal: NatureIn common: Seurat, patchwork, ggplot2, 1 other tool, mouse, cellular / molecular, 2 references
- [9] doi:10.3390/ijms27104466 [code]
- Uncovering the Key Circuit FOSL2/
FOS/ EGR3/ EGR1, Contributing to the Hyperexcitability of Excitatory Neurons in the Epileptic Temporal Cortex and Hippocampus. Journal: International journal of molecular sciencesIn common: Seurat, patchwork, ggplot2, 1 other tool, 2 references - [10] doi:10.1038/s41597-026-07185-4 [code]
- A multi-center cross-platform single-cell multimodal atlas of the mouse cerebral cortex.Journal: Scientific dataIn common: Seurat, patchwork, ggplot2, 1 other tool, mouse, 2 references
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.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 4 scripts, and 5 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:cb1dd60f0bb0cbb1…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
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.
