1 Introduction

The ASOC Bioinformatics team generated this QC report, which includes stats and diagnostic plots of the GeoMx Digital Spatial (DSP) data.

This report was generated to support Dr. Jonathan Epp's talk at the Spatial Omics Seminar on November 7th, 2024, entitled "Impaired Parvalbumin Interneurons in the Retrosplenial Cortexas the Root of Sex-Dependent Vulnerability in Alzheimer's Disease." The workflow was revised from the original analysis to deliver step-by-step quality assessment and better visualization during the seminar.

2 Prerequisite

2.1 Environment

  • OS: macOS Sequoia 15.0.1
  • Platform: aarch64-apple-darwin20 (64-bit)
  • Software: R (v4.4.1)
  • Pakcages:
    • NanoStringNCTools (v1.12.0)
    • GeoMxWorkflows (v1.10.0)
    • GeomxTools (v3.8.0)
    • stringr (v1.5.1)
    • dplyr (v1.1.4)
    • scales (v1.3.0)
    • ggplot2 (v3.5.1)
    • ggsankey (v0.0.99999)
    • plotly (v4.10.4)
    • reshape2(v1.4.4)
    • EnvStats (v3.0.0)
    • DescTools (v0.99.56)
    • RColorBrewer(v1.1-3)

2.2 GeoMx DSP Data

  • Group: 5xFAD TG (transgenic) â—¼ and WT (wild-type) â—¼ mice
  • Sex/Slide: Male â—¼ (slide #1) and Female â—¼ (#2)
  • Model, N=15:
    • TG-Males (blues), N=4: TG1M (transgenic mice 1, male) â—¼, TG2M â—¼, TG3M â—¼, and TG4M â—¼
    • TG-Females (greens), N=4: TG1F â—¼, TG2F â—¼, TG3F â—¼, and TG4F â—¼
    • WT-Males (reds), N=4: WT1M â—¼, WT2M â—¼, WT3M â—¼, and WT4M â—¼
    • WT-Females (pruples), N=3: WT1F â—¼, WT2F â—¼, and WT3F â—¼
  • Segment: PV (interneurons) â—¼, NeuN (neuron) â—¼, Amyloid â—¼, and TN (triple-negative) â—¼
  • Files: Annotation.xlsx, DCC files, and PKC file are under the Annot, DCC, and PKC folders, respectivley
WORKING_DIRECTORY
├── Annot
│   └── Annotation.xlsx
├── DCC
│   ├── DSP-*-?-???.dcc
└── PKC
    └── *.pkc

3 Preprocessing/QC

3.1 Preparation

  • Set working directory to load files
# Do not run
baseDir <- "WORKING_DIRECTORY" # where the Annot/DCC/PKC/Settings folders are located
setwd(baseDir)
library(NanoStringNCTools)
library(GeoMxWorkflows)
library(GeomxTools)
library(stringr)
library(dplyr)
library(scales)
library(ggplot2)
library(ggsankey)
library(plotly)
library(reshape2)
library(EnvStats)
library(DescTools)
library(RColorBrewer)

3.2 Compile a GeoMx object (Step 1)

  • Import DCC/PKC/Annotation files and export to a GeoMx object, e.g., geomxSet.RDS
dccFiles <- dir(file.path(baseDir, "DCC"), pattern = ".dcc$", full.names = TRUE, recursive = TRUE)
pkcFile <- dir(file.path(baseDir, "PKC"), pattern = ".pkc$", full.names = TRUE, recursive = TRUE)
annotFile <- dir(file.path(baseDir, "Annot"), pattern = ".xlsx$", full.names = TRUE, recursive = TRUE)
initSet <- readNanoStringGeoMxSet(
        dccFiles = dccFiles,
        pkcFiles = pkcFile,
        phenoDataFile = annotFile,
        phenoDataSheet = "Annotation",
        phenoDataDccColName = "FileName",
        protocolDataColNames = c("ROI", "AOI"),
        experimentDataColNames = c("Panel")
)

dim(initSet)
## Features  Samples 
##    20175       95
assayData(initSet)$exprs[c(4:8), c(8:10)]
##            DSP-1001660023394-A-A09.dcc DSP-1001660023394-A-A10.dcc
## RTS0060890                         214                           1
## RTS0060891                         129                           0
## RTS0060892                         128                           0
## RTS0060893                         104                           0
## RTS0060894                         291                           1

3.3 Assign a pseudo value (Step 2)

  • Shift any expression counts with a value of zero (0) to one (1) to enable in downstream transformations
gSet <- shiftCountsOne(initSet, useDALogic = TRUE)
assayData(gSet)$exprs[c(4:8), c(8:10)]
##            DSP-1001660023394-A-A09.dcc DSP-1001660023394-A-A10.dcc
## RTS0060890                         214                           1
## RTS0060891                         129                           1
## RTS0060892                         128                           1
## RTS0060893                         104                           1
## RTS0060894                         291                           1

3.4 Segment QC (Step 3)

  • Assess sequencing quality and adequate tissue sampling for every ROI/AOI segment
    • Any segments below the dotted line, i.e., recommended thresholds, will be filtered out
    • Row: Slide, Column: Segment
module <- gsub(".pkc", "", annotation(gSet))

gSet <- setSegmentQCFlags(gSet, qcCutoffs = segmentQcParams)
qcMat <- sData(gSet)
qcMat$Segment <- factor(qcMat$Segment, levels = segmentOrder)
qcMat$Slide <- factor(qcMat$Slide, levels = slideOrder)
histQC(qcMat, "Trimmed (%)", segmentQC_colBy, segmentQC_rowBy, segmentQC_trimmedThre, cols = segmentCols)

histQC(qcMat, "Stitched (%)", segmentQC_colBy, segmentQC_rowBy, segmentQC_stitchedThre, cols = segmentCols)

histQC(qcMat, "Aligned (%)", segmentQC_colBy, segmentQC_rowBy, segmentQC_alignedThre, cols = segmentCols)

histQC(qcMat, "Saturated (%)", segmentQC_colBy, segmentQC_rowBy, segmentQC_saturatedThre, cols = segmentCols)

histQC(qcMat, "area", segmentQC_colBy, segmentQC_rowBy, segmentQC_areaThre, "log10", "AOI Area (log10)", cols = segmentCols)

histQC(qcMat, "nuclei", segmentQC_colBy, segmentQC_rowBy, segmentQC_nucleiThre, "log10", "AOI nuclei count", cols = segmentCols)

segmentQcResults <- protocolData(gSet)[["QCFlags"]]
flagColumns <- colnames(segmentQcResults)
qcSummary <- data.frame(Pass = colSums(!segmentQcResults[, flagColumns]), Warning = colSums(segmentQcResults[, flagColumns]))
segmentQcResults$QCStatus <- apply(segmentQcResults, 1L, function(x) {
        ifelse(sum(x) == 0L, "PASS", "WARNING")
})
qcSummary["TOTAL FLAGS", ] <- c(sum(segmentQcResults[, "QCStatus"] == "PASS"), sum(segmentQcResults[, "QCStatus"] == "WARNING"))
qcSummary[, "TOTAL"] <- apply(qcSummary, 1, sum)
qcSummary
##               Pass Warning TOTAL
## LowReads        95       0    95
## LowTrimmed      94       1    95
## LowStitched     94       1    95
## LowAligned      95       0    95
## LowSaturation   95       0    95
## LowNegatives    95       0    95
## LowNuclei       95       0    95
## LowArea         94       1    95
## TOTAL FLAGS     93       2    95
gSet <- gSet[, segmentQcResults$QCStatus == "PASS"]
dim(gSet)
## Features  Samples 
##    20175       93

3.5 Background signal (Step 4)

  • Calculate negative count which is the geometric mean of the several unique negative probes in the GeoMx panel that do not target mRNA and establish the background count level per segment
negCol <- "NegGeoMean"

negativeGeoMeans <- esBy(
        negativeControlSubset(gSet),
        GROUP = "Module",
        FUN = function(x) {
                assayDataApply(x, MARGIN = 2, FUN = ngeoMean, elt = "exprs")
        }
)
protocolData(gSet)[[negCol]] <- negativeGeoMeans
pData(gSet)[, negCol] <- sData(gSet)[[negCol]]

backgrounMat <- sData(gSet)
backgrounMat <- backgrounMat[, c("NegGeoMean", segmentQC_colBy, segmentQC_rowBy)]
backgrounMat$Segment <- factor(backgrounMat$Segment, levels = segmentOrder)
backgrounMat$Slide <- factor(backgrounMat$Slide, levels = slideOrder)
histQC(backgrounMat, "NegGeoMean", segmentQC_colBy, segmentQC_rowBy, loqCutoff, "log10", "GeoMean(negative probes)", cols = segmentCols)

3.6 Probe-level QC (Step 5)

  • Remove low-performing probes. In short, this QC is an outlier removal process, whereby probes are either removed entirely from the study (global) or from specific segments (local)
gSet <- setBioProbeQCFlags(gSet, qcCutoffs = probeQcParams, removeLocalOutliers = FALSE)
probeQcResults <- fData(gSet)[["QCFlags"]]

qcDf <- data.frame(
        Global_outlier = length(which(fData(gSet)[["QCFlags"]][, c("GlobalGrubbsOutlier")] == TRUE)),
        Local_outlier = length(which(fData(gSet)[["QCFlags"]][, c("LowProbeRatio")] == TRUE)) 
)
qcDf
##   Global_outlier Local_outlier
##                0             0
probeQcPassed <- subset(
        gSet,
        fData(gSet)[["QCFlags"]][, c("LowProbeRatio")] == FALSE &
                fData(gSet)[["QCFlags"]][, c("GlobalGrubbsOutlier")] == FALSE
)
gSet <- probeQcPassed
dim(gSet)
## Features  Samples 
##    20175       93

3.7 Gene-level aggregation (Step 6)

  • Generate a gene-level count matrix where the count for any gene with multiple probes per segment is calculated as the geometric mean of those probes
newSet <- aggregateCounts(gSet)
newSet <- subset(newSet, fData(newSet)$TargetName != "NegProbe-WTX") # Remove negative probe in downstream analysis
dim(newSet)
## Features  Samples 
##    19962       93

3.8 Segment QC (Step 7)

3.8.1 Relationship between Area and Number of Nuclei

  • Check the AOI area and the number of nuclei estimated
lowLvqcDf <- data.frame(
        Slide = pData(newSet)$Slide,
        Group = pData(newSet)$Group,
        Model = pData(newSet)$Model,
        Sex = pData(newSet)$Sex,
        Library = pData(newSet)$Library,
        Segment = pData(newSet)$Segment,
        Area = pData(newSet)$area,
        Nuclei = pData(newSet)$nuclei
)
lowLvqcDf$Slide <- factor(lowLvqcDf$Slide, levels=slideOrder)
lowLvqcDf$Group <- factor(lowLvqcDf$Group, levels=groupOrder)
lowLvqcDf$Model <- factor(lowLvqcDf$Model, levels=modelOrder)
lowLvqcDf$Sex <- factor(lowLvqcDf$Sex, levels=sexOrder)
lowLvqcDf$Segment <- factor(lowLvqcDf$Segment, levels=segmentOrder)

dodge <- position_dodge(width = 0.5)
ggplot(data = lowLvqcDf, aes(x = Slide, y = Area, fill = Slide)) +
        geom_violin(position = dodge, size = 0) +
        geom_boxplot(width = 0.1, position = dodge, fill="white") +
        scale_fill_manual(values = slideCols) +
        labs(
                title = "",
                x = "", 
                y = "Area"
        ) +
        theme_bw() +
        theme(
                axis.line = element_line(colour = "black"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                legend.position = "none", 
                text = element_text(size = 12)
        ) + 
        scale_y_continuous(trans = "log10")

ggplot(data = lowLvqcDf, aes(x = Slide, y = Nuclei, fill = Slide)) +
        geom_violin(position = dodge, size = 0) +
        geom_boxplot(width = 0.1, position = dodge, fill="white") +
        scale_fill_manual(values = slideCols) +
        labs(
                title = "",
                x = "", 
                y = "#Nuclei"
        ) +
        theme_bw() +
        theme(
                axis.line = element_line(colour = "black"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                legend.position = "none", 
                text = element_text(size = 12)
        ) + 
        scale_y_continuous(trans = "log10")

scatterPlot <- ggplot(data = lowLvqcDf, aes(x = Area, y = Nuclei, color = Group, label = Library)) +
        geom_point() +
        scale_color_manual(values = groupCols) +
        labs(
                title = "",
                x = "Area", 
                y = "#Nuclei"
        ) +
        theme_bw() +
        theme(
                axis.line = element_line(colour = "black"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                text = element_text(size = 12)
        ) + 
        scale_x_continuous(trans = "log10") + 
        scale_y_continuous(trans = "log10")
ggplotly(scatterPlot)
scatterPlot <- ggplot(data = lowLvqcDf, aes(x = Area, y = Nuclei, color = Model, label = Library)) +
        geom_point() +
        scale_color_manual(values = modelCols) +
        labs(
                title = "",
                x = "Area", 
                y = "#Nuclei"
        ) +
        theme_bw() +
        theme(
                axis.line = element_line(colour = "black"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                text = element_text(size = 12)
        ) + 
        scale_x_continuous(trans = "log10") + 
        scale_y_continuous(trans = "log10")
ggplotly(scatterPlot)
scatterPlot <- ggplot(data = lowLvqcDf, aes(x = Area, y = Nuclei, color = Sex, label = Library)) +
        geom_point() +
        scale_color_manual(values = sexCols) +
        labs(
                title = "",
                x = "Area", 
                y = "#Nuclei"
        ) +
        theme_bw() +
        theme(
                axis.line = element_line(colour = "black"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                text = element_text(size = 12)
        ) + 
        scale_x_continuous(trans = "log10") + 
        scale_y_continuous(trans = "log10")
ggplotly(scatterPlot)
scatterPlot <- ggplot(data = lowLvqcDf, aes(x = Area, y = Nuclei, color = Segment, label = Library)) +
        geom_point() +
        scale_color_manual(values = segmentCols) +
        labs(
                title = "",
                x = "Area", 
                y = "#Nuclei"
        ) +
        theme_bw() +
        theme(
                axis.line = element_line(colour = "black"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                text = element_text(size = 12)
        ) + 
        scale_x_continuous(trans = "log10") + 
        scale_y_continuous(trans = "log10")
ggplotly(scatterPlot)

3.8.2 Calculate LOQ (limit of quantification)

  • Determine the LOQ where the LOQ is calculated based on the distribution of negative control probes and is intended to approximate the quantifiable limit of gene expression per segment
loqDf <- data.frame(row.names = colnames(newSet))

varNames <- paste0(c("NegGeoMean_", "NegGeoSD_"), module)
if (all(varNames[1:2] %in% colnames(pData(newSet)))) {
        loqDf[, module] <- pData(newSet)[, varNames[1]] * (pData(newSet)[, varNames[2]]^loqCutoff)
}

statDf <- data.frame(
        Slide = pData(newSet)$Slide,
        Library = protocolData(newSet)$AOI,
        Segment = pData(newSet)$Segment,
        LOQ = loqDf[, 1]
)
statDf <- statDf[order(statDf$LOQ), ]
statDf$Slide <- factor(statDf$Slide, levels=slideOrder)
statDf$Segment <- factor(statDf$Segment, levels = segmentOrder)
statDf$Library <- factor(statDf$Library, levels = statDf$Library)

dodge <- position_dodge(width = 0.5)
suppressWarnings({
        ggplot(data = statDf, aes(x = Slide, y = log10(LOQ), fill = Slide)) +
                geom_violin(position = dodge, size = 0) +
                geom_boxplot(width = 0.1, position = dodge, fill = "white") +
                scale_fill_manual(values = slideCols) +
                labs(
                        title = "",
                        x = "Slide",
                        y = "LOQ, log10"
                ) +
                theme_bw() +
                theme(
                        axis.line = element_line(colour = "black"),
                        panel.grid.major = element_blank(),
                        panel.grid.minor = element_blank(),
                        panel.border = element_blank(),
                        panel.background = element_blank(),
                        axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 0),
                        legend.position = "none",
                        text = element_text(size = 12)
                ) +
                geom_hline(aes(yintercept = log10(loqMin)), lty = 2, col = "grey50")
})

loqDf[loqDf < loqMin] <- loqMin
pData(newSet)$LOQ <- loqDf

loqMat <- t(esApply(newSet, MARGIN = 1, FUN = function(x) {
        x > LOQ[, module]
}))
loqMat <- loqMat[fData(newSet)$TargetName, ] # Ordering

3.8.3 Segment gene detection

  • Filter out segments with exceptionally low signal that have a small fraction of panel genes detected above the LOQ relative to the other segments in the study
pData(newSet)$GenesDetected <- colSums(loqMat, na.rm = TRUE)
pData(newSet)$GeneDetectionRate <- pData(newSet)$GenesDetected / nrow(newSet)
pData(newSet)$DetectionThreshold <- cut(pData(newSet)$GeneDetectionRate, breaks = geneDetectionRateBins, labels = geneDetectionRateBinLabels)

rateMat <- pData(newSet)
rateMat$Slide <- factor(rateMat$Slide, levels = slideOrder)
rateMat$Segment <- factor(rateMat$Segment, levels = segmentOrder)
suppressWarnings({
        ggplot(rateMat, aes(x = DetectionThreshold)) +
                geom_bar(aes(fill = Segment)) +
                geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5) +
                scale_fill_manual(values = segmentCols) +
                theme_bw() +
                theme(
                        axis.line = element_line(colour = "black"),
                        panel.background = element_blank(),
                        axis.text.x = element_text(angle = 90, vjust = 0, hjust = 0),
                        text = element_text(size = 12),
                        legend.position = "none"
                ) +
                scale_y_continuous(expand = expansion(mult = c(0, 0.1))) +
                labs(
                        x = "Gene Detection Rate",
                        y = "Number of Segments"
                ) +
                facet_grid(as.formula(paste("~", segmentQC_colBy)))
})

statDf <- data.frame(
        Slide = pData(newSet)$Slide,
        AOI = protocolData(newSet)$AOI,
        Segment = pData(newSet)$Segment,
        GenesDetected = colSums(loqMat, na.rm = TRUE),
        Nuclei = pData(newSet)$nuclei
)
statDf$Slide <- factor(statDf$Slide, slideOrder)
statDf$Segment <- factor(statDf$Segment, segmentOrder)

for (segment in segmentOrder) {
        tmpDf <- statDf[which(statDf$Segment == segment), ]
        tmpDf <- tmpDf[order(tmpDf$GenesDetected, decreasing = F), ]
        tmpDf$AOI <- factor(tmpDf$AOI, levels = tmpDf$AOI)
        barplot <- ggplot(tmpDf, aes(x = AOI, y = GenesDetected, fill = Slide)) +
                geom_bar(stat = "identity") +
                scale_fill_manual(values = slideCols) +
                theme_minimal() +
                labs(
                        title = "",
                        x = "AOI"
                ) +
                coord_flip() +
                theme_bw() +
                theme(
                        axis.line = element_line(colour = "black"),
                        panel.grid.major = element_blank(),
                        panel.grid.minor = element_blank(),
                        panel.border = element_blank(),
                        panel.background = element_blank(),
                        axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0),
                        legend.position = "none"
                ) +
                scale_x_discrete(guide = guide_axis(check.overlap = TRUE))
        print(barplot)
        rm(barplot)
}

newSet <- newSet[, pData(newSet)$GeneDetectionRate >= geneDetectionRateThre]
dim(newSet)
## Features  Samples 
##    19962       52

3.8.4 Gene detection rate

  • Determine the detection rate for genes across the study where individual genes are detected to varying degrees in the segments. In other words, we will calculate the total number of genes detected in different percentages of segments to filter out low detected genes
loqMat <- loqMat[, colnames(newSet)]
fData(newSet)$DetectedSegments <- rowSums(loqMat, na.rm = TRUE)
fData(newSet)$DetectionRate <- fData(newSet)$DetectedSegments / nrow(pData(newSet))

geneDetectionRateDf <- data.frame(
        Gene = rownames(newSet),
        Number = fData(newSet)$DetectedSegments,
        DetectionRate = percent(fData(newSet)$DetectionRate)
)
geneDetectionRateDf <- geneDetectionRateDf[order(geneDetectionRateDf$Number, geneDetectionRateDf$DetectionRate, geneDetectionRateDf$Gene), ]

finalSet <- newSet[fData(newSet)$DetectionRate >= geneDetectionRateThre, ]
dim(finalSet)
## Features  Samples 
##     6875       52

3.9 Normalization (Step 8)

  • Raw count
annot <- pData(finalSet)

segmentIdx <- c()
for (segment in segmentOrder) segmentIdx <- c(segmentIdx, which(annot$Segment == segment))

rawMat <- assayData(finalSet)$exprs
colnames(rawMat) <- annot$Library
rawDf <- melt(rawMat)
colnames(rawDf) <- c("Gene", "Slide", "Expression")
rawDf$Segment <- rep(annot$Segment, each=nrow(rawMat))
rawDf$Segment <- factor(rawDf$Segment, levels = segmentOrder)

boxplot(log10(rawMat[, segmentIdx] + 1), col = segmentCols[annot$Segment][segmentIdx], names = sapply(str_split(colnames(rawMat), "-"), "[[", 2)[segmentIdx], pch = 20, xlab = "", ylab = "Raw count, log10", las = 3)

  • Upper-quartile (Q3) normalization method estimates a normalization factor per segment to bring the segment data distributions together
finalSet <- normalize(finalSet, norm_method = "quant", desiredQuantile = .75, toElt = "q_norm")
saveRDS(finalSet, file.path(outDir, "02_finalSet.GeoMx.RDS"))

normMat <- assayData(finalSet)$q_norm
colnames(normMat) <- annot$Library

normDf <- melt(normMat)
colnames(normDf) <- c("Gene", "Slide", "Expression")
normDf$Segment <- rep(annot$Segment, each=nrow(rawMat))
normDf$Segment <- factor(normDf$Segment, levels = segmentOrder)

boxplot(log10(normMat[, segmentIdx] + 1), col = segmentCols[annot$Segment][segmentIdx], names = sapply(str_split(colnames(rawMat), "-"), "[[", 2)[segmentIdx], pch = 20, xlab = "", ylab = "Upper-quartile norm, log10", las=3)

3.10 QC Summary

  • The number of features, i.e., probe or gene, and samples
Dataset #Samples #Features
Initial 95 20175
After QC (analysis-ready) 52 6875
  • Study design after QC
countDf <- pData(finalSet) %>% make_long(Sex, Model, Segment)
ggplot(countDf, aes(x = x, next_x = next_x, node = node, next_node = next_node, fill = factor(node), label = node)) +
        geom_sankey(flow.alpha = .6, node.color = "gray30") +
        geom_sankey_label(size = 3, color = "black", fill = "white") +
        scale_fill_viridis_d(option = "A", alpha = 0.95) +
        theme_sankey(base_size = 18) +
        labs(
                x = NULL, 
                y = NULL
        ) +
        theme_bw() +
        theme(
                axis.line = element_blank(),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(),
                panel.background = element_blank(),
                axis.text.x = element_text(angle = 0, vjust = 0, hjust = 0.5),
                axis.ticks.x = element_blank(),
                axis.text.y = element_blank(),
                axis.ticks.y = element_blank(),
                legend.position = "none", 
                text = element_text(size = 12)
        )

  • QC parameters used in this report
Step Filter name Threshold Description
SegmentQC minSegmentReads 1000 Minimum number of reads
percentTrimmed 80 Minimum % of reads trimmed
percentStitched 80 Minimum % of reads stitched
percentAligned 75 Minimum % of reads aligned
percentSaturation 50 Minimum sequencing saturation (%)
minNuclei 20 Minimum number of nuclei estimated
minArea 1000 Minimum segment area
ProbeQC minProbeRatio 0.1 Geometric mean of a given probe / geometric mean of all probe
percentFailGrubbs 20 An outlier according to the Grubb’s test (%)
LOQ loqCutoff 2 LOQ cut off value
loqMin 2 LOQ minimum value
GeneQC geneDetectionRateThre 0.1 Minimum gene detection rate
  • Dev environment
sessionInfo()
## R version 4.4.1 (2024-06-14)
## Platform: aarch64-apple-darwin20
## Running under: macOS 15.0.1
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
## 
## locale:
## [1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8
## 
## time zone: America/Edmonton
## tzcode source: internal
## 
## attached base packages:
## [1] grid      stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] DESeq2_1.44.0               SummarizedExperiment_1.34.0
##  [3] MatrixGenerics_1.16.0       matrixStats_1.4.1          
##  [5] GenomicRanges_1.56.1        GenomeInfoDb_1.40.1        
##  [7] IRanges_2.38.1              RColorBrewer_1.1-3         
##  [9] DescTools_0.99.56           EnvStats_3.0.0             
## [11] reshape2_1.4.4              plotly_4.10.4              
## [13] ggsankey_0.0.99999          ggrepel_0.9.6              
## [15] ggpubr_0.6.0                scales_1.3.0               
## [17] dplyr_1.1.4                 stringr_1.5.1              
## [19] GeoMxWorkflows_1.10.0       GeomxTools_3.8.0           
## [21] NanoStringNCTools_1.12.0    ggplot2_3.5.1              
## [23] S4Vectors_0.42.1            Biobase_2.64.0             
## [25] BiocGenerics_0.50.0        
## 
## loaded via a namespace (and not attached):
##   [1] splines_4.4.1           tibble_3.2.1            cellranger_1.1.0       
##   [4] polyclip_1.10-7         lifecycle_1.0.4         rstatix_0.7.2          
##   [7] globals_0.16.3          lattice_0.22-6          MASS_7.3-61            
##  [10] crosstalk_1.2.1         backports_1.5.0         magrittr_2.0.3         
##  [13] sass_0.4.9              rmarkdown_2.28          jquerylib_0.1.4        
##  [16] yaml_2.3.10             spam_2.10-0             askpass_1.2.0          
##  [19] sp_2.1-4                reticulate_1.39.0       gld_2.6.6              
##  [22] cowplot_1.1.3           minqa_1.2.8             abind_1.4-8            
##  [25] zlibbioc_1.50.0         expm_1.0-0              Rtsne_0.17             
##  [28] purrr_1.0.2             tweenr_2.0.3            GenomeInfoDbData_1.2.12
##  [31] listenv_0.9.1           pheatmap_1.0.12         BiocStyle_2.32.1       
##  [34] umap_0.2.10.0           RSpectra_0.16-2         parallelly_1.38.0      
##  [37] DelayedArray_0.30.1     codetools_0.2-20        ggforce_0.4.2          
##  [40] tidyselect_1.2.1        outliers_0.15           UCSC.utils_1.0.0       
##  [43] farver_2.1.2            lme4_1.1-35.5           jsonlite_1.8.9         
##  [46] e1071_1.7-16            progressr_0.14.0        systemfonts_1.1.0      
##  [49] tools_4.4.1             Rcpp_1.0.13             glue_1.8.0             
##  [52] SparseArray_1.4.8       xfun_0.47               ggthemes_5.1.0         
##  [55] withr_3.0.1             numDeriv_2016.8-1.1     BiocManager_1.30.25    
##  [58] fastmap_1.2.0           GGally_2.2.1            boot_1.3-31            
##  [61] fansi_1.0.6             openssl_2.2.2           digest_0.6.37          
##  [64] R6_2.5.1                colorspace_2.1-1        networkD3_0.4          
##  [67] utf8_1.2.4              tidyr_1.3.1             generics_0.1.3         
##  [70] data.table_1.16.0       class_7.3-22            httr_1.4.7             
##  [73] htmlwidgets_1.6.4       S4Arrays_1.4.1          ggstats_0.6.0          
##  [76] pkgconfig_2.0.3         gtable_0.3.5            Exact_3.3              
##  [79] XVector_0.44.0          htmltools_0.5.8.1       carData_3.0-5          
##  [82] dotCall64_1.1-1         SeuratObject_5.0.2      lmom_3.0               
##  [85] png_0.1-8               knitr_1.48              rstudioapi_0.16.0      
##  [88] rjson_0.2.23            uuid_1.2-1              nlme_3.1-166           
##  [91] nloptr_2.1.1            proxy_0.4-27            cachem_1.1.0           
##  [94] rootSolve_1.8.2.4       parallel_4.4.1          vipor_0.4.7            
##  [97] pillar_1.9.0            vctrs_0.6.5             car_3.1-2              
## [100] beeswarm_0.4.0          evaluate_1.0.0          locfit_1.5-9.10        
## [103] mvtnorm_1.3-1           cli_3.6.3               compiler_4.4.1         
## [106] rlang_1.1.4             crayon_1.5.3            future.apply_1.11.2    
## [109] ggsignif_0.6.4          labeling_0.4.3          plyr_1.8.9             
## [112] ggbeeswarm_0.7.2        ggiraph_0.8.10          stringi_1.8.4          
## [115] BiocParallel_1.38.0     viridisLite_0.4.2       lmerTest_3.1-3         
## [118] munsell_0.5.1           Biostrings_2.72.1       lazyeval_0.2.2         
## [121] Matrix_1.7-0            future_1.34.0           highr_0.11             
## [124] igraph_2.0.3            broom_1.0.6             bslib_0.8.0            
## [127] readxl_1.4.3