Modelling synaptic dysfunction in childhood dementia using human iPSC-derived cortical networks.
The 13 matches
- [1] § Methods › Electrophysiological feature analysis › Gene set enrichment analysis (GSEA) ↔ Rscripts/Differential_Expression_Analysis_120D.Rmd, lines 694–780 · score 0.96 · simplifyGO, GO IDs, Cellular metabolism, avglog2FC, common words, downregulated genes
- [2] § Methods › Electrophysiological feature analysis › Single nuclei data processing ↔ Rscripts/QualityControl_120Day.Rmd, lines 255–289 · score 0.95 · generate cell clusters, Principal component, FindClusters, FindNeighbors, RunUMAP, SCTransform
- [3] § Methods › Electrophysiological feature analysis › Differential expression analysis ↔ Rscripts/Differential_Expression_Analysis_120D.Rmd, lines 782–901 · score 0.92 · FindMarkers, min.diff.pct, logfc.threshold, fold change, log normalised, excitatory neurons
- [4] § Methods › Electrophysiological feature analysis › Gene set enrichment analysis (GSEA) ↔ Rscripts/Differential_Expression_Analysis_120D.Rmd, lines 607–652 · score 0.90 · minSize, nPermSimple, gseaParam, maxSize, synaptic genes, inhibitory neurons
- [5] § Methods › Electrophysiological feature analysis › scMayoMap cell annotations ↔ Rscripts/Neuronal_Glial_Types_Analysis_120D.Rmd, lines 325–401 · score 0.85 · FindConservedMarkers, cluster_type2, scMayoMap, cluster_type1, cell annotations, database
- [6] § Methods › Electrophysiological feature analysis › Integration with neurotypical, human cortical biopsies ↔ Rscripts/QualityControl_120Day.Rmd, lines 255–289 · score 0.80 · SCT assay, variable features, RunPCA, Principal component, SCTransform, days
- [7] § Results › MPS IIIA neurons reveal dysregulated gene expression implicated in synaptic homeostasis ↔ Rscripts/Differential_Expression_Analysis_120D.Rmd, lines 694–780 · score 0.71 · Cellular metabolism, Ions, transport, inhibitory neurons, organising, upregulated
- [8] § Methods › Electrophysiological feature analysis › UMAP and Seurat cluster-based cell classification ↔ Rscripts/Neuronal_Glial_Types_Analysis_120D.Rmd, lines 572–609 · score 0.71 · FindClusters, FindNeighbors, RunUMAP, Seurat cluster, harmony, cells
- [9] § Methods › Electrophysiological feature analysis › Classification of cycling cells ↔ Rscripts/Neuronal_Glial_Types_Analysis_120D.Rmd, lines 211–278 · score 0.71 · cell cycle scores, NonCycling, AddModuleScore, G2M, G1S, gene
- [10] § Results › MPS IIIA neurons reveal dysregulated gene expression implicated in synaptic homeostasis ↔ Rscripts/Differential_Expression_Analysis_120D.Rmd, lines 506–563 · score 0.61 · expressed genes, NEUROD6, SATB2, excitatory neurons, inhibitory neurons, overlap
- [11] § Methods › Electrophysiological feature analysis › Calculation of cell type scores ↔ Rscripts/Neuronal_Glial_Types_Analysis_120D.Rmd, lines 150–209 · score 0.54 · AddModuleScore, Immature Neurons, Nowakowski, scores, OPCs, Astrocytes
- [12] § Methods › Electrophysiological feature analysis › Final cell type assignments ↔ Rscripts/Neuronal_Glial_Types_Analysis_120D.Rmd, lines 325–401 · score 0.51 · scMayoMap, cluster_type1, Seurat cluster, Inhibitory, Excitatory, cell
- [13] § Methods › Electrophysiological feature analysis › Unsupervised clustering analysis ↔ Rscripts/QualityControl_120Day.Rmd, lines 291–323 · score 0.50 · principal components, elbow, variance, PCA, clustering, filtered
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 · 929 lines · 54 KB · no license · 5 matches
- ---
- title: "{[Sanfilippo] Differential expression analysis - 120 Day"
- author: "Inushi De Silva & Paris Mazzachi"
- date: "2023-11-16"
- output: html_document
- editor_options:
- chunk_output_type: console
- chunk_output_type: console
- ---
- ```{r setup, include=FALSE}
- knitr::opts_chunk$set(echo = TRUE)
- ```
- 1. ***First we will load the required libraries and set workingdirectories, datadirectories and plotdirectories.***
- ```{r Load Libraries and Set Directory Paths}
- options(future.globals.maxSize=1000* 1024^3)
- script_path <- rstudioapi::getActiveDocumentContext()$path
- script_dir <- dirname(script_path)
- workingdirectory <- dirname(script_dir)
- setwd(workingdirectory)
- datadirectory <- paste0(workingdirectory,"/data")
- resultsdirectory <- paste0(workingdirectory, "/results")
- RData_directory <- paste0(datadirectory,"/RData")
- ##dir.create(resultsdirectory)
- ## Load required libraries
- if(!require(dplyr)){
- install.packages("dplyr")
- library(dplyr)
- }
- if(!require(Seurat)){
- install.packages("Seurat")
- library(Seurat)
- }
- if(!require(ggplot2)){
- install.packages("ggplot2")
- library(ggplot2)
- }
- if(!require(sctransform)){
- install.packages("sctransform")
- library(sctransform)
- }
- if(!require(RColorBrewer)){
- install.packages("RColorBrewer")
- library(RColorBrewer)
- }
- if(!require(ggpointdensity)){
- install.packages("ggpointdensity")
- library(ggpointdensity)
- }
- if(!require(devtools)){
- install.packages("devtools")
- library(devtools)
- }
- if(!require(BiocManager)){
- install.packages("BiocManager")
- library(BiocManager)
- }
- if(!require(patchwork)){
- install.packages("patchwork")
- library(patchwork)
- }
- ```
- ```{r Other functions required in this markdown}
- ## A function to calculate differentially and significantly expressed geens
- significantly_expressed_genes <- function(differential_genes_df){
- differential_genes_df <- differential_genes_df[order(-differential_genes_df$avg_log2FC, differential_genes_df$p_val_adj),]
- differential_genes_df$p_val_adj[differential_genes_df$p_val_adj == 0] <- 1e-304
- differential_genes_df$log10p_adj <- -log10(differential_genes_df$p_val_adj)
- differential_genes_df$rank <- (differential_genes_df$avg_log2FC)*(differential_genes_df$log10p_adj)
- differential_genes_df <- differential_genes_df[order(differential_genes_df$rank, decreasing = T),]
- top <- differential_genes_df %>% top_n(15, rank)
- bottom <- differential_genes_df %>% top_n(-15, rank)
- label_genes <- c(rownames(top), rownames(bottom))
- differential_genes_df$diffexpressed <- ifelse(differential_genes_df$p_val_adj < 0.05 & differential_genes_df$avg_log2FC > 0, "TOP UP", ifelse(differential_genes_df$p_val_ad < 0.05 & differential_genes_df$avg_log2FC < 0,"TOP DOWN", "NO"))
- differential_genes_df$delabel <- NA
- differential_genes_df$delabel[(rownames(differential_genes_df) %in% label_genes)] <- rownames(differential_genes_df)[(rownames(differential_genes_df) %in% label_genes)]
- differential_genes_df$diffexpressed[is.na(differential_genes_df$delabel)] <- "NO"
- df_name <- deparse(substitute(differential_genes_df))
- return(differential_genes_df)
- }
- ## Adjusted EnrichmentPlot
- EnrichmentPlot <- function (pathway, stats, gseaParam = 1, ticksSize = 0.2)
- {
- pd <- plotEnrichmentData(pathway = pathway, stats = stats,
- gseaParam = gseaParam)
- with(pd, ggplot(data = curve) + geom_line(aes(x = rank, y = ES),
- color = "deepskyblue") + geom_segment(data = ticks, mapping = aes(x = rank,
- y = -spreadES/16, xend = rank, yend = spreadES/16), linewidth = ticksSize) +
- #geom_hline(yintercept = posES, colour = "red", linetype = "dashed") +
- #geom_hline(yintercept = negES, colour = "red", linetype = "dashed") +
- geom_hline(yintercept = 0, colour = "black") + theme(panel.background = element_blank(),
- panel.grid.major = element_line(color = "grey92"), axis.text.x = element_text(size = 18, angle = 90, vjust = 0.5), axis.text.y = element_text(size = 18, hjust = 0.5), axis.title.x = element_text(size = 18), axis.title.y = element_text(size = 18)) +
- labs(x = "Gene rank", y = "Enrichment score")) # + coord_cartesian(ylim = c(-0.025,0.45))
- }
- ## Manually calculate percentage of cells
- PrctCellExpringGene <- function(object, genes, group.by = "all"){
- if(group.by == "all"){
- prct = unlist(lapply(genes,calc_helper, object=object))
- result = data.frame(Markers = genes, Cell_proportion = prct)
- return(result)
- }
- else{
- list = SplitObject(object, group.by)
- factors = names(list)
- results = lapply(list, PrctCellExpringGene, genes=genes)
- for(i in 1:length(factors)){
- results[[i]]$Feature = factors[i]
- }
- combined = do.call("rbind", results)
- return(combined)
- }
- }
- calc_helper <- function(object,genes){
- counts = object[['RNA']]@data
- ncells = ncol(counts)
- if(genes %in% row.names(counts)){
- sum(counts[genes,]>0)/ncells
- }else{return(NA)}
- }
- ## function detect the most common words per cluster
- most_common_word=function(x){
- #Split every word into single words for counting
- splitTest=unlist(strsplit(x," "))
- #Counting words
- count=table(splitTest)
- #Sorting to select only the highest value, which is the first one
- count=count[order(count, decreasing=TRUE)][1:50]
- #Return the desired character.
- #By changing this you can choose whether it show the number of times a word repeats
- return(names(count))
- }
- # from https://hbctraining.github.io/scRNA-seq/lessons/elbow_plot_metric.html
- significant_pcs <- function(x){
- stdv <- x@reductions$pca@stdev # stdev per PC
- sum.stdv <- sum(x@reductions$pca@stdev) # Sum of stdev
- percent.stdv <- (stdv/sum.stdv)*100 # percentage of variation associated with each PC
- cumulative <- cumsum(percent.stdv) # cumulative percent of each PC
- # Determine which PC exhibits cumulative percent greater than 90% and % variation associated with the PC as less than 5
- co1 <- which(cumulative > 90 & percent.stdv < 5)[1]
- # Determine the difference between variation of PC and subsequent PC
- co2 <- sort(which((percent.stdv[1:length(percent.stdv) - 1] - percent.stdv[2:length(percent.stdv)]) > 0.1),
- decreasing = T)[1] + 1
- # Minimum of the two calculations used for clustering
- min.pc <- min(co1, co2)
- return(min.pc)
- }
- ```
- 2. ***Load the required RData files that have previously been QC'd***
- ```{r Load RData files that have previously been QC'd}
- ## Load required datasets
- set.seed(1)
- file_names <- list.files(paste0(RData_directory,"/120D/revisions/"), pattern = "*RData",full.names = T)
- lapply(file_names[c(6, 8)], load, .GlobalEnv)
- rm(file_names)
- ```
- 3. ***We now load in genes from the Nowakowski and Liddelow datasets***
- ```{r Load in neuronal gene lists and create colour scheme}
- ##load updated neuronal gene lists
- ##The gene names have been updated previously.
- load(file = paste0(datadirectory, "/reference_sheets/updated_neuronal_genes_ls.RData"))
- library(readxl)
- synaptic_genes <- read_excel(paste0(datadirectory, "/reference_sheets/syngo_genes.xlsx")) # SynGO Portal v1.2 (2023-12-01)
- stress_genes <- read_excel(paste0(datadirectory, "/reference_sheets/response_to_stress_genes.xlsx"))
- neuronal_genes_ls <- updated_neuronal_genes_ls
- rm(updated_neuronal_genes_ls)
- ## We also create a colour palette for each of the cell types
- library(colorspace)
- colour_palette <- data.frame(matrix(nrow = 44, ncol = 2))
- colour_palette$X1 <- c(names(neuronal_genes_ls)[1:43], "Other")
- colour_palette$X2[grepl("Astrocyte", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("salmon", "red"))(3)
- colour_palette$X2[grepl("eN", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("chocolate4", "tan"))(18)
- colour_palette$X2[grepl("RG", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("limegreen", "palegreen"))(11)
- colour_palette$X2[grepl("MGE_newborn", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("plum", "plum4"))(5)
- colour_palette$X2[grepl("MGE_Ctx", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("purple", "purple3"))(2)
- colour_palette$X2[grepl("CGE_LGE", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("slateblue", "slateblue4"))(2)
- colour_palette$X2[grepl("OPC", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("royalblue", "royalblue"))(1)
- colour_palette$X2[grepl("Striatal", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("sienna", "sienna"))(1)
- colour_palette$X2[grepl("Microglia", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("aquamarine3", "aquamarine3"))(1)
- colour_palette$X2[grepl("Mural", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("khaki", "khaki"))(1)
- colour_palette$X2[grepl("Other", colour_palette$X1, ignore.case = T)] <- colorRampPalette(c("black", "black"))(1)
- ##convert to named vector
- colours <- as.vector(colour_palette$X2)
- names(colours) <- colour_palette$X1
- ```
- 4. ***We now perform a differential expression analysis between control and MPSIIIA***
- ```{r Differential Expression Analysis and Volcano Plots - ALL}
- ## To perform differential expression analysis we first merge the two Seurat objects together.
- ## We will use the datasets which do not contain any "Unassigned" values for the donor id
- Sanfilippo_120D <- merge(Control_filtered_ambientRNA_120D, MPSIIIA_filtered_ambientRNA_120D) # remove 2 unassigned from MPSIIIA seurat
- table(Sanfilippo_120D$orig.ident)
- tbl <- [email hidden] %>% group_by(orig.ident, BIAD_id, final_cell_type) %>% summarise(n = n())
- cells_to_remove <- c("unassigned", "doublet") # remove doublets and unassigned cells
- Sanfilippo_120D <- subset(Sanfilippo_120D, cells = which(Sanfilippo_120D$BIAD_id %in% cells_to_remove), invert = T) # need to removed 2 unassigned from sanfil + striatal neurons
- tbl <- [email hidden] %>% group_by(orig.ident, BIAD_id, final_cell_type) %>% summarise(n = n())
- [email hidden] %>% group_by(orig.ident) %>% summarise(n = n())
- Idents(Sanfilippo_120D) <- 'orig.ident'
- Idents(Sanfilippo_120D) <- 'final_cell_type'
- Sanfilippo_120D <- subset(Sanfilippo_120D, downsample = 6619) # Downsample to have same pool of cells in each genotype
- [email hidden] %>% group_by(orig.ident) %>% summarise(n = n())
- ## We now SCTransform, RunPCA and UMAP to normalise gene expressions.
- Sanfilippo_120D <- JoinLayers(Sanfilippo_120D, assay = 'RNA')
- Sanfilippo_120D <- SCTransform(Sanfilippo_120D, vars.to.regress = c("percent.mt", "BIAD_id"))
- ## Save the seurat object to save time in future without re-running SCTransform each time
- save(Sanfilippo_120D, file = paste0(datadirectory, "/RData/120D/revisions/Combined_Control_MPSIIIA_120D_NOambientRNA.RData"))
- load(file = paste0(datadirectory, "/RData/120D/revisions/Combined_Control_MPSIIIA_120D_NOambientRNA.RData")) # Once run SCTransform once, can load the save RData file
- ## Run PCA and clustering for visualisation of cell types
- Sanfilippo_120D <- RunPCA(Sanfilippo_120D, npcs = 100, assay = "SCT")
- Sanfilippo_120D <- NormalizeData(Sanfilippo_120D, assay = "RNA", normalization.method = "LogNormalize")
- min.pc <- significant_pcs(Sanfilippo_120D)
- Sanfilippo_120D <- FindNeighbors(Sanfilippo_120D, dims = 1:min.pc, reduction = "pca")
- Sanfilippo_120D <- FindClusters(Sanfilippo_120D, resolution = 0.1)
- Sanfilippo_120D <- RunUMAP(Sanfilippo_120D, reduction = "pca", dims= 1:min.pc, n.components = 2L)
- tbl <- [email hidden] %>%
- group_by(orig.ident, BIAD_id, final_cell_type) %>%
- summarise(n = n()) %>%
- mutate(freq = (n / sum(n))*100)
- tbl
- write.csv(tbl, file = paste0(resultsdirectory, "/sheets/revisions_120D/20250717_MPSIIIAvHealthy_CellTypes_PatientProportions.csv"))
- Sanfilippo_120D$final_cell_type <- factor(Sanfilippo_120D$final_cell_type, levels = c( "Astrocyte","OPC","RG","Immature Neurons","Inhibitory","Excitatory")) # Re-order cell types for visualisation
- ## Visualisation of different cell types in culture - Fig 1B ##
- umap <- DimPlot(Sanfilippo_120D, reduction = "umap", group.by = "final_cell_type", split.by = "orig.ident", cols = c("firebrick4", "darkorchid2", "orange", "forestgreen", "mediumblue","deeppink2"), pt.size = 0.5, alpha = 1.0, order = T, label = FALSE, repel = FALSE) + ##you can replace the group.by variable to any column on the metadata
- theme(legend.position = "bottom", legend.text = element_text(size = 10), legend.justification = "center",
- axis.text.x = element_text(size = 22), axis.text.y = element_text(size = 22),
- axis.title.x = element_text(size = 22), axis.title.y = element_text(size = 22),
- panel.border = element_rect(fill=NA, colour = "black", size=0.5), plot.title= element_blank()) +
- coord_cartesian(ylim = c(-10, 10))
- umap <- umap + NoAxes() #+ NoLegend()
- umap
- ggsave(umap, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250717_ControlMPSIIIA_CellTypes_E-ISplit_percent.mito_BIAD-id.pdf", sep = ""), height = 6, width = 10, dpi = 300, useDingbats = FALSE, limitsize = F)
- ## Cell types separated by each donor - Supp Fig 3A ##
- Sanfilippo_120D$BIAD_id <- factor(Sanfilippo_120D$BIAD_id, levels = c( "B04-cNP11","B13-cNP20","B12-cNP24","B06-cNP08","B05-cNP21","B11-cNP30", "B03-cNP13", "B02-cNP16", "B01-cNP06", "B10-cNP25"))
- biad_ids <- unique(Sanfilippo_120D$BIAD_id)[1:10]
- umap_plots <- list()
- for (id in biad_ids) {
- umap <- DimPlot(Sanfilippo_120D, reduction = "umap", group.by = "final_cell_type",
- cells = which(Sanfilippo_120D$BIAD_id == id), # Subset cells by BIAD_id
- cols = c("firebrick4", "darkorchid2", "orange", "forestgreen", "mediumblue","deeppink2"),
- pt.size = 0.5, alpha = 1.0, order = TRUE, label = FALSE, repel = FALSE) +
- ggtitle(id) +
- theme(legend.position = "bottom",
- legend.text = element_text(size = 10),
- legend.justification = "center",
- axis.text.x = element_text(size = 22),
- axis.text.y = element_text(size = 22),
- axis.title.x = element_text(size = 22),
- axis.title.y = element_text(size = 22),
- panel.border = element_rect(fill = NA, colour = "black", size = 0.5),
- plot.title = element_text(size = 22, hjust = 0.5)) +
- coord_cartesian(ylim = c(-10, 10)) +
- NoAxes() #+ NoLegend() # Uncomment NoLegend if desired
- umap_plots[[id]] <- umap
- }
- combined_plot <- wrap_plots(umap_plots, nrow = 2, ncol = 5)
- combined_plot
- ggsave(combined_plot, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250718_ControlMPSIIIA_BIAD-id_neurons-split_noaxes_percent.mito_BIAD-id.pdf", sep = ""), height = 10.5, width = 20, dpi = 300, useDingbats = FALSE, limitsize = F)
- tbl <- [email hidden] %>%
- group_by(orig.ident, BIAD_id, final_cell_type) %>%
- summarise(n = n()) %>%
- mutate(freq = (n / sum(n))*100)
- tbl
- write.csv(tbl, file = paste0(resultsdirectory, '/sheets/revisions_120D/20250604_120D_BIAD-id_nodonordownsample_cell_types.csv'))
- ## Cell cycle analysis - Supp Fig 3F ##
- umap_density <- [email hidden][,c("orig.ident","cell_cycle")]
- umap_density <- cbind(umap_density, Sanfilippo_120D@reductions$[email hidden])
- scatterPlot <- ggplot(umap_density[na.omit(umap_density$cell_cycle == "NonCycling"),], aes(x = umap_1, y = umap_2)) +
- geom_point(data = umap_density[na.omit(umap_density$cell_cycle != "NonCycling"),], color = "grey90", size = 0.5) +
- geom_pointdensity(adjust = 0.2, size = 0.5) +
- scale_colour_gradient(low = "ghostwhite", high = "firebrick1", breaks = c(0,45,90), limits=c(0,90), na.value = "black") + #
- facet_wrap(~orig.ident, labeller = labeller(orig.ident = c("Control_120D" = "Healthy\n n= 6464 (98%)", "Sanfilippo_120D" = "MPSIIIA\n n= 6348 (96%)"))) +
- theme_bw() +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "bottom", legend.text = element_text(size = 16, vjust = 0.5), legend.title = element_blank(), axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 20), axis.title.x = element_text(size = 20), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + NoAxes()
- scatterPlot
- scatterPlot <- ggplot(umap_density[na.omit(umap_density$cell_cycle == "G1S"),], aes(x = umap_1, y = umap_2)) +
- geom_point(data = umap_density[na.omit(umap_density$cell_cycle != "G1S"),], color = "grey90", size = 0.5) +
- geom_pointdensity(adjust = 0.2, size = 0.5) +
- scale_colour_gradient(low = "ghostwhite", high = "green1", breaks = c(0,25), limits=c(0,25), na.value = "black") + #
- facet_wrap(~orig.ident, labeller = labeller(orig.ident = c("Control_120D" = "Healthy\n n= 91 (1%)", "Sanfilippo_120D" = "MPSIIIA\n n= 153 (2%)"))) +
- theme_bw() +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "bottom", legend.text = element_text(size = 16, vjust = 0.5), legend.title = element_blank(), axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 20), axis.title.x = element_text(size = 20), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + NoAxes()
- scatterPlot
- scatterPlot <- ggplot(umap_density[na.omit(umap_density$cell_cycle == "G2M"),], aes(x = umap_1, y = umap_2)) +
- geom_point(data = umap_density[na.omit(umap_density$cell_cycle != "G2M"),], color = "grey90", size = 0.5) +
- geom_pointdensity(adjust = 0.2, size = 0.5) +
- scale_colour_gradient(low = "ghostwhite", high = "gold", breaks = c(0,16,32), limits=c(0,32), na.value = "black") + #
- facet_wrap(~orig.ident, labeller = labeller(orig.ident = c("Control_120D" = "Healthy\n n= 64 (1%)", "Sanfilippo_120D" = "MPSIIIA\n n= 118 (2%)"))) +
- theme_bw() +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "bottom", legend.text = element_text(size = 16, vjust = 0.5), legend.title = element_blank(), axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 20), axis.title.x = element_text(size = 20), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + NoAxes()
- scatterPlot
- ggsave(scatterPlot, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250523_Control_MPSIIIA_G2M_Density_final.pdf", sep = ""), height = 6.5, width = 10, dpi = 300, useDingbats = FALSE, limitsize = F)
- tbl <- [email hidden] %>%
- group_by(final_cell_type, new_cell_types) %>%
- summarise(n = n()) %>%
- mutate(freq = (n / sum(n))*100)
- tbl
- ```
- 4. ***Now we isolate just the neurons and separate them into excitatory and inhibitory neurons***
- ```{Identify excitatory and inhibitory neurons}
- ## Isolate the 'Neurons' from broad_cell_types to further separate them into excitatory and inhibitory neurons
- table([email hidden][['final_cell_type']])
- Idents(Sanfilippo_120D) <- 'final_cell_type'
- Sanfilippo_120D_Neurons <- subset(Sanfilippo_120D, idents = c('Excitatory', 'Inhibitory'))
- table(Sanfilippo_120D_Neurons$orig.ident)
- Idents(Sanfilippo_120D_Neurons) <- "orig.ident"
- Sanfilippo_120D_Neurons <- subset(Sanfilippo_120D_Neurons, downsample = 1015)
- [email hidden] %>% group_by(orig.ident) %>% summarise(n = n())
- Sanfilippo_120D_Neurons$neuron_types_ident <- paste(Sanfilippo_120D_Neurons$orig.ident, Sanfilippo_120D_Neurons$final_cell_type, sep = "_")
- Sanfilippo_120D_Neurons$biad_id_type <- paste(Sanfilippo_120D_Neurons$BIAD_id, Sanfilippo_120D_Neurons$final_cell_type, sep = "_")
- ## Save out proportion of excitatory and inhibitory neurons
- tbl <- [email hidden] %>%
- group_by(orig.ident, final_cell_type) %>%
- summarise(n = n()) %>%
- mutate(freq = (n / sum(n))*100)
- tbl
- write.csv(tbl, file = paste0(resultsdirectory, '/sheets/revisions_120D/20250604_120D_BIAD-id_nodonordownsample_Split_Neuron-type-proportions.csv'))
- # proportions used in Supp Fig 20B #
- tbl <- [email hidden] %>%
- group_by(orig.ident, BIAD_id, final_cell_type) %>%
- summarise(n = n()) %>%
- mutate(freq = (n / sum(n))*100)
- tbl
- write.csv(tbl, file = paste0(resultsdirectory, '/sheets/[Sanfilippo] DE_120D/20250604_MPSIIIA-Healthy_NeuronType_BIAD-id_proportions.csv'))
- ## Prepare object for UMAP reduction
- Sanfilippo_120D_Neurons <- SCTransform(Sanfilippo_120D_Neurons, vars.to.regress = c("percent.mt", "BIAD_id"))
- ## Save out seurat object
- save(Sanfilippo_120D_Neurons_New, file = paste0(datadirectory, "/RData/120D/revisions/Combined_Control_MPSIIIA_120D_NOambientRNA_NeuronsOnly.RData")) # As above, save after running SCTransform to save time
- load(file = paste0(datadirectory, "/RData/120D/revisions/Combined_Control_MPSIIIA_120D_NOambientRNA_NeuronsOnly.RData"))
- ## Re-run PCA and clustering for visualisation of neuronal subtypes
- var_features <- Sanfilippo_120D_Neurons_New@assays[["SCT"]]@var.features
- var_features <- var_features[grep("^LINC|^LOC|^AC[0-9]*\\.[0-9]|^AP[0-9]*\\.[0-9]|^AL[0-9]*\\.[0-9]",var_features, invert = T)]
- Sanfilippo_120D_Neurons_New <- RunPCA(Sanfilippo_120D_Neurons_New, npcs = 100, assay = "SCT", features = var_features)
- Sanfilippo_120D_Neurons_New <- NormalizeData(Sanfilippo_120D_Neurons_New, assay = "RNA", normalization.method = "LogNormalize")
- min.pc <- significant_pcs(Sanfilippo_120D_Neurons_New)
- Sanfilippo_120D_Neurons_New <- FindNeighbors(Sanfilippo_120D_Neurons_New, dims = 1:min.pc, reduction = "pca")
- Sanfilippo_120D_Neurons_New <- FindClusters(Sanfilippo_120D_Neurons_New, resolution = 0.1)
- Sanfilippo_120D_Neurons_New <- RunUMAP(Sanfilippo_120D_Neurons_New, reduction = "pca", dims= 1:min.pc, n.components = 2L)
- ## Visualise spread of excitatory/inhibitory neurons - Fig 7A ##
- umap <- DimPlot(Sanfilippo_120D_Neurons_New, reduction = "umap", group.by = "nowakowski_celltypes", split.by = "orig.ident", pt.size = 1.25, alpha = 1.0, order = T, label = FALSE, repel = FALSE) + ##you can replace the group.by variable to any column on the metadata
- theme(legend.position = "bottom", legend.text = element_text(size = 10), legend.justification = "center",
- axis.text.x = element_text(size = 22), axis.text.y = element_text(size = 22),
- axis.title.x = element_text(size = 22), axis.title.y = element_text(size = 22),
- panel.border = element_rect(fill=NA, colour = "black", size=0.5), plot.title= element_blank())# +
- #coord_cartesian(ylim = c(-10, 10))
- umap <- umap + NoAxes() #+ NoLegend()
- umap
- ggsave(umap, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250529_Excit-Inhib_percent.mt_BIAD-id_nodonordownsample.pdf", sep = ""), height = 6, width = 10, dpi = 300, useDingbats = FALSE, limitsize = F)
- ## Confirm neuronal populations express correct excitatory or inhibitory markers - Fig 7A ##
- features <- c("NXPH1","GAD1","GAD2","SOX6","SLC6A1","SHANK2","GRIA2","GRM5","SOX5","CAMK2A") # excitatory and inhibitory markers
- Idents(Sanfilippo_120D_Neurons_New) <- 'neuron_types_ident'
- dotplot <- DotPlot(Sanfilippo_120D_Neurons_New, features = features, cols = c("blue", "firebrick2"), idents = c("Sanfilippo_120D_Excitatory", "Sanfilippo_120D_Inhibitory")) + theme_bw() +
- #labs(title = "Excitatory Neurons", subtitle = "[n = 26 cells]") +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "right", legend.text = element_text(size = 16, vjust = 0.5), axis.text.x = element_blank(), axis.text.y = element_text(size = 20), axis.title.x = element_blank(), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + coord_flip() #+ scale_y_reordered()
- dotplot$data$id <- factor(dotplot$data$id,
- levels = c("Sanfilippo_120D_Excitatory", "Sanfilippo_120D_Inhibitory"))
- dotplot
- ggsave(dotplot, filename = paste0(resultsdirectory,"/plots/revisions_120D/20250529_MPSIIIA_ExcVInhibNeurons_DotPlot_nodonordownsamp.pdf"), height = 5, width = 4.5, dpi = 300)
- ## Density plots separating excitatory and inhibitory neurons - Supp Fig 20C ##
- ## Excitatory neurons
- umap_density <- [email hidden][,c("orig.ident","final_cell_type")]
- umap_density <- cbind(umap_density, Sanfilippo_120D_Neurons_New@reductions$[email hidden])
- scatterPlot <- ggplot(umap_density[na.omit(umap_density$final_cell_type == "Excitatory"),], aes(x = umap_1, y = umap_2)) +
- geom_point(data = umap_density[na.omit(umap_density$final_cell_type != "Excitatory"),], color = "grey90", size = 1.25) +
- geom_pointdensity(adjust = 0.2, size = 1.25) +
- scale_colour_gradient(low = "ghostwhite", high = "deeppink2", breaks = c(0,24), limits=c(0,24), na.value = "black") + #
- facet_wrap(~orig.ident, labeller = labeller(orig.ident = c("Control_120D" = "Healthy\n n= 320 (31.5%)", "Sanfilippo_120D" = "MPSIIIA\n n= 505 (49.8%)"))) +
- theme_bw() +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "bottom", legend.text = element_text(size = 16, vjust = 0.5), legend.title = element_blank(), axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 20), axis.title.x = element_text(size = 20), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + NoAxes()
- scatterPlot
- ggsave(scatterPlot, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250529_Control_MPSIIIA_ExcitatoryNeurons_Density_nodonordownsamp.pdf", sep = ""), height = 6, width = 10, dpi = 300, useDingbats = FALSE, limitsize = F)
- ## Inhibitory neurons
- scatterPlot <- ggplot(umap_density[na.omit(umap_density$final_cell_type == "Inhibitory"),], aes(x = umap_1, y = umap_2)) +
- geom_point(data = umap_density[na.omit(umap_density$final_cell_type != "Inhibitory"),], color = "grey90", size = 1.25) +
- geom_pointdensity(adjust = 0.2, size = 1.25) +
- scale_colour_gradient(low = "ghostwhite", high = "mediumblue", breaks = c(0,19), limits=c(0,19), na.value = "black") + #
- facet_wrap(~orig.ident, labeller = labeller(orig.ident = c("Control_120D" = "Healthy\n n= 695 (68.5%)", "Sanfilippo_120D" = "MPSIIIA\n n= 510 (50.2%)"))) +
- theme_bw() +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "bottom", legend.text = element_text(size = 16, vjust = 0.5), legend.title = element_blank(), axis.text.x = element_text(size = 20), axis.text.y = element_text(size = 20), axis.title.x = element_text(size = 20), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + NoAxes()
- scatterPlot
- ggsave(scatterPlot, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250529_Control_MPSIIIA_Inhib_Density_redone_nodonordownsamp.pdf", sep = ""), height = 6, width = 10, dpi = 300, useDingbats = FALSE, limitsize = F)
- ## Density plot looking at split of excitatory and inhibitory neurons by donor - Supp Fig 20E ##
- Sanfilippo_120D_Neurons_New$BIAD_id <- factor(Sanfilippo_120D_Neurons_New$BIAD_id, levels = c( "B04-cNP11","B13-cNP20","B12-cNP24","B06-cNP08","B05-cNP21","B11-cNP30", "B03-cNP13", "B02-cNP16", "B01-cNP06", "B10-cNP25"))
- umap_density <- [email hidden][,c("BIAD_id","final_cell_type")]
- umap_density <- cbind(umap_density, Sanfilippo_120D_Neurons_New@reductions$[email hidden])
- library(ggnewscale)
- scatterPlot <- ggplot(umap_density, aes(x = umap_1, y = umap_2)) +
- geom_point(data = umap_density[!(umap_density$final_cell_type %in% c("Excitatory", "Inhibitory")),], color = "grey80", size = 1.25) +
- geom_pointdensity(data = umap_density[umap_density$final_cell_type == "Excitatory",], adjust = 0.2, size = 1.25) +
- scale_colour_gradient(name = "Excitatory", low = "ghostwhite", high = 'deeppink2', breaks = c(0,24), limits=c(0,24), na.value = 'black') +
- new_scale_colour() +
- geom_pointdensity(data = umap_density[umap_density$final_cell_type == "Inhibitory",], adjust = 0.2, size = 1.25) +
- scale_colour_gradient(name = "Inhibitory", low = "ghostwhite", high = "mediumblue", breaks = c(0,19), limits=c(0,19), na.value = "black") +#breaks = c(0,24), limits = c(0,24),
- facet_wrap(~BIAD_id, labeller = labeller(BIAD_id = c(
- "B12-cNP24" = 'BIAD12 (2 clones)',
- "B06-cNP08" = 'BIAD06 (2 clones)',
- "B13-cNP20" = 'BIAD13 (2 clones)',
- "B04-cNP11" = 'BIAD04 (2 clones)',
- "B05-cNP21" = 'BIAD05 (1 clone)',
- "B11-cNP30" = 'BIAD11 (2 clones)',
- 'B10-cNP25' = 'BIAD10 (2 clones)',
- "B01-cNP06" = 'BIAD01 (2 clones)',
- "B03-cNP13" = 'BIAD03 (2 clones)',
- "B02-cNP16" = 'BIAD02 (2 clones)')), ncol = 5) +
- theme_bw() +
- theme(
- plot.title = element_text(size = 20, hjust = 0.5),
- plot.subtitle = element_text(size = 16, hjust = 0.5, face = "italic"),
- legend.position = "bottom",
- legend.text = element_text(size = 16, vjust = 0.5),
- axis.text.x = element_text(size = 20),
- axis.text.y = element_text(size = 20),
- axis.title.x = element_text(size = 20),
- axis.title.y = element_text(size = 20),
- panel.border = element_rect(fill = NA, colour = "black", size = 0.25),
- panel.grid = element_blank(),
- strip.text.x = element_text(size = 20),
- strip.background = element_blank()
- ) +
- coord_equal() + NoAxes()
- # Display the scatter plot
- scatterPlot
- ggsave(scatterPlot, filename = paste0(resultsdirectory,"/plots/revisions_120D/UMAPs_120D/20250529_ControlMPSIIIA_UMAP_DonorID_ExcitatoryInhibitory_Density_nodonordownsamp.pdf", sep = ""), height = 12, width = 14, dpi = 300, useDingbats = FALSE, limitsize = F)
- ```
- 5. We perform differential expression analysis on different neuronal subtypes
- ``` {DE Analysis and visulation for excitatory and inhibitory neurons}
- ## We conduct a differential expression to identify genes that are significantly expressed in Sanfilippo compared to Control.
- ## Excitatory neurons
- Idents(Sanfilippo_120D_Neurons_New) <- 'neuron_types_ident'
- DE_Control_MPSIIIA_EN <- FindMarkers(Sanfilippo_120D_Neurons_New, assay = 'RNA', slot = 'data', ident.1 = "Sanfilippo_120D_Excitatory", ident.2 = "Control_120D_Excitatory", logfc.threshold = 0, min.pct = 0.1, min.diff.pct = 0.1, test.use = "wilcox")
- DE_Control_MPSIIIA_EN$hgnc_symbol <- rownames(DE_Control_MPSIIIA_EN)
- DE_Control_MPSIIIA_EN <- significantly_expressed_genes(DE_Control_MPSIIIA_EN)
- ## Save out DE results
- write.csv(DE_Control_MPSIIIA_EN, file = paste0(resultsdirectory, "/sheets/revisions_120D/DE_120D/20250718_DE_Control_MPSIIIA_ExcitatoryNeurons_wilcox_nodonordownsample.csv"))
- # #Inhibitory neurons
- DE_Control_MPSIIIA_IN <- FindMarkers(Sanfilippo_120D_Neurons_New, assay = 'RNA', slot = 'data', ident.1 = "Sanfilippo_120D_Inhibitory", ident.2 = "Control_120D_Inhibitory", logfc.threshold = 0, min.pct = 0.1, min.diff.pct = 0.1, test.use = "wilcox")
- DE_Control_MPSIIIA_IN$hgnc_symbol <- rownames(DE_Control_MPSIIIA_IN)
- DE_Control_MPSIIIA_IN <- significantly_expressed_genes(DE_Control_MPSIIIA_IN)
- ## Save out DE results
- write.csv(DE_Control_MPSIIIA_IN, file = paste0(resultsdirectory, "/sheets/revisions_120D/DE_120D/20250718_DE_Control_MPSIIIA_InhibitoryNeurons_wilcox_nodonordownsample.csv"))
- ## Dot plots to visualise key genes up or down regulated in excitatory and inhibitory neurons (disease v healthy) - Figure 5B
- excitatory_genes <- c("PEG3", "AC069277.1", "XIST", "AC006115.2", "GRM7-AS3", "IQCJ-SCHIP1", "NELL2", "NEUROD6", "SATB2", "TAFA1") # top 5 up/down DEG
- inhibitory_genes <- c("PEG3", "AC069277.1", "MTRNR2L1", "XIST", "GRM7-AS3", "CRLF1", "PTGDS", "CHL1", "IFITM3", "NEUROD6") # top 5 up/down DEG
- excit_v_inhib <- DotPlot(Sanfilippo_120D_Neurons_New, features = inhibitory_genes, cols = c("blue", "firebrick2"), idents = c("Sanfilippo_120D_Inhibitory", "Control_120D_Inhibitory")) + theme_bw() +
- #labs(title = "Excitatory Neurons", subtitle = "[n = 26 cells]") +
- theme(plot.title = element_text(size = 20, hjust = 0.5), plot.tag.position = "top",plot.subtitle = element_text(size = 20, hjust = 0.5, face = "plain"), plot.title.position = "plot", legend.position = "right", legend.text = element_text(size = 16, vjust = 0.5), axis.text.x = element_blank(), axis.text.y = element_text(size = 20), axis.title.x = element_blank(), axis.title.y = element_text(size = 20), panel.border = element_rect(fill=NA, colour = "black", size=0.5), panel.grid = element_blank(), strip.text.x = element_text(size=20),strip.background = element_blank()) + coord_flip() #+ scale_y_reordered()
- excit_v_inhib$data$id <- factor(excit_v_inhib$data$id,
- levels = c("Sanfilippo_120D_Inhibitory", "Control_120D_Inhibitory"))
- excit_v_inhib
- ggsave(excit_v_inhib, filename = paste0(resultsdirectory,"/plots/revisions_120D/DE_120D/20250529_SanfilvControl_InhibitoryNeurons_DotPlot_nodonordownsample.pdf"), height = 5, width = 4.75, dpi = 300)
- ## Volcano Plot - Fig 7B (swap the data between excitatory or inhibitory DE results) ##
- VP <- ggplot(DE_Control_MPSIIIA_EN, aes(avg_log2FC, log10p_adj, label=delabel, color=diffexpressed)) + geom_point(alpha = 1, size = 3, fill = "grey90") + ## transform to change the order of the plots in facet_wrap()
- theme_light() +
- scale_fill_gradientn(colours = c(rainbow(100)), ## colors in the scale
- breaks = seq(0, 1, 0.2),
- limits = c(0, 1)) +
- scale_color_manual(values = c("grey60","blue","red")) +
- geom_text_repel(data=DE_Control_MPSIIIA_EN, size = 8, max.overlaps = 75, direction = "both") +
- theme(legend.position = "right", axis.text.x = element_text(size = 28), axis.text.y = element_text(size = 28), axis.title.x = element_text(size = 30), axis.title.y = element_text(size = 30), panel.border = element_rect(fill=NA, colour = "black", size=0.5)) +
- labs(y=expression('-Log'[10]*' P'[adj]), x=expression(atop('Log'[2]*' fold change', paste("[MPSIIIA/Control]")))) +
- scale_x_continuous(breaks = seq(-7, 7, by = 2)) +
- scale_y_continuous(breaks = seq(0, 90, by = 20)) +
- coord_cartesian(xlim = c(-7, 7), ylim = c(0, 80)) +
- geom_hline(yintercept = -log10(0.05), linetype = "dashed", col = "darkgrey", size = 1) + NoLegend()
- VP
- ggsave(VP, filename = paste0(resultsdirectory,"/plots/revisions_120D/DE_120D/20250529_VP_MPSIIIA_Control_DE_ExcitatoryNeurons_nodonordownsample.pdf"), height = 10, width = 10, dpi = 300)
- # Looking at expression of E/I genes by patient - Fig 7F #
- Idents(Sanfilippo_120D_Neurons_New) <- "BIAD_id"
- average_expression <- AverageExpression(Sanfilippo_120D_Neurons_New, assay = "RNA", slot = "counts", features = c("NLGN1", "CDKL5", "DISC1", "SHANK2", "DLG4", "GPHN", "NLGN2", "GABRA1", "GLRB", "GRIA1", "GRIA2", "GRIA3", "GRIA4", "HOMER1", "CAMK2A", "ARHGEF9", "KCC2", "GRIN1", "GRIN2A", "GRIN2B", "GABARAP", "GABRA2"), group.by = c("BIAD_id", "final_cell_type"))
- average_expression <- as.data.frame(average_expression)
- average_expression <- t(average_expression)
- write.csv(average_expression, file = paste0(resultsdirectory, "/sheets/revisions_120D/DE_120D/20250717_synapsegenes_e-i-neurons_biad-id_rawcounts_120d.csv"))
- ```
- 6.***We perform GSEA for excitatory and inhibitory neurons***
- ```{r GSEA for differentially expressed genes in excitatory and inhibitory neurons}
- ### Use this if you want to run fgsea analysis
- library(fgsea)
- library(data.table)
- ## Isolate avglog2FC values from previously ranked DE list for excitatory and inhibitory neurons
- upreg_EN <- DE_Control_MPSIIIA_EN[which(DE_Control_MPSIIIA_EN$avg_log2FC > 0 & DE_Control_MPSIIIA_EN$p_val_adj < 0.05),]
- downreg_EN <- DE_Control_MPSIIIA_EN[which(DE_Control_MPSIIIA_EN$avg_log2FC < 0 & DE_Control_MPSIIIA_EN$p_val_adj < 0.05),]
- dysreg_EN <- rbind(upreg_EN, downreg_EN)
- ranked_genes_EN <- dysreg_EN$avg_log2FC
- names(ranked_genes_EN) <- rownames(dysreg_EN)
- upreg_IN <- DE_Control_MPSIIIA_IN[which(DE_Control_MPSIIIA_IN$avg_log2FC > 0 & DE_Control_MPSIIIA_IN$p_val_adj < 0.05),]
- downreg_IN <- DE_Control_MPSIIIA_IN[which(DE_Control_MPSIIIA_IN$avg_log2FC < 0 & DE_Control_MPSIIIA_IN$p_val_adj < 0.05),]
- dysreg_IN <- rbind(upreg_IN, downreg_IN)
- ranked_genes_IN <- dysreg_IN$avg_log2FC
- names(ranked_genes_IN) <- rownames(dysreg_IN)
- Idents(Sanfilippo_120D_Neurons_New) <- 'neuron_types_ident'
- # Create a dataframe with avg log2FC values for a list of synaptic genes
- av_exp_df <- as.data.frame(AverageExpression(Sanfilippo_120D_Neurons_New, assays = "RNA", slot = "data", features = unique(unlist(synaptic_genes$hgnc_symbol))))
- av_exp_df$Logadj_Control_EN <- log2((av_exp_df$RNA.Control.120D.Excitatory))
- av_exp_df$Logadj_MPSIIIA_EN <- log2((av_exp_df$RNA.Sanfilippo.120D.Excitatory))
- av_exp_df$Logadj_Control_IN <- log2((av_exp_df$RNA.Control.120D.Inhibitory))
- av_exp_df$Logadj_MPSIIIA_IN <- log2((av_exp_df$RNA.Sanfilippo.120D.Inhibitory))
- av_exp_df$avg_log2FC_ENs <- av_exp_df$Logadj_MPSIIIA_EN - av_exp_df$Logadj_Control_EN
- av_exp_df$avg_log2FC_ENs[is.na(av_exp_df$avg_log2FC_ENs)] <- 0
- av_exp_df$avg_log2FC_ENs[is.infinite(av_exp_df$avg_log2FC_ENs)] <- 0
- av_exp_df$avg_log2FC_INs <- av_exp_df$Logadj_MPSIIIA_IN - av_exp_df$Logadj_Control_IN
- av_exp_df$avg_log2FC_INs[is.na(av_exp_df$avg_log2FC_INs)] <- 0
- av_exp_df$avg_log2FC_INs[is.infinite(av_exp_df$avg_log2FC_INs)] <- 0
- ranked_genes <- as.vector(av_exp_df[,10])
- names(ranked_genes) <- rownames(av_exp_df)
- ranked_genes <- sort(ranked_genes, decreasing = T)
- ## Load list of synaptic genes
- pathways <- list("DEGs" = dysreg_EN$hgnc_symbol)
- pathways_IN <- list("DEGs" = dysreg_IN$hgnc_symbol)
- gse_all_EN <- fgsea(pathways,
- stats = ranked_genes,
- minSize = 1,
- maxSize = 500,
- nPermSimple = 10000,
- gseaParam = 1,
- eps = 0)
- gse_all_IN <- fgsea(pathways_IN,
- stats = ranked_genes,
- minSize = 1,
- maxSize = 500,
- nPermSimple = 10000,
- gseaParam = 1,
- eps = 0)
- ## Visualise enrichment for excitatory and inhibitory neurons - Fig 7E ##
- pdf(paste0(resultsdirectory,"/plots/revisions_120D/DE_120D/20250623_SynapticGene_Enrichment_Plot_InhibitoryNeurons_nodonordownsample.pdf"), width=7.5, height=5)
- EP <- EnrichmentPlot(pathways$DEGs,
- ranked_genes, gseaParam = 2, ticksSize = 0.2)
- EP
- dev.off()
- test_list <- list(gse_all$leadingEdge)
- gse_all_EN <- as.data.frame(gse_all_EN)
- gse_all_EN <- gse_all_EN[1:7]
- gse_all_IN <- as.data.frame(gse_all_IN)
- gse_all_IN <- gse_all_IN[1:7]
- write.csv(gse_all_EN, file = paste0(resultsdirectory, '/sheets/revisions_120D/20250623_SynapticEnrich_ExcitatoryNeurons_nodonordownsamp.csv'))
- write.csv(gse_all_IN, file = paste0(resultsdirectory, '/sheets/revisions_120D/20250623_SynapticEnrich_InhibitoryNeurons_nodonordownsamp.csv'))
- # Perform GO Pathway analysis on significantly dysregulated genes
- library(msigdbr)
- library(org.Hs.eg.db)
- library(enrichplot)
- library(clusterProfiler)
- library(DOSE)
- library(simplifyEnrichment)
- library(GOSemSim)
- ## Create a vector of all gene names in count matrix to use as background set of genes
- all_genes <- as.matrix(Sanfilippo_120D_Neurons_New@assays[["RNA"]]@layers[["counts"]])
- rownames(all_genes) <- rownames(Sanfilippo_120D_Neurons_New@assays[['RNA']])
- all_genes <- row.names(all_genes)
- # Create vector of gene names that are significantly dysregulated for GO enrichment
- geneList <- dysreg_EN$hgnc_symbol
- geneList_IN <- dysreg_IN$hgnc_symbol
- test_enrichment <- enrichGO(gene = geneList, # make sure it's running for either the excitatory list or inhibitory
- OrgDb = 'org.Hs.eg.db',
- keyType = 'SYMBOL',
- ont = 'BP',
- universe = all_genes,
- pvalueCutoff = 0.05,
- pAdjustMethod = 'BH',
- qvalueCutoff = 0.1,
- minGSSize = 10,
- maxGSSize = 500,
- readable = TRUE)
- job::job({inhib_enrichment <- enrichGO(gene = geneList_IN, # to be able to run two enrichment analyses at once
- OrgDb = 'org.Hs.eg.db',
- keyType = 'SYMBOL',
- ont = 'BP',
- universe = all_genes,
- pvalueCutoff = 0.05,
- pAdjustMethod = 'BH',
- qvalueCutoff = 0.1,
- minGSSize = 10,
- maxGSSize = 500,
- readable = TRUE)})
- ## Isolate GO ID's for similarity clustering
- go_id_EN <- test_enrichment@result$ID
- job::job({go_mat <- GO_similarity(go_id_EN, ont = "BP")})
- go_id <- inhib_enrichment@result$ID
- job::job({go_mat_inhib <- GO_similarity(go_id, ont = "BP")})
- ## generate clusters using louvain clustering.
- go_cluster_louvain <- simplifyGO(go_mat_inhib, method = "louvain") ## NEED TO RUN THIS FOR INHIBITORY NEURONS AND FINISH CHORD PLOT TO UPDATE FIGURE
- test_enrichment@result$Cluster_louvain <- go_cluster_louvain$cluster[match(test_enrichment@result$ID, go_cluster_louvain$id)]
- inhib_enrichment@result$Cluster_louvain <- go_cluster_louvain$cluster[match(inhib_enrichment@result$ID, go_cluster_louvain$id)]
- enrichment_result <- as.data.frame(test_enrichment@result)
- enrichment_result <- as.data.frame(inhib_enrichment@result)
- most_common_word=function(x){
- #Split every word into single words for counting
- splitTest=unlist(strsplit(x," "))
- #Counting words
- count=table(splitTest)
- #Sorting to select only the highest value, which is the first one
- count=count[order(count, decreasing=TRUE)][1:50]
- #Return the desired character.
- #By changing this you can choose whether it show the number of times a word repeats
- return(names(count))
- }
- cluster_words <- vector("list", 12) # List to store results for each cluster
- # Loop through clusters 1 to 18
- for (i in 1:12) {
- # Subset descriptions for the current cluster
- cluster_descriptions <- test_enrichment@result[test_enrichment@result$Cluster_louvain == i,]
- # Apply most_common_word to the descriptions
- cluster_words[[i]] <- most_common_word(cluster_descriptions)
- }
- # Optionally, name the list elements for clarity
- names(cluster_words) <- paste0("Cluster_", 1:18)
- ## Add description based on pathways in the clusters and most common word function above
- # Excitatory
- test_enrichment@result$new_description <- ifelse(test_enrichment@result$Cluster_louvain == "1", "cellular differentiation and development", ifelse(test_enrichment@result$Cluster_louvain == "2", "ions and transport", ifelse(test_enrichment@result$Cluster_louvain == "3", "signaling pathways", ifelse(test_enrichment@result$Cluster_louvain == "4", "regulation and organisation", ifelse(test_enrichment@result$Cluster_louvain == "5", "regulation and organisation", ifelse(test_enrichment@result$Cluster_louvain == "6", "cellular metabolism", "other"
- ))))))
- # Inhibitory
- inhib_enrichment@result$new_description <- ifelse(inhib_enrichment@result$Cluster_louvain == "1", "cellular differentiation and development", ifelse(inhib_enrichment@result$Cluster_louvain == "2", "ions and transport", ifelse(inhib_enrichment@result$Cluster_louvain == "3", "signaling pathways", ifelse(inhib_enrichment@result$Cluster_louvain == "4", "regulation and organisation", ifelse(inhib_enrichment@result$Cluster_louvain == "5", "regulation and organisation", ifelse(inhib_enrichment@result$Cluster_louvain == "6", "cellular metabolism", "other"
- ))))))
- # Reorder by P.adjust value and save out to create table of top 5 GO IDs - Supp Fig 20E
- test_enrichment <- test_enrichment@result[order(test_enrichment@result$p.adjust),]
- inhib_enrichment <- inhib_enrichment@result[order(inhib_enrichment@result$p.adjust),]
- write.csv(test_enrichment, file = paste0(resultsdirectory, '/sheets/revisions_120D/20250604_Excitatory_neuron_DEG_PathwayAnalysis_nodonordownsample.csv'))
- enrichGO_list <- list()
- enrichGO_list$results <- data.frame("Category" = "BP","ID" = test_enrichment$Cluster_louvain, "Term" = test_enrichment$new_description, "Genes" = test_enrichment$geneID, "adj_pval" = test_enrichment$p.adjust) # swap enrichment result object between excitatory or inhibitory for cord plot visualisation
- enrichGO_list$results$Genes <- gsub("/",",",enrichGO_list$results$Genes)
- ## Make list of dysregulated genes in excitatory and inhibitory with their avglog2FC from DE analysis
- library(GOplot)
- enrichGO_list$geneList <- data.frame("ID" = rownames(dysreg_IN), "logFC" = dysreg_IN$avg_log2FC)
- circ <- circle_dat(enrichGO_list$results, enrichGO_list$geneList)
- enrichGO_list$process <- unique(circ$term)
- chord <- chord_dat(circ, enrichGO_list$geneList, enrichGO_list$process)
- chord <- chord[c(1:25, 751:755),] # Filter for the top 15 upregulated and top 15 downregulated genes
- chord <- chord[order(chord[,6], decreasing = T), ] # Order by decreasing logFC
- ## Order by different cluster descriptions
- chord <- chord[, c("cellular metabolism", "signaling pathways", "regulation and organisation", "cellular differentiation and development", "ions and transport", "logFC")] #
- ## Visualise chord plot - Fig 7D
- pdf(file = paste0(resultsdirectory,"/plots/revisions_120D/DE_120D/20250604_GOChord_top30DEgenes_upanddown_louvainclustering_inhibitoryneurons_nodonordownsample.pdf"), width = 14, height =14)
- cplot <- GOChord(chord,
- nlfc = 1,
- limit = c(0,0),
- space = 0.02,
- gene.space = 0.25,
- gene.order = "logFC",
- border.size = 0,
- ribbon.col = c("firebrick2", "orange","green3", "dodgerblue2", "deeppink"), #
- gene.size = 5,
- lfc.min = -7,
- lfc.max = 7,
- lfc.col = c("red", "grey90", "blue"))
- cplot
- dev.off()
- ```
- 7. ddressing reviewer concerns regarding BIAD03's high SOX2 iPSC expression and effect that has on phenotypes identified
- ```{Addressing reviewer concerns regarding BIAD03}
- ## Isolating excitatory neurons then performing FindMarkers on BIAD03 compared to other excitatory neurons
- Idents(Sanfilippo_120D_Neurons_New) <- 'neuron_types_ident'
- excitatory_only <- subset(Sanfilippo_120D_Neurons_New, idents = 'Sanfilippo_120D_Excitatory')
- excitatory_only <- NormalizeData(excitatory_only, assay = "RNA", normalization.method = "LogNormalize")
- # Perform DE on BIAD03 vs all MPSIIIA patients to understand unique population #
- Idents(excitatory_only) <- 'biad_id_type'
- BIAD03_unique <- FindMarkers(excitatory_only, assay = 'RNA', slot = 'data', ident.1 = "B03-cNP13_Excitatory", ident.2 = NULL, logfc.threshold = 0, min.pct = 0.1, min.diff.pct = 0.1, test.use = "wilcox")
- BIAD03_unique$hgnc_symbol <- rownames(BIAD03_unique)
- BIAD03_unique <- significantly_expressed_genes(BIAD03_unique)
- BIAD03_unique_upreg <- BIAD03_unique[which(BIAD03_unique$avg_log2FC > 0 &BIAD03_unique$p_val_adj < 0.05),] # find uniquely upregulated for GO analysis
- BIAD03_unique_downreg <- BIAD03_unique[which(BIAD03_unique$avg_log2FC < 0 &BIAD03_unique$p_val_adj < 0.05),] # find uniquely downregulated for GO analysis
- write.csv(BIAD03_unique, file = paste0(resultsdirectory, "/sheets/revisions_120D/DE_120D/20251203_DE_BIAD03-ENs_AllDonors_wilcox_nodonordownsample.csv"))
- # Volcano plot of uniquely dysregulated genes
- VP <- ggplot(BIAD03_unique, aes(avg_log2FC, log10p_adj, label=delabel, color=diffexpressed)) + geom_point(alpha = 1, size = 3, fill = "grey90") + ## transform to change the order of the plots in facet_wrap()
- theme_light() +
- scale_fill_gradientn(colours = c(rainbow(100)), ## colors in the scale
- breaks = seq(0, 1, 0.2),
- limits = c(0, 1)) +
- scale_color_manual(values = c("grey60","blue","red")) +
- geom_text_repel(data=BIAD03_unique, size = 8, max.overlaps = 75, direction = "both") +
- theme(legend.position = "right", axis.text.x = element_text(size = 28), axis.text.y = element_text(size = 28), axis.title.x = element_text(size = 30), axis.title.y = element_text(size = 30), panel.border = element_rect(fill=NA, colour = "black", size=0.5)) +
- labs(y=expression('-Log'[10]*' P'[adj]), x=expression(atop('Log'[2]*' fold change', paste("[MPSIIIA/Control]")))) +
- scale_x_continuous(breaks = seq(-7, 7, by = 2)) +
- scale_y_continuous(breaks = seq(0, 90, by = 20)) +
- coord_cartesian(xlim = c(-7, 7), ylim = c(0, 80)) +
- geom_hline(yintercept = -log10(0.05), linetype = "dashed", col = "darkgrey", size = 1) + NoLegend()
- VP
- ggsave(VP, filename = paste0(resultsdirectory,"/plots/revisions_120D/DE_120D/20251203_VP_BIAD03_ENs_GeneExpression_nodonordownsample.pdf"), height = 10, width = 10, dpi = 300)
- # pathways of DEGs for BIAD03 ENs
- library(msigdbr)
- library(org.Hs.eg.db)
- library(enrichplot)
- library(clusterProfiler)
- library(DOSE)
- library(simplifyEnrichment)
- library(GOSemSim)
- ## Create a vector of all gene names in count matrix to use as background set of genes
- all_genes <- as.matrix(excitatory_only@assays[["RNA"]]@layers[["counts"]])
- rownames(all_genes) <- rownames(excitatory_only@assays[['RNA']])
- all_genes <- row.names(all_genes)
- # Create vector of gene names that are significantly dysregulated for GO enrichment
- geneList <- BIAD03_unique_upreg$hgnc_symbol # swap this between upreg and downreg genes
- test_enrichment <- enrichGO(gene = geneList, # make sure it's running for either the excitatory list or inhibitory
- OrgDb = 'org.Hs.eg.db',
- keyType = 'SYMBOL',
- ont = 'BP',
- universe = all_genes,
- pvalueCutoff = 0.05,
- pAdjustMethod = 'BH',
- qvalueCutoff = 0.1,
- minGSSize = 10,
- maxGSSize = 500,
- readable = TRUE)
- go_id <- test_enrichment@result$ID
- GO_pathways <- dotplot(test_enrichment, showCategory = 20)
- GO_pathways
- ggsave(GO_pathways, filename = paste0(resultsdirectory,"/plots/revisions_120D/DE_120D/20251207_BIAD03_Pathways-upregDEGs.pdf"), height = 10, width = 7, dpi = 300)
- ## SOX2 expression per donor
- cortical_mark <- c("SOX2")
- control_matrix <- GetAssayData(object = Sanfilippo_120D,
- assay = "RNA",
- layer = "counts")
- control_matrix <- as.matrix(control_matrix)
- control_matrix <- control_matrix[cortical_mark,, drop = F]
- control_matrix <- as.data.frame(t(control_matrix))
- control_matrix$BIAD_id[match(rownames(control_matrix), rownames([email hidden]))] <- Sanfilippo_120D$BIAD_id[match(rownames(control_matrix),rownames([email hidden]))]
- control_matrix$condition[match(rownames(control_matrix), rownames([email hidden]))] <- Sanfilippo_120D$orig.ident[match(rownames(control_matrix),rownames([email hidden]))]
- MPSIIIA_matrix <- control_matrix[control_matrix$condition == "Sanfilippo_120D",]
- control_matrix <- control_matrix[control_matrix$condition == "Control_120D",]
- control_matrix_noexp <- control_matrix[rowSums(control_matrix[1]) == 0,]
- MPSIIIA_matrix_noexp <- MPSIIIA_matrix[rowSums(MPSIIIA_matrix[1]) == 0,]
- SOX2_gene_prop <- data.frame("Control_Number" = colSums(control_matrix > 0), "Control_Percent" = (colSums(control_matrix > 0)/nrow(control_matrix))*100,"MPSIIIA_Number" = colSums(MPSIIIA_matrix > 0), "MPSIIIA_Percent" = (colSums(MPSIIIA_matrix > 0)/nrow(MPSIIIA_matrix))*100)
- control_gene_prop_per_donor <- control_matrix |>
- group_by(BIAD_id) |>
- summarize(n = n(),
- across(-n, ~sum(. > 0)))
- control_gene_prop_per_donor$pct_expressing <- (control_gene_prop_per_donor$SOX2/control_gene_prop_per_donor$n)*100
- control_gene_prop_per_donor$condition <- "Healthy"
- control_gene_prop_per_donor$DIV <- "120D"
- MPSIIIA_gene_prop_per_donor <- MPSIIIA_matrix |>
- group_by(BIAD_id) |>
- summarize(n = n(),
- across(-n, ~sum(. > 0)))
- MPSIIIA_gene_prop_per_donor$pct_expressing <- (MPSIIIA_gene_prop_per_donor$SOX2/MPSIIIA_gene_prop_per_donor$n)*100
- MPSIIIA_gene_prop_per_donor$condition <- "MPSIIIA"
- MPSIIIA_gene_prop_per_donor$DIV <- "120D"
- av_exp_120D <- AggregateExpression(Sanfilippo_120D, features = "SOX2", group.by = c("BIAD_id"), assays = "RNA", slot = "counts")
- av_exp_120D <- as.data.frame(t(av_exp_120D$RNA))
- colnames(av_exp_120D) <- "SOX2_sum_exp"
- av_exp_120D$BIAD_id <- rownames(av_exp_120D)
- cortical_gene_prop_per_donor <- rbind(control_gene_prop_per_donor, MPSIIIA_gene_prop_per_donor)
- rownames(cortical_gene_prop_per_donor) <- cortical_gene_prop_per_donor$BIAD_id
- cortical_gene_prop_per_donor <- merge(cortical_gene_prop_per_donor, av_exp_120D, by = "BIAD_id")
- write.csv(cortical_gene_prop_per_donor, file = paste0(resultsdirectory, "/sheets/revisions_120D/Control_MPSIIIA_neurons_cortical_SOX2gene_prop_per_donor_nodownsample.csv"))
- ```
- 6. ***Look at proportion of neurons at 30DIV to address reviewer concerns about uneven proportions at 120D***
- ```{Assessing expression of key synaptic genes in 30DIV data}
- ### LOAD 30 DAY DATA ###
- ## Load required datasets
- load(file = paste0(datadirectory, "/RData/30D/Combined_Control_MPSIIIA_30D.RData"))
- tbl <- [email hidden] %>% group_by(orig.ident) %>% summarise(n = n())
- tbl
- Idents(Combined_Healthy_MPSIIIA) <- 'orig.ident'
- Combined_Healthy_MPSIIIA <- subset(Combined_Healthy_MPSIIIA, downsample = 4444)
- [email hidden] %>% group_by(orig.ident) %>% summarise(n = n())
- # Sort into excitatory and inhibitory neurons
- Combined_30D_neurons <- subset(Combined_Healthy_MPSIIIA, idents = c('Control_30D', 'Sanfilippo_30D'))
- table(Combined_30D_neurons$orig.ident)
- Idents(Combined_30D_neurons) <- "final_cell_type"
- Combined_30D_neurons <- subset(Combined_30D_neurons, idents = c('Excitatory', 'Inhibitory'))
- Idents(Combined_30D_neurons) <- 'orig.ident'
- Combined_30D_neurons <- subset(Combined_30D_neurons, downsample = 1952)
- # Donor proportions for excitatory and inhibitory neurons - Supp Fig 20A #
- tbl <- [email hidden] %>% group_by(orig.ident, BIAD_id, final_cell_type) %>% summarise(n = n())
- tbl
- write.csv(tbl, file = paste0(resultsdirectory, "/sheets/revisions_120D/DE_120D/20250612_30DIV_neuron-types_biad-id_nodwonsample.csv"))
- ```
Differential_Expression_Analysis_120D.Rmd at commit 04a5121, no license · at the source
Overview
- Laboratory for Human Neurophysiology and Genetics, South Australian Health and Medical Research Institute (SAHMRI),Adelaide, SA Australia
- Flinders Health and Medical Research Institute, College of Medicine and Public Health, Flinders University,Adelaide, SA Australia
- Sanfilippo Children’s Foundation, Sydney, NSW Australia
- Childhood Dementia Initiative, Sydney, NSW Australia
- School of Biomedicine, Adelaide University,Adelaide, SA Australia
- Institute for Photonic and Advanced Sensing, Adelaide University,Adelaide, SA Australia
- Cure Sanfilippo Foundation, Columbia, SC USA
- Department of Neurology and Clinical Neurophysiology, Women’s and Children’s Health Network,Adelaide, SA Australia
- Paediatric Neurodegenerative Disease Research Group, Discipline of Paediatrics, College of Health, Adelaide University,Adelaide, SA Australia
- Brain Organoid Therapeutics, Adelaide, SA Australia
Abstract
The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.
Repository
Its files are read in the Code ↔ Paper reader above, with 13 matches between paragraphs and lines of code.
bardylab/MPSIIIA_snRNAseq_Synaptic_Paper_2026
04a512141b0b5beeb0fe7b925e8b3186311d53a9, 12 February 2026Availability: 1 check, the latest on 29 September 2026: the link answers
- 29 September 2026: the link answers
4 files
- Rscripts/
Differential_Expression_ , R, 929 lines, 5 matchesAnalysis_120D.Rmd - Rscripts/
Neuronal_Glial_Types_Ana , R, 968 lines, 5 matcheslysis_120D.Rmd - Rscripts/
QualityControl_120Day.Rm , R, 323 lines, 3 matchesd - README.md, Text, 70 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: bardylab/
MPSIIIA_snRNAseq_Synapti c_Paper_2026
Read it in the paper: doi.org/10.1038/s41467-026-71112-9.
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;
- 3 scripts, each with its path and the digest of its content;
- 13 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
No dataset and no data link were found in the paper.
Data availability statement
The paper has a data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:
- it says that the data are available on request
Read it in the paper: doi.org/10.1038/s41467-026-71112-9.
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, 29 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 20 authors, 5 keywords, 10 MeSH terms, 2 funders, 128 references.
Cite
This paper
Mazzachi, P., McDonald, E., Greenberg, Z., Puerta, A. N., Tran, J., De Silva, M. I., Christensen, C., Adams, R., Loskarn, S., Beard, H., Zabolocki, M., Elmasri, M., Maack, M., Elvidge, K. L., Hutchinson, M. R., O’Neill, C., Hemsley, K. M., Melton, L., Smith, N., & Bardy, C. (2026). Modelling synaptic dysfunction in childhood dementia using human iPSC-derived cortical networks. Nature communications, 17(1), 3161. https://
BibTeX
@article{mazzachi2026mod
author = {Mazzachi, Paris and McDonald, Ella and Greenberg, Zarina and Puerta, Alejandra Noreña and Tran, Jenne and De Silva, Manam Inushi and Christensen, Cade and Adams, Robert and Loskarn, Sebastian and Beard, Helen and Zabolocki, Michael and Elmasri, Meera and Maack, Megan and Elvidge, Kristina L. and Hutchinson, Mark R. and O’Neill, Cara and Hemsley, Kim M. and Melton, Lisa and Smith, Nicholas and Bardy, Cedric},
title = {{Modelling synaptic dysfunction in childhood dementia using human iPSC-derived cortical networks}},
journal = {Nature communications},
year = {2026},
month = apr,
volume = {17},
number = {1},
pages = {3161},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/
url = {https://
pmid = {41946741},
pmcid = {PMC13057175}
}
RIS
TY - JOUR
AU - Mazzachi, Paris
AU - McDonald, Ella
AU - Greenberg, Zarina
AU - Puerta, Alejandra Noreña
AU - Tran, Jenne
AU - De Silva, Manam Inushi
AU - Christensen, Cade
AU - Adams, Robert
AU - Loskarn, Sebastian
AU - Beard, Helen
AU - Zabolocki, Michael
AU - Elmasri, Meera
AU - Maack, Megan
AU - Elvidge, Kristina L.
AU - Hutchinson, Mark R.
AU - O’Neill, Cara
AU - Hemsley, Kim M.
AU - Melton, Lisa
AU - Smith, Nicholas
AU - Bardy, Cedric
TI - Modelling synaptic dysfunction in childhood dementia using human iPSC-derived cortical networks
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/
VL - 17
IS - 1
SP - 3161
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1038/
"type": "article-journal",
"title": "Modelling synaptic dysfunction in childhood dementia using human iPSC-derived cortical networks",
"container-title": "Nature communications",
"author": [
{
"family": "Mazzachi",
"given": "Paris"
},
{
"family": "McDonald",
"given": "Ella"
},
{
"family": "Greenberg",
"given": "Zarina"
},
{
"family": "Puerta",
"given": "Alejandra Noreña"
},
{
"family": "Tran",
"given": "Jenne"
},
{
"family": "De Silva",
"given": "Manam Inushi"
},
{
"family": "Christensen",
"given": "Cade"
},
{
"family": "Adams",
"given": "Robert"
},
{
"family": "Loskarn",
"given": "Sebastian"
},
{
"family": "Beard",
"given": "Helen"
},
{
"family": "Zabolocki",
"given": "Michael"
},
{
"family": "Elmasri",
"given": "Meera"
},
{
"family": "Maack",
"given": "Megan"
},
{
"family": "Elvidge",
"given": "Kristina L."
},
{
"family": "Hutchinson",
"given": "Mark R."
},
{
"family": "O’Neill",
"given": "Cara"
},
{
"family": "Hemsley",
"given": "Kim M."
},
{
"family": "Melton",
"given": "Lisa"
},
{
"family": "Smith",
"given": "Nicholas"
},
{
"family": "Bardy",
"given": "Cedric"
}
],
"container-title-short":
"volume": "17",
"issue": "1",
"page": "3161",
"DOI": "10.1038/
"PMID": "41946741",
"PMCID": "PMC13057175",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
7
]
]
}
}
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/s41467-026-76837-1 [code]
- Drug screen and machine learning predict neuroprotective agents in a preclinical human model of childhood dementia.Journal: Nature communicationsIn common: Harmony, clusterProfiler, Seurat, 3 other tools, Alzheimer's / dementia, 34 references, 13 authors
- [2] doi:10.1093/bib/bbag175 [code]
- Uncovering causal relationships in single-cell omic studies with causarray.Journal: Briefings in bioinformaticsIn common: Harmony, clusterProfiler, Seurat, 4 other tools, Alzheimer's / dementia, 2 references
- [3] doi:10.1038/s41467-026-71595-6 [code]
- A single-cell and spatial atlas of early human olfactory development.Journal: Nature communicationsIn common: Harmony, Seurat, patchwork, 2 other tools, 4 references
- [4] 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: Harmony, clusterProfiler, Seurat, 4 other tools, Alzheimer's / dementia, cellular / molecular, 2 references
- [5] doi:10.1038/s41586-026-10877-x [code]
- Human brain organoids record the passage of time over multiple years.Journal: NatureIn common: Harmony, Seurat, data.table, 2 other tools, 4 references
- [6] doi:10.1002/alz.71823 [code]
- Cellular transcriptomic signatures underpinning the heterogeneity of depression in Alzheimer's disease.Journal: Alzheimer's & dementia : the journal of the Alzheimer's AssociationIn common: Harmony, Seurat, data.table, 3 other tools, Alzheimer's / dementia, cellular / molecular, 2 references
- [7] doi:10.1038/s41586-026-10214-2 [code]
- Multidimensional profiling of heterogeneity in supratentorial ependymomas.Journal: NatureIn common: Harmony, clusterProfiler, Seurat, 4 other tools, 2 references
- [8] 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: Harmony, clusterProfiler, Seurat, 4 other tools, cellular / molecular, 1 reference
- [9] doi:10.1038/s41467-026-69944-6 [code]
- Multi-modal dissection of cell-type specific TDP-43 pathology in the motor cortex.Journal: Nature communicationsIn common: clusterProfiler, Seurat, data.table, 3 other tools, 2 references
- [10] 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: Harmony, clusterProfiler, Seurat, 4 other tools, 1 reference
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, 3 scripts, and 13 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:0cb5da4d0d6bf760…
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.
