MIC-Drop-seq: scalable single-cell phenotyping of mutant vertebrate embryos.
The 20 matches
- [1] § Results › MIC-Drop-seq enables multiplexed embryo phenotyping ↔ Figure1_MIC-Drop-seq.Rmd, lines 907–958 · score 0.81 · hoxa9a, hoxb9a, hoxc6b, spinal cord, identified cdx4, clusters
- [2] § Methods › Dimensionality reduction, clustering and cell cluster labeling ↔ Figure1_MIC-Drop-seq.Rmd, lines 551–607 · score 0.81 · transfer anchors, 21–26, Predicted cell, reference atlas, Daniocell, hpf
- [3] § Methods › Determination of CRISPR editing frequency ↔ Figure1_MIC-Drop-seq.Rmd, lines 442–484 · score 0.80 · rhAmpSeq, cut site, editing frequency, Genomic DNA, indels, sequencing
- [4] § Results › MIC-Drop-seq reveals transcriptional and cellular phenotypes ↔ Figure3_MIC-Drop-seq.Rmd, lines 473–498 · score 0.78 · optic tectum, nkx2.7, gata2a, sox11b, dlx1a expression, hypothalamus
- [5] § Methods › Differential cell abundance analysis ↔ Figure2_MIC-Drop-seq.Rmd, lines 951–1019 · score 0.76 · Poisson Lognormal models, biological replicate, cell abundance, Monocle3, Hooke, genotype
- [6] § Methods › Statistics and reproducibility ↔ Figure4_MIC-Drop-seq.Rmd, lines 912–959 · score 0.75 · pairwise comparisons, post hoc, mRNA, Tukey, rescue, ANOVA
- [7] § Results › MIC-Drop-seq reveals transcriptional and cellular phenotypes ↔ Figure3_MIC-Drop-seq.Rmd, lines 473–498 · score 0.74 · optic tectum, nkx2.7, gata2a, sox11b, dlx1a expression, hypothalamus
- [8] § Methods › In situ imaging and quantification ↔ Figure3_MIC-Drop-seq.Rmd, lines 285–312 · score 0.71 · pixel area, dlx1a, gata2a, Stained, trunk, head
- [9] § Results › MIC-Drop-seq enables multiplexed embryo phenotyping ↔ Figure1_MIC-Drop-seq.Rmd, lines 442–484 · score 0.71 · cut sites, genomic DNA, editing frequency, genotypic composition, bulk, indel
- [10] § Methods › Dimensionality reduction, clustering and cell cluster labeling ↔ Figure1_MIC-Drop-seq.Rmd, lines 529–549 · score 0.71 · variable features, remove cells, dimensionality reduction, Seurat, doublets, gRNA
- [11] § Methods › Differential gene expression analysis ↔ Figure2_MIC-Drop-seq.Rmd, lines 664–749 · score 0.70 · edgeR, glmQLFit, aggregate, pseudobulk, FDR, gene expression
- [12] § Results › MIC-Drop-seq enables multiplexed embryo phenotyping ↔ Figure1_MIC-Drop-seq.Rmd, lines 698–727 · score 0.65 · presomitic mesoderm, tbx16 mutant, tbxta mutant, tyr, accumulation, depletion
- [13] § Results › MIC-Drop-seq detects indirect developmental effects ↔ Figure4_MIC-Drop-seq.Rmd, lines 912–959 · score 0.64 · post hoc, mRNA, way ANOVA, CVP, Tukey, outliers
- [14] § Methods › Gene expression matrix generation and genotype assignment ↔ Figure2_MIC-Drop-seq.Rmd, lines 159–241 · score 0.62 · gRNAs, multiple gene, mutant genotype, protospacer, doublet, detection
- [15] § Results › MIC-Drop-seq reveals transcriptional and cellular phenotypes ↔ Figure4_MIC-Drop-seq.Rmd, lines 169–292 · score 0.61 · presomitic mesoderm, optic tectum, myotome, sclerotome, dorsal, secreted
- [16] § Results › MIC-Drop-seq reveals transcriptional and cellular phenotypes ↔ Figure4_MIC-Drop-seq.Rmd, lines 169–292 · score 0.60 · optic tectum, hindbrain, neurons, ventral, MIC Drop seq, precursors
- [17] § Results › MIC-Drop-seq detects indirect developmental effects ↔ Figure4_MIC-Drop-seq.Rmd, lines 839–888 · score 0.59 · phenotype class, DEG thresholds, cell extrinsic, lineage, classification, seq
- [18] § Results › MIC-Drop-seq detects indirect developmental effects ↔ Figure4_MIC-Drop-seq.Rmd, lines 839–888 · score 0.58 · lineage intrinsic, cell intrinsic, cell extrinsic, threshold, DEGs, classified
- [19] § Methods › Determination of cell extrinsic and cell intrinsic effects ↔ Figure4_MIC-Drop-seq.Rmd, lines 635–666 · score 0.52 · cell intrinsic, cell extrinsic, threshold, lineage, classified
- [20] § Results › MIC-Drop-seq enables multiplexed embryo phenotyping ↔ Figure1_MIC-Drop-seq.Rmd, lines 698–727 · score 0.52 · hoxb1b, foxa2, hand2, tbx16, tyr, tbxta
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 · 1,137 lines · 37 KB · MIT · 7 matches
- ---
- title: "Figure 1: MIC-Drop-seq Proof-of-Concept Validation"
- author: "Clay Carey"
- date: "2024-05-08"
- output: html_document
- ---
- First- set your base directory to the folder with the downloaded 'input_data" folder. This contains all source data to run the code to reprodce figures.
- ```{r setup}
- # Set working directory for analysis- you MUST download the input dat aand set this directory manually for the code to work
- knitr::opts_knit$set(root.dir = "")
- ```
- # =============================================================================
- # SECTION 1: LOAD LIBRARIES
- # =============================================================================
- ```{r load-libraries, message=FALSE, warning=FALSE}
- # Core data manipulation
- library(Seurat)
- library(dplyr)
- library(tidyverse)
- library(stringr)
- # Single-cell analysis
- library(scCustomize)
- library(dittoSeq)
- library(scDblFinder)
- library(SingleCellExperiment)
- # Visualization
- library(ggplot2)
- library(ggridges)
- library(viridis)
- library(EnhancedVolcano)
- # Differential expression
- library(edgeR)
- library(presto)
- # Table formatting
- library(gtExtras)
- ```
- # =============================================================================
- # SECTION 2: LOAD AND PROCESS gRNA DATA
- # =============================================================================
- ## Load Cell Ranger CRISPR output
- Cell Ranger generates a "protospacer_calls_per_cell.csv" file that contains:
- - cell_barcode: 10X cell barcode
- - feature_call: pipe-delimited list of detected gRNA IDs
- - num_umis: pipe-delimited list of UMI counts per gRNA
- ```{r load-grna-data}
- # Load gRNA detection data from Cell Ranger
- pilot_CRISPR_data <- read.csv(file = "input_data/protospacer_calls_per_cell.csv")
- # Load experimental configuration (maps gRNA IDs to target genes)
- exp_config <- read.csv(file = "input_data/feature_reference.csv")
- head(pilot_CRISPR_data)
- head(exp_config)
- ```
- ## Parse gRNA detection data
- Cell Ranger stores multiple gRNAs per cell as pipe-delimited strings.
- We split these into separate columns for downstream classification.
- ```{r parse-grna-function}
- #' Process Cell Ranger CRISPR output
- #'
- #' Splits pipe-delimited feature_call and num_umis columns into
- #' separate columns (up to 20 features per cell)
- #'
- #' @param data Dataframe from Cell Ranger protospacer_calls_per_cell.csv
- #' @return Dataframe with feature_call_1:20 and num_umis_1:20 columns
- process_data <- function(data) {
- max_features <- 20
- feature_cols <- paste0("feature_call_", 1:max_features)
- # Split feature_call column (gRNA IDs)
- split_features <- strsplit(as.character(data$feature_call), "\\|")
- for (i in 1:max_features) {
- data[, feature_cols[i]] <- sapply(split_features, function(x) {
- if (length(x) >= i) return(x[i]) else return(0)
- })
- }
- # Split num_umis column (UMI counts)
- max_umis <- 20
- umis_cols <- paste0("num_umis_", 1:max_umis)
- split_umis <- strsplit(as.character(data$num_umis), "\\|")
- for (i in 1:max_umis) {
- data[, umis_cols[i]] <- sapply(split_umis, function(x) {
- if (length(x) >= i) return(x[i]) else return(0)
- })
- }
- return(data)
- }
- # Apply parsing function
- CRdata <- process_data(pilot_CRISPR_data)
- ```
- ## Classify cells by genotype
- For each cell, determine if gRNAs target a single gene or multiple genes.
- - Single gene → Assign that gene as genotype
- - Multiple genes → Classify as "Multiple" (doublet)
- - No gRNA → Will be classified as "ND" (Not Detected) later
- ```{r classify-genotypes}
- #' Classify cells by gRNA detection pattern
- #'
- #' Checks each cell across all feature_call columns and determines
- #' whether detected gRNAs target a single gene or multiple genes
- #'
- #' @param df Parsed CRISPR dataframe with feature_call_1:20 columns
- #' @param proto_ids Vector of gRNA IDs from experimental config
- #' @return Dataframe with 'class' column (gene name or "Multiple")
- classifier <- function(df, proto_ids) {
- # Create binary detection columns for each gRNA
- for (proto in proto_ids) {
- df <- df %>%
- mutate(!!paste0(proto, "_count") := case_when(
- feature_call_1 == proto ~ 1,
- feature_call_2 == proto ~ 1,
- feature_call_3 == proto ~ 1,
- feature_call_4 == proto ~ 1,
- feature_call_5 == proto ~ 1,
- feature_call_6 == proto ~ 1,
- feature_call_7 == proto ~ 1,
- feature_call_8 == proto ~ 1,
- feature_call_9 == proto ~ 1,
- feature_call_10 == proto ~ 1,
- feature_call_11 == proto ~ 1,
- feature_call_12 == proto ~ 1,
- feature_call_13 == proto ~ 1,
- feature_call_14 == proto ~ 1,
- feature_call_15 == proto ~ 1,
- feature_call_16 == proto ~ 1,
- feature_call_17 == proto ~ 1,
- feature_call_18 == proto ~ 1,
- feature_call_19 == proto ~ 1,
- feature_call_20 == proto ~ 1,
- TRUE ~ 0
- ))
- }
- # Extract detection counts and identify detected gRNAs per cell
- temp_df <- select(df, cell_barcode, ends_with("_count"))
- temp_df <- temp_df %>%
- pivot_longer(-cell_barcode) %>%
- filter(value == 1)
- # Summarize detected gRNAs per cell
- temp_df <- temp_df %>%
- group_by(cell_barcode) %>%
- summarise(class = paste(unique(name), collapse = ","))
- # Clean up gRNA names to gene names
- temp_df$all_protos <- temp_df$class
- temp_df$all_protos <- gsub("_count", "", temp_df$all_protos)
- temp_df$class <- gsub("-\\d+_count", "", temp_df$class)
- # Separate into columns to check for multiple targets
- temp_df <- separate(temp_df,
- class,
- into = c("count1", "count2", "count3", "count4", "count5"),
- sep = ",",
- extra = "merge")
- # Classify based on target gene consistency
- temp_df <- mutate(temp_df, class = case_when(
- is.na(count2) ~ count1,
- count1 == count2 & is.na(count3) ~ count1,
- count1 == count2 & count2 == count3 & is.na(count4) ~ count1,
- count1 == count2 & count2 == count3 & count3 == count4 & is.na(count5) ~ count1,
- TRUE ~ "Multiple" # Different genes detected = doublet
- ))
- # Merge back with original data
- temp_df <- select(temp_df, cell_barcode, all_protos, class)
- df <- left_join(df, temp_df, by = "cell_barcode")
- df <- select(df, cell_barcode, num_features, feature_call, num_umis, all_protos, class)
- return(df)
- }
- # Apply classification
- CRdata_classified <- classifier(CRdata, unique(exp_config$id))
- head(CRdata_classified)
- ```
- # =============================================================================
- # SECTION 3: CREATE SEURAT OBJECT AND ADD METADATA
- # =============================================================================
- ## Load 10X data
- Data contains two assays:
- 1. Gene Expression (RNA)
- 2. CRISPR Guide Capture (gRNA counts)
- ```{r load-10x-data}
- # Read both assays from Cell Ranger output
- tenx_data <- Read10X(data.dir = "input_data/micdrop_overload_matrix")
- tenx_data.gex <- tenx_data$`Gene Expression`
- tenx_data.crispr <- tenx_data$`CRISPR Guide Capture`
- # Create Seurat object with RNA assay
- mdp <- CreateSeuratObject(counts = tenx_data.gex, min.cells = 3)
- # Add CRISPR assay
- mdp[['CRISPR']] <- CreateAssayObject(counts = tenx_data.crispr)
- ```
- ## Merge gRNA classifications into Seurat metadata
- ```{r add-grna-metadata}
- # Extract metadata and add cell barcodes
- mdp_meta <- [email hidden]
- mdp_meta$cell_barcode <- rownames(mdp_meta)
- # Merge with gRNA classifications
- mdp_meta <- left_join(mdp_meta, CRdata_classified, by = "cell_barcode")
- rownames(mdp_meta) <- mdp_meta$cell_barcode
- # Add back to Seurat object
- [email hidden] <- mdp_meta
- # Clean up classifications
- [email hidden] <- [email hidden] %>%
- mutate(
- class = ifelse(is.na(class), "ND", class), # Cells without gRNA
- class = ifelse(class == "Non-Targeting", "tyr", class) # Rename control
- )
- table(mdp$class)
- ```
- # =============================================================================
- # SECTION 4: QUALITY CONTROL
- # =============================================================================
- ## Calculate QC metrics
- ```{r calculate-qc}
- # Calculate mitochondrial percentage
- mdp[["percent.mt"]] <- PercentageFeatureSet(mdp, pattern = "^mt-")
- # Visualize QC metrics
- DefaultAssay(mdp) <- "RNA"
- VlnPlot(mdp, features = c("percent.mt", "nCount_RNA", "nFeature_RNA"))
- ```
- ## Filter low-quality cells
- ```{r filter-cells}
- # Apply quality thresholds
- mdp <- subset(mdp, subset = nFeature_RNA > 200 &
- nFeature_RNA < 9000 &
- percent.mt < 15)
- cat("Cells after filtering:", ncol(mdp), "\n")
- ```
- # =============================================================================
- # SECTION 5: FIGURE 1B - gRNA UMI DISTRIBUTION
- # =============================================================================
- Distribution of gRNA UMI counts in cells with detected gRNAs
- ```{r figure1B, fig.width=2, fig.height=2}
- mdp_meta <- [email hidden]
- mdp_meta %>%
- filter(class != "ND") %>%
- ggplot(aes(x = nCount_CRISPR)) +
- geom_histogram(binwidth = 1, fill = "black") +
- scale_x_continuous(limits = c(0, 75)) +
- theme_classic() +
- theme(
- text = element_text(family = "Helvetica", size = 12, color = "black"),
- axis.text = element_text(size = 12, color = "black", family = "Helvetica"),
- axis.title = element_text(size = 12)
- ) +
- xlab("gRNA UMIs") +
- ylab("Cell Count")
- ggsave(filename = "outputs_fig1/Figure_1B.eps",
- device = "ps",
- width = 2, height = 2, units = 'in',
- bg = "transparent")
- ```
- # =============================================================================
- # SECTION 6: FIGURE 1C - gRNA TARGET DISTRIBUTION
- # =============================================================================
- Cells classified by number of gene targets detected
- - 0: No gRNA detected
- - 1: Single gene target (expected for MIC-Drop)
- - 2+: Multiple gene targets (doublets)
- ```{r figure1C, fig.width=1.5, fig.height=2}
- # Categorize cells by number of targets
- mdp_meta <- [email hidden] %>%
- mutate(type = case_when(
- class == "ND" ~ "0",
- class == "Multiple" ~ "2+",
- TRUE ~ "1"
- ))
- # Plot distribution
- mdp_meta %>%
- dplyr::count(type) %>%
- ggplot() +
- geom_bar(aes(x = type, y = n / 1000), stat = "identity", fill = "black") +
- theme_classic() +
- xlab("gRNA targets") +
- ylab("Cells (thousands)") +
- scale_y_continuous(labels = scales::comma) +
- theme(
- axis.text = element_text(size = 12, family = "Helvetica", color = "black"),
- axis.title = element_text(size = 12, family = "Helvetica")
- )
- ggsave(filename = "outputs_fig1/Figure_1C.eps",
- device = "ps",
- width = 1.5, height = 2, units = 'in',
- bg = "transparent")
- ```
- # =============================================================================
- # SECTION 7: DOUBLET DETECTION WITH scDblFinder
- # =============================================================================
- Use computational doublet detection to validate that cells with
- multiple gRNA targets are enriched for doublets
- ```{r doublet-detection}
- # Prepare for scDblFinder (requires matching order)
- correctorder <- dimnames(mdp@assays$RNA$counts)[[2]]
- mdp <- mdp[, correctorder]
- [email hidden] <- [email hidden][match(correctorder, rownames([email hidden])), ]
- # Normalize and scale for doublet detection
- mdp <- NormalizeData(mdp)
- mdp <- ScaleData(mdp)
- # Convert to SingleCellExperiment and run scDblFinder
- mdp_sce <- as.SingleCellExperiment(mdp)
- mdp_sce <- scDblFinder(mdp_sce)
- mdp_sce <- as.Seurat(mdp_sce)
- # Extract doublet information
- dub_info <- data.frame([email hidden]) %>%
- select(scDblFinder.class, scDblFinder.score,
- scDblFinder.weighted, scDblFinder.cxds_score, class) %>%
- mutate(type = case_when(
- class == "Multiple" ~ "2+",
- TRUE ~ "0-1"
- ))
- ```
- ## Figure S2A: Doublet score distribution
- Cells with multiple gRNA targets show higher doublet scores
- ```{r figureS2A, fig.width=4, fig.height=3}
- ggplot(dub_info, aes(x = scDblFinder.weighted, fill = type)) +
- geom_density(alpha = 0.8, position = "identity", color = NA) +
- scale_fill_manual(values = c("0-1" = "black", "2+" = "grey")) +
- xlab("scDblFinder Doublet Score") +
- ylab("Density") +
- theme_classic() +
- guides(fill = guide_legend(title = "gRNA targets")) +
- theme(
- axis.text = element_text(size = 12, family = "Helvetica", color = "black"),
- axis.title = element_text(size = 12, family = "Helvetica"),
- legend.text = element_text(size = 12, family = "Helvetica")
- )
- ggsave(filename = "outputs_fig1/Figure_S2A.eps",
- device = "ps",
- width = 4, height = 3, units = 'in',
- bg = "transparent")
- ```
- ## Figure S2B: Doublet classification by gRNA pattern
- ```{r figureS2B, fig.width=3.5, fig.height=3}
- # Calculate doublet proportions
- class_freq <- dub_info %>%
- select(type, scDblFinder.class) %>%
- group_by(type) %>%
- dplyr::count(scDblFinder.class) %>%
- left_join(
- dub_info %>%
- select(type, scDblFinder.class) %>%
- group_by(type) %>%
- dplyr::count(scDblFinder.class) %>%
- summarize(tot = sum(n)),
- by = "type"
- ) %>%
- mutate(pct = n / tot)
- # Plot proportions
- ggplot(class_freq, aes(x = type, fill = scDblFinder.class, y = pct)) +
- scale_fill_manual(values = c("singlet" = "black", "doublet" = "grey")) +
- geom_bar(position = "stack", stat = "identity") +
- theme_classic() +
- theme(
- axis.text = element_text(size = 12, family = "Helvetica", color = "black"),
- axis.title = element_text(size = 12, family = "Helvetica"),
- legend.text = element_text(size = 12, family = "Helvetica")
- ) +
- guides(fill = guide_legend(title = "scDblFinder Class")) +
- ylab("Proportion of Cells") +
- xlab("gRNA targets recovered") +
- labs(fill = "")
- ggsave(filename = "outputs_fig1/Figure_S2B.eps",
- device = "ps",
- width = 3.5, height = 3, units = 'in',
- bg = "transparent")
- ```
- # =============================================================================
- # SECTION 8: FIGURE 1E - MUTAGENESIS EFFICIENCY
- # =============================================================================
- Compare CRISPR editing frequency (from genomic DNA) to
- genotype composition (from gRNA detection)
- ```{r load-rhampseq-data}
- # Load rhAmpSeq results (bulk DNA sequencing of cut sites)
- rhamp <- read.csv(file = "input_data/rhamp_results.csv")
- # Extract gene names from target column
- rhamp <- mutate(rhamp, class = case_when(
- str_detect(target, "^cdx4") ~ "cdx4",
- str_detect(target, "^rx3") ~ "rx3",
- str_detect(target, "^tbx16") ~ "tbx16",
- str_detect(target, "^tbxta") ~ "tbxta",
- str_detect(target, "^hand2") ~ "hand2",
- str_detect(target, "^hoxb1b") ~ "hoxb1b",
- str_detect(target, "^foxa2") ~ "foxa2",
- str_detect(target, "^tyr") ~ "tyr",
- TRUE ~ "Other"
- ))
- # Calculate percentage of cells with each genotype
- cellfreq <- data.frame(table(mdp$class)) %>%
- filter(Var1 != "ND", Var1 != "Multiple") %>%
- mutate(pct = (Freq / sum(Freq)) * 100) %>%
- select(Var1, pct)
- names(cellfreq) <- c("class", "cell_pct")
- cellfreq$class <- gsub("Non-Targeting", "tyr", cellfreq$class)
- # Merge with rhAmpSeq data, keep highest edited site per gene
- rhamp <- rhamp %>%
- left_join(cellfreq, by = "class") %>%
- select(class, target, pct_indel, wt_indel, cell_pct) %>%
- group_by(class) %>%
- filter(pct_indel == max(pct_indel)) %>%
- ungroup() %>%
- mutate(class = factor(class, levels = c("hoxb1b", "rx3", "cdx4", "hand2",
- "tbx16", "tbxta", "foxa2", "tyr")))
- ```
- ```{r figure1E, fig.width=2.5, fig.height=3}
- # Normalize indel rate by subtracting background
- rhamp_normalized <- rhamp %>%
- mutate(indel_normalized = pct_indel - wt_indel)
- # Dumbbell plot comparing DNA editing to gRNA detection
- ggplot(rhamp_normalized) +
- geom_segment(aes(x = class, xend = class,
- y = indel_normalized, yend = cell_pct),
- color = "grey") +
- geom_point(aes(x = class, y = indel_normalized,
- color = factor("% DNA with indel",
- levels = c("% DNA with indel", "% Cells with gRNA"))),
- size = 3) +
- geom_point(aes(x = class, y = cell_pct,
- color = factor("% Cells with gRNA",
- levels = c("% DNA with indel", "% Cells with gRNA"))),
- size = 3) +
- scale_color_manual(values = c("black", "#888888")) +
- coord_flip() +
- scale_y_continuous(limits = c(0, 17), breaks = c(0, 5, 10, 15)) +
- theme_classic() +
- theme(
- text = element_text(family = "Helvetica"),
- axis.text.x = element_text(size = 12),
- axis.text.y = element_text(size = 12, face = "italic", color = "black"),
- axis.title = element_text(size = 12),
- legend.text = element_text(size = 12),
- legend.title = element_blank(),
- legend.position = c(0.4, -0.25),
- plot.margin = margin(b = 70),
- legend.background = element_rect(fill = alpha("white", 0))
- ) +
- xlab("") +
- ylab(element_blank()) +
- guides(color = guide_legend(title = "", ncol = 1))
- ggsave(filename = "outputs_fig1/Figure_1E.eps",
- device = "ps",
- width = 2.5, height = 3, units = 'in',
- bg = "transparent")
- ```
- # =============================================================================
- # SECTION 9: DIMENSIONALITY REDUCTION AND CLUSTERING
- # =============================================================================
- Remove doublets and perform standard Seurat workflow
- ```{r clustering}
- # Remove cells with multiple gRNA targets (doublets)
- mdp_filt <- subset(mdp, subset = class != "Multiple")
- # Standard Seurat workflow
- mdp_filt <- NormalizeData(mdp_filt)
- mdp_filt <- FindVariableFeatures(mdp_filt, selection.method = "vst", nfeatures = 2000)
- mdp_filt <- ScaleData(mdp_filt)
- mdp_filt <- RunPCA(mdp_filt, features = VariableFeatures(object = mdp_filt))
- mdp_filt <- FindNeighbors(mdp_filt, dims = 1:30)
- mdp_filt <- FindClusters(mdp_filt, resolution = 0.5)
- mdp_filt <- RunUMAP(mdp_filt, dims = 1:30, min.dist = 0.4)
- DimPlot(mdp_filt)
- ```
- # =============================================================================
- # SECTION 10: CELL TYPE ANNOTATION VIA LABEL TRANSFER
- # =============================================================================
- Use Daniocell reference atlas to annotate cell types
- ```{r label-transfer}
- # Load Daniocell reference (21-26 hpf timepoints)
- dcell_ref <- readRDS(file = "input_data/dcell_21_26.rds")
- # Prepare reference
- dcell_ref <- RunPCA(dcell_ref, dims = 1:30)
- dcell_ref <- RunUMAP(dcell_ref, dims = 1:30, return.model = TRUE)
- # Separate cell type hierarchy into columns
- [email hidden] <- separate([email hidden],
- full_ident,
- into = c("tissue", "cell_type", "sub_type"),
- sep = "[|>]",
- remove = FALSE)
- # Find transfer anchors and transfer labels
- xfer_anchors <- FindTransferAnchors(
- reference = dcell_ref,
- query = mdp_filt,
- dims = 1:30,
- reference.assay = "RNA",
- query.assay = "RNA",
- reference.reduction = "pca"
- )
- predictions <- TransferData(
- anchorset = xfer_anchors,
- refdata = dcell_ref$full_ident,
- dims = 1:30
- )
- # Add predictions to query
- mdp_filt <- AddMetaData(mdp_filt, metadata = predictions)
- # Map query to reference UMAP
- mdp_filt <- MapQuery(
- anchorset = xfer_anchors,
- reference = dcell_ref,
- query = mdp_filt,
- refdata = "full_ident",
- reference.reduction = "pca",
- reduction.model = "umap"
- )
- # Separate predicted cell type hierarchy
- [email hidden] <- separate([email hidden],
- predicted.id,
- into = c("tissue", "cell_type", "sub_type"),
- sep = "[|>]",
- remove = FALSE)
- ```
- ## Figure S4: Label transfer validation
- ```{r figureS4A, fig.width=4, fig.height=4}
- # S4A: Reference atlas tissue types
- p1 <- DimPlot(dcell_ref, group.by = "tissue", label = FALSE, reduction = 'umap')
- LabelClusters(p1, id = "tissue", repel = TRUE) +
- NoLegend() + NoAxes() +
- ggtitle("Daniocell reference tissue types") +
- theme(plot.title = element_text(size = 12, family = "Helvetica"))
- ggsave(filename = "outputs_fig1/Figure_S4A.eps",
- device = "ps",
- width = 4, height = 4, units = 'in',
- bg = "transparent")
- ```
- ```{r figureS4B, fig.width=4, fig.height=4}
- # S4B: Query cells projected to reference
- DimPlot(mdp_filt, group.by = "tissue", label = FALSE, reduction = 'ref.umap') +
- NoLegend() + NoAxes() +
- ggtitle("MIC-Drop-seq cells projected to reference") +
- theme(plot.title = element_text(size = 12, family = "Helvetica"))
- ggsave(filename = "outputs_fig1/Figure_S4B.eps",
- device = "ps",
- width = 4, height = 4, units = 'in',
- bg = "transparent")
- ```
- ## Assign consensus cell types to clusters
- Take the most frequent predicted cell type for each cluster
- ```{r consensus-labels}
- consensus_assignments <- [email hidden] %>%
- group_by(seurat_clusters) %>%
- dplyr::count(predicted.id) %>%
- top_n(n = 1, wt = n) %>%
- select(seurat_clusters, predicted.id) %>%
- separate(predicted.id,
- into = c("consensus_tissue", "consensus_cell_type", "consensus_sub_type"),
- sep = "[|>]",
- remove = FALSE) %>%
- dplyr::rename("consensus_predicted.id" = "predicted.id")
- # Merge back with metadata
- [email hidden] <- [email hidden] %>%
- left_join(consensus_assignments, by = "seurat_clusters")
- rownames([email hidden]) <- [email hidden]$cell_barcode
- ```
- ```{r figureS4C, fig.width=4, fig.height=4}
- # S4C: Consensus tissue labels
- p1 <- DimPlot(mdp_filt, group.by = "consensus_tissue", label = FALSE)
- LabelClusters(p1, id = "consensus_tissue", repel = TRUE, size = 4) +
- NoLegend() + NoAxes() +
- ggtitle("MIC-Drop-seq consensus tissue labels") +
- theme(plot.title = element_text(size = 12, family = "Helvetica"))
- ggsave(filename = "outputs_fig1/Figure_S4C.eps",
- device = "ps",
- width = 4, height = 4, units = 'in',
- bg = "transparent")
- ```
- ## Figure 1D: Cluster UMAP
- ```{r figure1D, fig.width=5, fig.height=5}
- # Custom color palette for 35 clusters
- palette <- c('#AADAEEFF', '#FCDACAFF', '#DCD4E6FF', '#92C8E0FF', '#FFBDF2FF',
- '#7BB6D3FF', '#64A4C5FF', '#C4DFB6FF', '#FCE4A6FF', '#EC85D8FF',
- '#ACCF9FFF', '#EBC576FF', '#F0ABAEFF', '#458DB3FF', '#D69E3BFF',
- '#AF7623FF', '#95C089FF', '#2675A1FF', '#1A6088FF', '#D35C61FF',
- '#7EB173FF', '#619F57FF', '#9A70ABFF', '#545454FF', '#8B1713FF',
- '#104B6FFF', '#428B39FF', '#D747BBFF', '#B90497FF', '#44236EFF',
- '#277822FF', '#1D6623FF', '#7C000CFF', '#770262FF', '#135524FF')
- p1 <- DimPlot(mdp_filt, cols = palette, group.by = 'seurat_clusters') +
- NoLegend() + NoAxes() + ggtitle("")
- LabelClusters(p1, id = "seurat_clusters", bg.color = "white")
- ggsave(filename = "outputs_fig1/Figure_1D.eps",
- device = "ps",
- width = 5, height = 5, units = 'in',
- bg = "transparent")
- ```
- # =============================================================================
- # SECTION 11: PHENOTYPE VALIDATION
- # =============================================================================
- ## Presomitic Mesoderm (tbx16, tbxta)
- Known phenotypes:
- - tbx16 mutants: Accumulation of presomitic mesoderm
- - tbxta mutants: Depletion of presomitic mesoderm
- ```{r presomitic-mesoderm}
- # Add presomitic mesoderm annotation
- [email hidden] <- mutate([email hidden], psm = case_when(
- seurat_clusters == 15 ~ "Presomitic Mesoderm",
- TRUE ~ "Other"
- ))
- # Calculate percentage of cells per genotype in PSM
- psmstats <- data.frame(table(mdp_filt$psm, mdp_filt$class))
- totals <- psmstats %>% group_by(Var2) %>% summarise(total = sum(Freq))
- psmstats <- left_join(psmstats, totals, by = "Var2") %>%
- mutate(pct = (Freq / total) * 100) %>%
- filter(Var1 == "Presomitic Mesoderm", Var2 != "ND", Var2 != "Multiple")
- psmstats$Var2 <- gsub("Non-Targeting", "tyr", psmstats$Var2)
- psmstats$Var2 <- factor(psmstats$Var2,
- levels = c("cdx4", "foxa2", "hand2", "hoxb1b",
- "rx3", "tbx16", "tbxta", "tyr"))
- ```
- ### Figure 1F: PSM UMAP split by genotype
- ```{r figure1F, fig.width=8, fig.height=1.5}
- Idents(mdp_filt) <- "seurat_clusters"
- PSM <- subset(mdp_filt, idents = "15")
- [email hidden] <- mutate([email hidden], psmplot = case_when(
- class == "tbx16" ~ "tbx16",
- class == "tyr" ~ "tyr",
- class == "tbxta" ~ "tbxta",
- TRUE ~ "Other"
- ))
- dittoDimPlot(PSM, "psmplot", split.by = "psmplot",
- color.panel = c("#000000", "black", "black", "black"),
- size = 0.5, split.nrow = 1) +
- NoAxes() + NoLegend() +
- coord_cartesian(xlim = c(-14, -9), ylim = c(-1, 2.5)) +
- theme(strip.text = element_text(size = 12, face = "italic", family = "Helvetica"),
- strip.background = element_rect(fill = "white")) +
- ggtitle("")
- ggsave(filename = "outputs_fig1/Figure_1F.eps",
- device = "ps",
- width = 8, height = 1.5, units = 'in',
- bg = "transparent")
- ```
- ### Figure 1G: PSM percentage barplot
- ```{r figure1G, fig.width=3, fig.height=2}
- ggplot(data = psmstats, aes(x = Var2, y = pct)) +
- geom_bar(stat = "identity", fill = "black") +
- theme_classic() +
- ylab("% cells in cluster") +
- xlab("Mutation") +
- theme(
- axis.text.x = element_text(size = 12, family = "Helvetica",
- color = "black", face = "italic",
- angle = 45, hjust = 1),
- axis.text.y = element_text(size = 12, family = "Helvetica", color = "black"),
- axis.title = element_text(size = 12, family = "Helvetica")
- )
- ggsave(filename = "outputs_fig1/Figure_1G.eps",
- device = "ps",
- width = 3, height = 2, units = 'in',
- bg = "transparent")
- ```
- ## Optic Primordia (rx3)
- Known phenotype: rx3 mutants lack eyes (depletion of retinal cells)
- ```{r optic-primordia}
- # Add optic primordia annotation
- [email hidden] <- mutate([email hidden], eye = case_when(
- seurat_clusters %in% c(2, 22) ~ "Optic Primordia",
- TRUE ~ "Other"
- ))
- # Calculate percentage of cells per genotype in optic primordia
- eyestats <- data.frame(table(mdp_filt$eye, mdp_filt$class))
- totals <- eyestats %>% group_by(Var2) %>% summarise(total = sum(Freq))
- eyestats <- left_join(eyestats, totals, by = "Var2") %>%
- mutate(pct = (Freq / total) * 100) %>%
- filter(Var1 == "Optic Primordia", Var2 != "ND", Var2 != "Multiple")
- eyestats$Var2 <- gsub("Non-Targeting", "tyr", eyestats$Var2)
- eyestats$Var2 <- factor(eyestats$Var2,
- levels = c("cdx4", "foxa2", "hand2", "hoxb1b",
- "rx3", "tbx16", "tbxta", "tyr"))
- ```
- ### Figure S5A: Optic primordia UMAP
- ```{r figureS5A, fig.width=6, fig.height=1.5}
- optic <- subset(mdp_filt, idents = c(2, 22))
- [email hidden] <- mutate([email hidden], opticplot = case_when(
- class == "rx3" ~ "rx3",
- class == "tyr" ~ "tyr",
- TRUE ~ "Other"
- ))
- dittoDimPlot(optic, "opticplot", split.by = "opticplot",
- color.panel = c("#000000", "black", "black", "black"),
- size = 0.5, split.nrow = 1) +
- NoAxes() + NoLegend() +
- coord_cartesian(xlim = c(2, 11), ylim = c(-7, -2)) +
- theme(strip.text = element_text(size = 12, face = "italic", family = "Helvetica"),
- strip.background = element_rect(fill = "white")) +
- ggtitle("")
- ggsave(filename = "outputs_fig1/Figure_S5A.eps",
- device = "ps",
- width = 6, height = 1.5, units = 'in',
- bg = "transparent")
- ```
- ### Figure S5B: Optic primordia percentage
- ```{r figureS5B, fig.width=3, fig.height=2}
- ggplot(data = eyestats, aes(x = Var2, y = pct)) +
- geom_bar(stat = "identity", fill = 'black') +
- theme_classic() +
- ylab("% cells in cluster") +
- xlab("Mutation") +
- theme(
- axis.text.x = element_text(size = 12, family = "Helvetica",
- color = "black", face = "italic",
- angle = 45, hjust = 1),
- axis.text.y = element_text(size = 12, family = "Helvetica", color = "black"),
- axis.title = element_text(size = 12, family = "Helvetica")
- )
- ggsave(filename = "outputs_fig1/Figure_S5B.eps",
- device = "ps",
- width = 3, height = 2, units = 'in',
- bg = "transparent")
- ```
- ## Spinal Cord (cdx4)
- Known phenotype: cdx4 regulates hox gene expression in spinal cord
- ```{r spinal-cord-deg}
- # Add cdx4 classification
- [email hidden] <- [email hidden] %>%
- mutate(cdx = ifelse(class == "cdx4", "cdx4", "other"))
- ```
- ### Figure 1H: Spinal cord UMAP
- ```{r figure1H, fig.width=3, fig.height=1.5}
- Idents(mdp_filt) <- "consensus_cell_type"
- sc <- subset(mdp_filt, idents = "spinal cord")
- [email hidden] <- mutate([email hidden], cdx = ifelse(class == "cdx4", "cdx4", "other"))
- dittoDimPlot(sc, "cdx", split.by = "cdx",
- color.panel = c("#000000", "black"),
- size = 0.5, split.nrow = 1) +
- NoAxes() + NoLegend() +
- coord_cartesian(xlim = c(-5, 0), ylim = c(-5, 2)) +
- theme(strip.text = element_text(size = 12, face = c("italic", "plain"), family = "Helvetica"),
- strip.background = element_rect(fill = "white")) +
- ggtitle("")
- ggsave(filename = "outputs_fig1/Figure_1H.eps",
- device = "ps",
- width = 3, height = 1.5, units = 'in',
- bg = "transparent")
- ```
- ### Figure 1I: Hox gene expression in spinal cord
- ```{r figure1I, fig.width=3, fig.height=2.5}
- Idents(mdp_filt) <- "consensus_tissue"
- VlnPlot(mdp_filt,
- group.by = "cdx",
- features = c('elavl3', 'hoxb9a', 'hoxc6b', 'hoxa9a'),
- idents = "spinal cord",
- stack = TRUE,
- flip = TRUE,
- cols = rep("darkgrey", 5)) +
- NoLegend() +
- scale_x_discrete(labels = c(expression(italic(cdx4), "other"))) +
- xlab("Mutation")
- ggsave(filename = "outputs_fig1/Figure_1I.eps",
- device = "ps",
- width = 3, height = 2.5, units = 'in',
- bg = "transparent")
- ```
- ### Figure S5C: cdx4 volcano plot
- ```{r figureS5C, fig.width=3, fig.height=3}
- # Identify cdx4 and control cells in spinal cord clusters
- cdx_spinal_cells <- [email hidden] %>%
- filter(seurat_clusters %in% c(4, 28), class == 'cdx4') %>%
- pull(cell_barcode)
- control_cells <- [email hidden] %>%
- filter(seurat_clusters %in% c(4, 28), class != "cdx4") %>%
- pull(cell_barcode)
- # Find differentially expressed genes
- cdx_deg <- FindMarkers(mdp_filt,
- ident.1 = cdx_spinal_cells,
- ident.2 = control_cells)
- # Prepare for plotting
- genes_of_interest <- c("hoxb9a", "hoxa9a", "hoxc6b")
- cdx_deg <- cdx_deg %>%
- rownames_to_column("gene") %>%
- mutate(
- is_highlight = gene %in% genes_of_interest,
- log_p = -log10(p_val_adj)
- )
- highlight_subset <- cdx_deg %>% filter(is_highlight)
- # Volcano plot
- ggplot(cdx_deg, aes(x = avg_log2FC, y = log_p)) +
- geom_point(color = "grey70", alpha = 0.6, size = 1.5) +
- geom_point(data = highlight_subset, color = "black", size = 3) +
- geom_label_repel(data = highlight_subset,
- aes(label = gene),
- fontface = "italic",
- force = 2) +
- theme_classic() +
- labs(
- title = expression(italic("cdx4") ~ "- Spinal Cord DEGs"),
- x = "Average Log2 Fold Change",
- y = "-Log10 Adjusted P-value"
- ) +
- geom_vline(xintercept = c(-1, 1), linetype = "dashed", color = "grey50") +
- geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "grey50") +
- theme(plot.title = element_text(hjust = 0.5))
- ggsave(filename = "outputs_fig1/Figure_S5C.eps",
- device = "ps",
- width = 3, height = 3, units = 'in',
- bg = "transparent")
- ```
- # =============================================================================
- # SECTION 12: SUPPLEMENTARY FIGURES
- # =============================================================================
- ## Figure S3A: Cells per genotype
- ```{r figureS3A, fig.width=4, fig.height=3}
- [email hidden] <- [email hidden] %>%
- mutate(class = factor(class,
- levels = c("hoxb1b", "rx3", "cdx4", "hand2",
- "tbx16", "tbxta", "foxa2", "tyr", "ND")))
- [email hidden] %>%
- dplyr::count(class) %>%
- ggplot(aes(x = class, y = n)) +
- geom_bar(stat = "identity", fill = "black") +
- theme_classic() +
- labs(y = "Assigned Cells", x = "Genotype") +
- scale_y_continuous(breaks = seq(0, 9000, by = 1000)) +
- theme(
- axis.title = element_text(size = 12, family = "Helvetica"),
- axis.text.y = element_text(size = 12, family = "Helvetica"),
- axis.text.x = element_text(angle = 45, hjust = 1, size = 12,
- face = c(rep("italic", 8), 'plain'),
- family = "Helvetica")
- )
- ggsave(filename = "outputs_fig1/Figure_S3A.eps",
- device = "ps",
- width = 4, height = 3, units = 'in',
- bg = "transparent")
- ```
- ## Figure S3B: UMAP split by genotype
- ```{r figureS3B, fig.width=6, fig.height=6}
- dittoDimPlot(mdp_filt, "class", split.by = "class") +
- NoLegend() + NoAxes() +
- theme(strip.text = element_text(size = 12,
- face = c(rep("italic", 8), "plain"),
- family = "Helvetica")) +
- ggtitle("")
- ggsave(filename = "outputs_fig1/Figure_S3B.eps",
- device = "ps",
- width = 6, height = 6, units = 'in',
- bg = "transparent")
- ```
- Figure S3D
- ```{r}
- #read amplican results
- amp_res <- read.csv(file = "input_data/amplican_results_summary.csv")
- amp_res_normalized <- amp_res %>%
- #calculate the percentage of reads frameshifted
- mutate(frameshift_pct = Reads_Frameshifted / Reads_Filtered * 100) %>%
- #calculate the proportion of frameshifted reads relative to the percentage of cells assigned the genotype
- mutate(non_frameshift_pr_normalized = 1 - (frameshift_pct / Cell_pct),
- frameshift_pr_normalized = (frameshift_pct / Cell_pct))
- cumul_frameshift <- amp_res_normalized %>%
- #Now we can group the rows by mutation, and then we summarize to a new column to show the cumulative frameshift efficiency
- group_by(Group) %>%
- summarise(cumulative_frameshift_efficiency = 1 - prod(non_frameshift_pr_normalized) )
- amp_results_final <- amp_res_normalized %>%
- left_join(cumul_frameshift, by = "Group") %>%
- mutate(Group = gsub("Non-Targeting","tyr",.$Group))
- amp_results_plot_data <- amp_results_final %>%
- #select only relevant columns
- dplyr::select(ID, Group, frameshift_pr_normalized, cumulative_frameshift_efficiency ) %>%
- pivot_longer(names_to = "name", cols = -c(Group, ID))
- p1 <- ggplot(amp_results_plot_data, aes(x = value, y = Group, color = name)) +
- geom_point(size = 3) +
- scale_x_continuous(limits = c(0,1)) +
- scale_color_manual(
- values = c("dodgerblue", "darkgrey"),
- labels = c("Cumulative Frameshift Probability", "Individual Guide Frameshift Frequency")
- ) +
- labs(
- x = "Normalized Frameshift Frequency",
- y = "Target Gene",
- color = "" # Blank legend title
- ) +
- theme_minimal() +
- theme(
- text = element_text(size = 12),
- axis.text = element_text(size = 12), # Axis numbers/labels
- axis.title = element_text(size = 12), # Axis titles
- legend.text = element_text(size = 12), # Legend text
- plot.title = element_text(size = 12), # Plot title (if you add one)
- panel.border = element_rect(color = "black", fill = NA, linewidth = 0.5),
- legend.position = "bottom",
- legend.direction = "vertical"
- )
- p1
- ggsave(filename = "outputs_fig1/Figure_S3D.eps",
- device = "ps",
- width = 3, height = 3, units = 'in',
- bg = "transparent")
- ```
- Figure S1C plot
- ```{r}
- # Load libraries
- library(ggplot2)
- library(dplyr)
- # 1. Data Setup (based on your table)
- data <- data.frame(
- gRNA = rep(c("Unmodified gRNA", "Modified gRNA"), each = 6),
- phenotype = rep(c("Full", "Full", "Partial", "Partial", "WT", "WT"), 2),
- replicate = rep(c(1, 2), 6),
- percentage = c(88, 94.7, 12, 5.3, 0, 0, # Unmodified
- 90.4, 94.1, 9.6, 5.9, 0, 0) # Modified
- )
- # 2. Data Processing
- # Set 'Full' as the base layer
- data$phenotype <- factor(data$phenotype, levels = c("Full", "Partial", "WT"))
- # Calculate means for the bars
- bar_data <- data %>%
- group_by(gRNA, phenotype) %>%
- summarize(mean_perc = mean(percentage), .groups = 'drop')
- # Filter dots to show ONLY the 'Full' phenotype variance
- dot_data <- data %>%
- filter(phenotype == "Full")
- # 3. Create the Plot
- p1 <- ggplot() +
- # Bars: Show the average composition
- geom_col(data = bar_data, aes(x = gRNA, y = mean_perc, fill = phenotype),
- color = "black", width = 0.6, position = position_stack(reverse = TRUE)) +
- # Dots: Show individual variance for the 'Full' phenotype only
- geom_point(data = dot_data,
- aes(x = gRNA, y = percentage),
- shape = 21,
- fill = "black", # White fill makes dots pop against black bars
- color = "white",
- size = 3.5,
- stroke = 1,
- position = position_dodge(width = 0.4),
- show.legend = FALSE) +
- # Aesthetics and Styling
- scale_fill_manual(values = c("Full" = "black",
- "Partial" = "grey70",
- "WT" = "white")) +
- scale_y_continuous(limits = c(0, 105), expand = c(0, 0), breaks = seq(0, 100, 20)) +
- labs(y = "% embryos with phenotype", x = NULL, fill = NULL) +
- theme_classic() +
- theme(
- axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1, size = 12, color = "black"),
- axis.text.y = element_text(size = 12, color = "black"),
- legend.position = "right"
- )
- p1
- ggsave(filename = "outputs_fig1/Figure_S1C.eps",
- device = "ps",
- width = 3, height = 4, units = 'in',
- bg = "transparent")
- ```
Figure1_MIC-Drop-seq.Rmd at commit 9de3c19, under MIT · at the source
Overview
- School of Biological Sciences, University of Utah,Salt Lake City, UT USA
- Department of Pharmacology and Toxicology, College of Pharmacy, University of Utah,Salt Lake City, UT USA
- Department of Cell & Developmental Biology, Feinberg School of Medicine, Northwestern University,Chicago, IL USA
- Henry Eyring Center for Cell & Genome Science, University of Utah,Salt Lake City, UT USA
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.
Repositories
Its files are read in the Code ↔ Paper reader above, with 20 matches between paragraphs and lines of code.
clay-carey/MIC-Drop-seq
9de3c197ea1f6a13758e52b6d2b419ceb3cb0582, 11 February 2026Availability: 1 check, the latest on 28 September 2026: the link answers
- 28 September 2026: the link answers
6 files
- Figure1_MIC-Drop-seq.Rmd
, R, 1,137 lines, 7 matches - Figure2_MIC-Drop-seq.Rmd
, R, 1,231 lines, 3 matches - Figure3_MIC-Drop-seq.Rmd
, R, 776 lines, 3 matches - Figure4_MIC-Drop-seq.Rmd
, R, 1,135 lines, 7 matches - LICENSE, License, 21 lines
- README.md, Text, 168 lines
Zenodo 18615355
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
- 28 September 2026: the link answers (HTTP 200)
6 files
- Figure1_MIC-Drop-seq.Rmd
, R, 1,137 lines - Figure2_MIC-Drop-seq.Rmd
, R, 1,231 lines - Figure3_MIC-Drop-seq.Rmd
, R, 776 lines - Figure4_MIC-Drop-seq.Rmd
, R, 1,135 lines - LICENSE, License, 21 lines
- README.md, Text, 168 lines
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:
- it points to the authors' code: clay-carey/
MIC-Drop-seq , Zenodo 18615355
Read it in the paper: doi.org/10.1038/s41467-026-70989-w.
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:
- 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 8 scripts, each with its path and the digest of its content;
- 20 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
- geo:GSE315445, at NCBI GEO; found in “Data availability”
- zenodo:18602858, at Zenodo; found in “Data availability”
Code and data availability statement
The paper has a code and data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:
- it points to 2 datasets: NCBI GEO GSE315445, Zenodo 18602858
- it points to the authors' code: clay-carey/
MIC-Drop-seq , Zenodo 18615355
Read it in the paper: doi.org/10.1038/s41467-026-70989-w.
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, 28 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 7 authors, 4 keywords, 14 MeSH terms, 1 funder, 64 references.
Cite
This paper
Carey, C. M., Parvez, S., Brandt, Z. J., Bisgrove, B. W., Yates, C. J., Peterson, R. T., & Gagnon, J. A. (2026). MIC-Drop-seq: scalable single-cell phenotyping of mutant vertebrate embryos. Nature communications, 17(1), 4738. https://
BibTeX
@article{carey2026mic,
author = {Carey, Clayton M. and Parvez, Saba and Brandt, Zachary J. and Bisgrove, Brent W. and Yates, Christopher J. and Peterson, Randall T. and Gagnon, James A.},
title = {{MIC-Drop-seq: scalable single-cell phenotyping of mutant vertebrate embryos}},
journal = {Nature communications},
year = {2026},
month = apr,
volume = {17},
number = {1},
pages = {4738},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/
url = {https://
pmid = {41922342},
pmcid = {PMC13216532}
}
RIS
TY - JOUR
AU - Carey, Clayton M.
AU - Parvez, Saba
AU - Brandt, Zachary J.
AU - Bisgrove, Brent W.
AU - Yates, Christopher J.
AU - Peterson, Randall T.
AU - Gagnon, James A.
TI - MIC-Drop-seq: scalable single-cell phenotyping of mutant vertebrate embryos
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/
VL - 17
IS - 1
SP - 4738
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1038/
"type": "article-journal",
"title": "MIC-Drop-seq: scalable single-cell phenotyping of mutant vertebrate embryos",
"container-title": "Nature communications",
"author": [
{
"family": "Carey",
"given": "Clayton M."
},
{
"family": "Parvez",
"given": "Saba"
},
{
"family": "Brandt",
"given": "Zachary J."
},
{
"family": "Bisgrove",
"given": "Brent W."
},
{
"family": "Yates",
"given": "Christopher J."
},
{
"family": "Peterson",
"given": "Randall T."
},
{
"family": "Gagnon",
"given": "James A."
}
],
"container-title-short":
"volume": "17",
"issue": "1",
"page": "4738",
"DOI": "10.1038/
"PMID": "41922342",
"PMCID": "PMC13216532",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
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.1038/s41593-026-02367-0 [code]
- A reproducible three-dimensional model of human brain tissue to investigate physiological and disease-associated microglia phenotypes.Journal: Nature neuroscienceIn common: Monocle 3, SingleCellExperiment, edgeR, 9 other tools, 2 references
- [2] 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: Monocle 3, SingleCellExperiment, edgeR, 9 other tools, 2 references
- [3] doi:10.1002/imt2.70163 [code]
- Spatial multi-omics unveils sphingolipid metabolic reprogramming within the retinal pathological niche.Journal: iMetaIn common: Monocle 3, SingleCellExperiment, edgeR, 10 other tools
- [4] doi:10.1186/s12967-026-08266-z [code]
- Single-cell multi-omic integration analysis prioritizes druggable genes and reveals cell-type-specific causal effects in glioblastomagenesis.Journal: Journal of translational medicineIn common: Monocle 3, edgeR, igraph, 8 other tools, 2 references
- [5] doi:10.1038/s41586-026-10214-2 [code]
- Multidimensional profiling of heterogeneity in supratentorial ependymomas.Journal: NatureIn common: Monocle 3, SingleCellExperiment, edgeR, 9 other tools
- [6] doi:10.1038/s41467-026-76341-6 [code]
- Neonatal inflammation disrupts a temporally restricted postnatal Numb-enriched microglial state in mice.Journal: Nature communicationsIn common: Monocle 3, SingleCellExperiment, igraph, 8 other tools, 1 reference
- [7] doi:10.1038/s41398-026-04200-5 [code]
- Postmortem brain single-nucleus and bulk gene expression analyses identify shared and distinct abnormalities in bipolar disorder and major depressive disorder.Journal: Translational psychiatryIn common: SingleCellExperiment, edgeR, rstatix, 8 other tools, 1 reference
- [8] doi:10.1038/s44318-026-00806-z [code]
- Interspecific diversity in the neuronal composition of the mammalian cortex arises from heterochrony in neurogenesis.Journal: The EMBO journalIn common: Monocle 3, SingleCellExperiment, igraph, 8 other tools, 1 reference
- [9] doi:10.1016/j.celrep.2026.117500 [code]
- Spatio-molecular gene expression reflects dorsal anterior cingulate cortex structure and function in the human brain.Journal: Cell reportsIn common: SingleCellExperiment, edgeR, igraph, 8 other tools, 1 reference
- [10] doi:10.1038/s41467-026-71595-6 [code]
- A single-cell and spatial atlas of early human olfactory development.Journal: Nature communicationsIn common: SingleCellExperiment, igraph, circlize, 7 other tools, 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: 2 repositories of the authors' code, each at its verified commit and with its license, 8 scripts, and 20 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:712ffd459a870577…
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.
