Fluorescent Reports
David Rach
University of Maryland, Baltimoredrach@som.umaryland.edu
30 October 2024
Source:vignettes/FluorescentReports.rmd
FluorescentReports.rmd
Introduction
This vignette builds on what can be done with the outputs from the
Luciernaga_QC()
function that was the main focus of
vignette 04_FluorescenceSignatures. Please read that vignette for all
the details regarding how the function processes the .fcs files into
individual signatures.
The following vignette covers the different functions that take these
Luciernaga_QC()
outputs, either in the “data” or “fcs”
format, and process them into useful reports to gain insight into the
fluorescence signatures that are present within your unmixing controls
(both single-color and unstained). At the end of this vignette, we will
discuss how we can extend these reports to visualize changes in
signature across time to monitor for changes in antibody-vial quality or
instrument health.
Some of these functions we will cover in this vignette will also resurface when we look at the Luciernaga unmixing functions that will be covered in Vignette_06.
Set Up
For this vignette, we will focus on characterizing the cell unmixing
controls. The following setup code is a repeat from previous vignettes,
and is used to provide the Luciernaga_QC()
outputs needed
by the functions that we will be covering.
Let’s first load the required packages by calling them with library.
library(Luciernaga)
library(flowCore)
library(flowWorkspace)
library(openCyto)
library(ggcyto)
library(data.table)
library(dplyr)
library(purrr)
library(stringr)
library(ggplot2)
library(gt)
library(plotly)
library(htmltools)
Then we can find the .fcs files stored within the
Luciernaga
packages extdata folder and sort them by their
respective type
File_Location <- system.file("extdata", package = "Luciernaga")
FCS_Pattern <- ".fcs$"
FCS_Files <- list.files(path = File_Location, pattern = FCS_Pattern,
full.names = TRUE, recursive = FALSE)
head(FCS_Files[10:30], 20)
#> [1] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/21_Before.fcs"
#> [2] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/22_After.fcs"
#> [3] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/22_Before.fcs"
#> [4] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/23_After.fcs"
#> [5] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/23_Before.fcs"
#> [6] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/4BeadsUnstained(Beads).fcs"
#> [7] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CCR4_BUV615(Beads).fcs"
#> [8] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CCR4_BUV615(Cells).fcs"
#> [9] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CCR6_BV786(Beads).fcs"
#> [10] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CCR6_BV786(Cells).fcs"
#> [11] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CCR7_BV650(Beads).fcs"
#> [12] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CCR7_BV650(Cells).fcs"
#> [13] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD107a_APC-R700(Beads).fcs"
#> [14] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD107a_APC-R700(Cells).fcs"
#> [15] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD127_BV421(Beads).fcs"
#> [16] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD127_BV421(Cells).fcs"
#> [17] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD16_APC(Beads).fcs"
#> [18] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD16_APC(Cells).fcs"
#> [19] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD161_BV480(Beads).fcs"
#> [20] "C:/Users/12692/AppData/Local/R/win-library/4.4/Luciernaga/extdata/CD161_BV480(Cells).fcs"
UnstainedFCSFiles <- FCS_Files[grep("Unstained", FCS_Files)]
UnstainedBeads <- UnstainedFCSFiles[grep("Beads", UnstainedFCSFiles)]
UnstainedCells <- UnstainedFCSFiles[-grep("Beads", UnstainedFCSFiles)]
BeadFCSFiles <- FCS_Files[grep("Beads", FCS_Files)]
BeadSingleColors <- BeadFCSFiles[-grep("Unstained", BeadFCSFiles)]
CellSingleColorFiles <- FCS_Files[grep("Cells", FCS_Files)]
CellSingleColors <- CellSingleColorFiles[!str_detect("Unstained", CellSingleColorFiles)]
Now lets create a GatingSet for our single-color cell unmixing controls
MyCytoSet <- load_cytoset_from_fcs(CellSingleColors,
truncate_max_range = FALSE,
transform = FALSE)
MyCytoSet
#> A cytoset with 30 samples.
#>
#> column names:
#> Time, UV1-A, UV2-A, UV3-A, UV4-A, UV5-A, UV6-A, UV7-A, UV8-A, UV9-A, UV10-A, UV11-A, UV12-A, UV13-A, UV14-A, UV15-A, UV16-A, SSC-W, SSC-H, SSC-A, V1-A, V2-A, V3-A, V4-A, V5-A, V6-A, V7-A, V8-A, V9-A, V10-A, V11-A, V12-A, V13-A, V14-A, V15-A, V16-A, FSC-W, FSC-H, FSC-A, SSC-B-W, SSC-B-H, SSC-B-A, B1-A, B2-A, B3-A, B4-A, B5-A, B6-A, B7-A, B8-A, B9-A, B10-A, B11-A, B12-A, B13-A, B14-A, YG1-A, YG2-A, YG3-A, YG4-A, YG5-A, YG6-A, YG7-A, YG8-A, YG9-A, YG10-A, R1-A, R2-A, R3-A, R4-A, R5-A, R6-A, R7-A, R8-A
MyGatingSet <- GatingSet(MyCytoSet)
MyGatingSet
#> A GatingSet with 30 samples
FileLocation <- system.file("extdata", package = "Luciernaga")
MyGates <- fread(file.path(path = FileLocation, pattern = 'Gates.csv'))
gt(MyGates)
alias | pop | parent | dims | gating_method | gating_args | collapseDataForGating | groupBy | preprocessing_method | preprocessing_args |
---|---|---|---|---|---|---|---|---|---|
singletsFSC | + | root | FSC-A,FSC-H | singletGate | FALSE | NA | NA | NA | |
singletsSSC | + | singletsFSC | SSC-A,SSC-H | singletGate | FALSE | NA | NA | NA | |
singletsSSCB | + | singletsSSC | SSC-A,SSC-B-A | singletGate | FALSE | NA | NA | NA | |
nonDebris | + | singletsSSCB | FSC-A | gate_mindensity | FALSE | NA | NA | NA | |
lymphocytes | + | nonDebris | FSC-A, SSC-A | flowClust | K=2, target=c(1e5, 5e4) | FALSE | NA | NA | NA |
MyGatingTemplate <- gatingTemplate(MyGates)
gt_gating(MyGatingTemplate, MyGatingSet)
MyGatingSet[[1]]
#> Sample: CCR4_BUV615(Cells).fcs
#> GatingHierarchy with 6 gates
Now lets create a GatingSet for our unstained cell unmixing controls
MyUnstainedCytoSet <- load_cytoset_from_fcs(UnstainedCells,
truncate_max_range = FALSE,
transform = FALSE)
MyUnstainedCytoSet
#> A cytoset with 18 samples.
#>
#> column names:
#> Time, UV1-A, UV2-A, UV3-A, UV4-A, UV5-A, UV6-A, UV7-A, UV8-A, UV9-A, UV10-A, UV11-A, UV12-A, UV13-A, UV14-A, UV15-A, UV16-A, SSC-W, SSC-H, SSC-A, V1-A, V2-A, V3-A, V4-A, V5-A, V6-A, V7-A, V8-A, V9-A, V10-A, V11-A, V12-A, V13-A, V14-A, V15-A, V16-A, FSC-W, FSC-H, FSC-A, SSC-B-W, SSC-B-H, SSC-B-A, B1-A, B2-A, B3-A, B4-A, B5-A, B6-A, B7-A, B8-A, B9-A, B10-A, B11-A, B12-A, B13-A, B14-A, YG1-A, YG2-A, YG3-A, YG4-A, YG5-A, YG6-A, YG7-A, YG8-A, YG9-A, YG10-A, R1-A, R2-A, R3-A, R4-A, R5-A, R6-A, R7-A, R8-A
MyUnstainedGatingSet <- GatingSet(MyUnstainedCytoSet)
MyUnstainedGatingSet
#> A GatingSet with 18 samples
FileLocation <- system.file("extdata", package = "Luciernaga")
MyGates <- fread(file.path(path = FileLocation, pattern = 'Gates.csv'))
gt(MyGates)
alias | pop | parent | dims | gating_method | gating_args | collapseDataForGating | groupBy | preprocessing_method | preprocessing_args |
---|---|---|---|---|---|---|---|---|---|
singletsFSC | + | root | FSC-A,FSC-H | singletGate | FALSE | NA | NA | NA | |
singletsSSC | + | singletsFSC | SSC-A,SSC-H | singletGate | FALSE | NA | NA | NA | |
singletsSSCB | + | singletsSSC | SSC-A,SSC-B-A | singletGate | FALSE | NA | NA | NA | |
nonDebris | + | singletsSSCB | FSC-A | gate_mindensity | FALSE | NA | NA | NA | |
lymphocytes | + | nonDebris | FSC-A, SSC-A | flowClust | K=2, target=c(1e5, 5e4) | FALSE | NA | NA | NA |
MyGatingTemplate <- gatingTemplate(MyGates)
gt_gating(MyGatingTemplate, MyUnstainedGatingSet)
MyUnstainedGatingSet[[1]]
#> Sample: INF071_Ctrl_Unstained.fcs
#> GatingHierarchy with 6 gates
Generate Luciernaga_QC Outputs
Now that the GatingSets are re-established, let’s continue where the
last vignette left off by processing all the fcs files with
Luciernaga_QC
to characterize the fluorescent signatures
within.
Let’s first provision the AFOverlap csv to handle conflicts.
FileLocation <- system.file("extdata", package = "Luciernaga")
pattern = "AutofluorescentOverlaps.csv"
AFOverlap <- list.files(path=FileLocation, pattern=pattern,
full.names = TRUE)
AFOverlap_CSV <- read.csv(AFOverlap, check.names = FALSE)
AFOverlap_CSV
#> Fluorophore MainDetector
#> 1 Unstained UV7-A,V7-A,V3-A,V5-A
#> 2 BUV496 UV7-A
#> 3 BV480 V5-A
#> 4 BV510 V7-A
#> 5 BV570 V8-A
And next generate a CellAF unstained signature that can be used when these fluorophore-autofluorescence overlap files are encountered:
# pData(MyUnstainedGatingSet[1])
removestrings <- c(".fcs")
TheCellAF <- map(.x=MyUnstainedGatingSet[1], .f=Luciernaga_QC, subsets="lymphocytes",
removestrings=removestrings, sample.name="GUID",
unmixingcontroltype = "cells", Unstained = TRUE,
ratiopopcutoff = 0.001, Verbose = FALSE,
AFOverlap = AFOverlap, stats = "median",
ExportType = "data", SignatureReturnNow = TRUE,
outpath = TemporaryFolder, Increments=0.1,
SecondaryPeaks=2, experiment = "FirstExperiment",
condition = "ILTPanel", SCData="subtracted",
NegativeType="default")
#> Normalizing Data for Signature Comparison
TheCellAF <- TheCellAF[[1]] #Removes list caused by map
gt(TheCellAF)
UV1-A | UV2-A | UV3-A | UV4-A | UV5-A | UV6-A | UV7-A | UV8-A | UV9-A | UV10-A | UV11-A | UV12-A | UV13-A | UV14-A | UV15-A | UV16-A | V1-A | V2-A | V3-A | V4-A | V5-A | V6-A | V7-A | V8-A | V9-A | V10-A | V11-A | V12-A | V13-A | V14-A | V15-A | V16-A | B1-A | B2-A | B3-A | B4-A | B5-A | B6-A | B7-A | B8-A | B9-A | B10-A | B11-A | B12-A | B13-A | B14-A | YG1-A | YG2-A | YG3-A | YG4-A | YG5-A | YG6-A | YG7-A | YG8-A | YG9-A | YG10-A | R1-A | R2-A | R3-A | R4-A | R5-A | R6-A | R7-A | R8-A |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
359.38 | 612.9988 | 437.0275 | 559.4488 | 779.7476 | 1246.153 | 2423.138 | 1793.776 | 1682.139 | 625.345 | 402.5919 | 251.5363 | 198.8788 | 255.1806 | 175.5994 | 168.3106 | 379.9125 | 1167.719 | 1815.069 | 2080.031 | 3214.613 | 3112.45 | 4226.681 | 3096.637 | 2104.025 | 2316.6 | 1251.25 | 704.825 | 632.8438 | 574.3375 | 518.1688 | 295.5562 | 1192.289 | 1367.454 | 1904.727 | 1289.431 | 1090.77 | 870.5431 | 619.2231 | 459.5087 | 477.0831 | 316.0812 | 239.0244 | 221.5788 | 163.0619 | 210.1844 | 516.2194 | 394.8131 | 402.2363 | 388.5 | 308.8575 | 310.3838 | 380.73 | 196.4006 | 195.2213 | 131.2575 | 189.9812 | 239.6306 | 253.4731 | 285.1131 | 152.1969 | 142.1681 | 129.8794 | 89.97625 |
We will start with the ExportType = “data” return for now for both the cell Single-Color and Unstained Unmixing controls.
SingleColor_Data <- map(.x=MyGatingSet, .f=Luciernaga_QC, subsets="lymphocytes",
removestrings=removestrings, sample.name="GUID",
unmixingcontroltype = "cells", Unstained = FALSE,
ratiopopcutoff = 0.001, Verbose = FALSE,
AFOverlap = AFOverlap, stats = "median",
ExportType = "data", SignatureReturnNow = FALSE,
outpath = TemporaryFolder, Increments=0.1,
SecondaryPeaks=2, experiment = "FirstExperiment",
condition = "ILTPanel", Subtraction = "Internal",
CellAF=TheCellAF, SCData="subtracted",
NegativeType="default") %>% bind_rows()
#> No second peak
#> No second peak
#> No second peak
#> Only a single detector present. If this was not an autofluorescence overlap
#> fluourophore, it would suggest there was no antibody staining, or everything
#> was overstained. Please investigate further.
#> No second peak
#> No second peak
#> No second peak
nrow(SingleColor_Data)
#> [1] 2598
Sample | Experiment | Condition | Cluster | Count | UV1 | UV2 | UV3 | UV4 | UV5 | UV6 | UV7 | UV8 | UV9 | UV10 | UV11 | UV12 | UV13 | UV14 | UV15 | UV16 | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | V11 | V12 | V13 | V14 | V15 | V16 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | YG1 | YG2 | YG3 | YG4 | YG5 | YG6 | YG7 | YG8 | YG9 | YG10 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
CCR4_BUV615(Cells) | FirstExperiment | ILTPanel | UV10_10-YG3_09-V10_03 | 95 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.30 | 1 | 0.5 | 0.3 | 0.2 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.3 | 0.10 | 0.1 | 0.1 | 0.1 | 0.1 | 0.0 | 0.00 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.10 | 0.1 | 0.10 | 0.1 | 0.1 | 0.4 | 0.9 | 0.4 | 0.3 | 0.3 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
CCR4_BUV615(Cells) | FirstExperiment | ILTPanel | UV10_10-YG3_09-V10_04 | 35 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.30 | 1 | 0.5 | 0.3 | 0.2 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.4 | 0.20 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.10 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.10 | 0.1 | 0.10 | 0.1 | 0.1 | 0.4 | 0.9 | 0.4 | 0.3 | 0.3 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.0 | 0.1 | 0.0 |
CCR4_BUV615(Cells) | FirstExperiment | ILTPanel | UV10_10-YG3_08-V10_03 | 32 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.35 | 1 | 0.4 | 0.3 | 0.2 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.3 | 0.15 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.05 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.05 | 0.0 | 0.05 | 0.0 | 0.1 | 0.4 | 0.8 | 0.4 | 0.3 | 0.3 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.0 | 0.1 | 0.1 | 0.1 | 0.0 |
CCR4_BUV615(Cells) | FirstExperiment | ILTPanel | UV10_10-YG3_08-V10_04 | 25 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.2 | 0.5 | 0.4 | 0.60 | 1 | 0.5 | 0.3 | 0.2 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.2 | 0.4 | 0.20 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.10 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.00 | 0.1 | 0.10 | 0.0 | 0.1 | 0.4 | 0.8 | 0.4 | 0.3 | 0.3 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.0 | 0.0 | 0.1 | 0.1 |
CCR4_BUV615(Cells) | FirstExperiment | ILTPanel | UV10_10-YG3_10-V10_03 | 19 | 0.0 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.30 | 1 | 0.5 | 0.3 | 0.2 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.3 | 0.10 | 0.1 | 0.1 | 0.1 | 0.0 | 0.0 | 0.10 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.0 | 0.10 | 0.0 | 0.10 | 0.0 | 0.1 | 0.5 | 1.0 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.0 | 0.0 | 0.0 | 0.1 | 0.0 |
Let’s now repeat this process for the Unstained GatingSet.
# pData(MyUnstainedGatingSet)
Unstained_Data <- map(.x=MyUnstainedGatingSet, .f=Luciernaga_QC, subsets="lymphocytes",
removestrings=removestrings, sample.name="GUID",
unmixingcontroltype = "cells", Unstained = TRUE,
ratiopopcutoff = 0.001, Verbose = FALSE,
AFOverlap = AFOverlap, stats = "median",
ExportType = "data", SignatureReturnNow = FALSE,
outpath = TemporaryFolder, Increments=0.1,
SecondaryPeaks=2, experiment = "FirstExperiment",
condition = "ILTPanel", Subtraction = "Internal",
CellAF=TheCellAF, SCData="subtracted",
NegativeType="default") %>% bind_rows()
nrow(Unstained_Data)
#> [1] 1752
Sample | Experiment | Condition | Cluster | Count | UV1 | UV2 | UV3 | UV4 | UV5 | UV6 | UV7 | UV8 | UV9 | UV10 | UV11 | UV12 | UV13 | UV14 | UV15 | UV16 | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | V11 | V12 | V13 | V14 | V15 | V16 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | YG1 | YG2 | YG3 | YG4 | YG5 | YG6 | YG7 | YG8 | YG9 | YG10 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
INF071_Ctrl_Unstained | FirstExperiment | ILTPanel | V7_10-UV8_05-B3_05 | 641 | 0.1 | 0.2 | 0.1 | 0.2 | 0.2 | 0.3 | 0.6 | 0.5 | 0.4 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.3 | 0.5 | 0.5 | 0.8 | 0.8 | 1 | 0.8 | 0.5 | 0.6 | 0.3 | 0.2 | 0.2 | 0.2 | 0.2 | 0.1 | 0.3 | 0.4 | 0.5 | 0.4 | 0.3 | 0.3 | 0.2 | 0.2 | 0.20 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
INF071_Ctrl_Unstained | FirstExperiment | ILTPanel | V7_10-UV8_04-B3_05 | 536 | 0.1 | 0.2 | 0.1 | 0.2 | 0.2 | 0.3 | 0.6 | 0.4 | 0.4 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.3 | 0.5 | 0.5 | 0.8 | 0.8 | 1 | 0.8 | 0.5 | 0.6 | 0.3 | 0.2 | 0.2 | 0.2 | 0.2 | 0.1 | 0.3 | 0.4 | 0.5 | 0.3 | 0.3 | 0.3 | 0.2 | 0.2 | 0.20 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
INF071_Ctrl_Unstained | FirstExperiment | ILTPanel | V7_10-UV8_05-B3_06 | 362 | 0.1 | 0.2 | 0.1 | 0.2 | 0.2 | 0.3 | 0.6 | 0.5 | 0.5 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.3 | 0.5 | 0.5 | 0.8 | 0.8 | 1 | 0.8 | 0.6 | 0.6 | 0.4 | 0.2 | 0.2 | 0.2 | 0.2 | 0.1 | 0.4 | 0.4 | 0.6 | 0.4 | 0.3 | 0.3 | 0.2 | 0.2 | 0.20 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
INF071_Ctrl_Unstained | FirstExperiment | ILTPanel | V7_10-UV8_05-B3_04 | 330 | 0.1 | 0.2 | 0.2 | 0.2 | 0.2 | 0.4 | 0.6 | 0.5 | 0.4 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.3 | 0.5 | 0.5 | 0.8 | 0.8 | 1 | 0.8 | 0.5 | 0.6 | 0.3 | 0.2 | 0.2 | 0.2 | 0.2 | 0.1 | 0.3 | 0.3 | 0.4 | 0.3 | 0.3 | 0.2 | 0.2 | 0.2 | 0.15 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
INF071_Ctrl_Unstained | FirstExperiment | ILTPanel | V7_10-UV8_04-B3_04 | 329 | 0.1 | 0.2 | 0.2 | 0.2 | 0.2 | 0.3 | 0.6 | 0.4 | 0.4 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.3 | 0.5 | 0.5 | 0.8 | 0.8 | 1 | 0.7 | 0.5 | 0.6 | 0.3 | 0.2 | 0.2 | 0.2 | 0.2 | 0.1 | 0.3 | 0.3 | 0.4 | 0.3 | 0.3 | 0.2 | 0.2 | 0.1 | 0.10 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.2 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 | 0.1 |
Luciernaga_Plots
The Luciernaga_Plots()
function works directly from the
Luciernaga_QC()
output when the ExportType = “data”. Let’s
start exploring what it can do.
We will first provide a file.path to the panel information, which
will be used by Luciernaga_Plots()
to arrange the
plots/report by the order of the fluorophores listed in the panel. If
there is a mismatch between the fluorophore data and the panel, it will
not rearrange but proceed to the output.
FileLocation <- system.file("extdata", package = "Luciernaga")
pattern = "^Panel.csv"
CSV <- list.files(path=FileLocation, pattern=pattern, full.names=TRUE)
TheFluorophoreOrder <- read.csv(CSV, check.names = FALSE)
The SingleColor_Data output from above currently contains the
information for every single fluorophore .fcs file that was processed.
While we can pass the entire object to Luciernaga_Plots()
and it will process a report for each, we can also tailor our output by
using dplyr to target
particular fluorophores of interest if we want to find information for a
specific fluorophore.
BUV615 <- SingleColor_Data %>% filter(str_detect(Sample, "BUV615"))
nrow(BUV615)
#> [1] 100
head(BUV615)
#> Sample Experiment Condition Cluster Count UV1
#> 1 CCR4_BUV615(Cells) FirstExperiment ILTPanel UV10_10-YG3_09-V10_03 95 0.1
#> 2 CCR4_BUV615(Cells) FirstExperiment ILTPanel UV10_10-YG3_09-V10_04 35 0.1
#> 3 CCR4_BUV615(Cells) FirstExperiment ILTPanel UV10_10-YG3_08-V10_03 32 0.1
#> 4 CCR4_BUV615(Cells) FirstExperiment ILTPanel UV10_10-YG3_08-V10_04 25 0.1
#> 5 CCR4_BUV615(Cells) FirstExperiment ILTPanel UV10_10-YG3_10-V10_03 19 0.0
#> 6 CCR4_BUV615(Cells) FirstExperiment ILTPanel UV10_10-YG3_09-V10_02 12 0.1
#> UV2 UV3 UV4 UV5 UV6 UV7 UV8 UV9 UV10 UV11 UV12 UV13 UV14 UV15 UV16 V1 V2
#> 1 0.1 0.1 0.1 0.1 0.1 0.10 0.1 0.30 1 0.5 0.3 0.20 0.2 0.1 0.1 0.1 0.1
#> 2 0.1 0.1 0.1 0.1 0.1 0.20 0.1 0.30 1 0.5 0.3 0.20 0.2 0.1 0.1 0.1 0.1
#> 3 0.1 0.1 0.1 0.1 0.1 0.20 0.1 0.35 1 0.4 0.3 0.20 0.2 0.1 0.1 0.1 0.1
#> 4 0.1 0.1 0.1 0.2 0.2 0.50 0.4 0.60 1 0.5 0.3 0.20 0.2 0.1 0.1 0.1 0.1
#> 5 0.1 0.1 0.1 0.1 0.1 0.10 0.1 0.30 1 0.5 0.3 0.20 0.2 0.1 0.1 0.1 0.1
#> 6 0.1 0.1 0.1 0.1 0.1 0.05 0.0 0.30 1 0.5 0.3 0.15 0.1 0.1 0.1 0.0 0.1
#> V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 B1 B2 B3 B4
#> 1 0.10 0.1 0.1 0.1 0.1 0.1 0.1 0.3 0.10 0.1 0.10 0.10 0.10 0.0 0.00 0.1 0.1 0.1
#> 2 0.10 0.1 0.1 0.1 0.1 0.1 0.2 0.4 0.20 0.1 0.10 0.10 0.10 0.1 0.10 0.1 0.1 0.1
#> 3 0.10 0.1 0.1 0.1 0.1 0.1 0.2 0.3 0.15 0.1 0.10 0.10 0.10 0.1 0.05 0.1 0.1 0.1
#> 4 0.10 0.1 0.1 0.1 0.1 0.2 0.2 0.4 0.20 0.1 0.10 0.10 0.10 0.1 0.10 0.1 0.1 0.1
#> 5 0.10 0.1 0.1 0.1 0.1 0.1 0.2 0.3 0.10 0.1 0.10 0.10 0.00 0.0 0.10 0.1 0.1 0.1
#> 6 0.05 0.1 0.0 0.0 0.0 0.0 0.1 0.2 0.10 0.1 0.05 0.05 0.05 0.0 0.00 0.0 0.0 0.1
#> B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 YG1 YG2 YG3 YG4 YG5 YG6 YG7 YG8
#> 1 0.1 0.1 0.1 0.1 0.10 0.1 0.10 0.10 0.10 0.10 0.1 0.4 0.9 0.4 0.3 0.3 0.20 0.1
#> 2 0.1 0.1 0.1 0.1 0.10 0.1 0.10 0.10 0.10 0.10 0.1 0.4 0.9 0.4 0.3 0.3 0.20 0.1
#> 3 0.1 0.1 0.1 0.1 0.10 0.1 0.05 0.00 0.05 0.00 0.1 0.4 0.8 0.4 0.3 0.3 0.20 0.1
#> 4 0.1 0.1 0.1 0.1 0.10 0.1 0.00 0.10 0.10 0.00 0.1 0.4 0.8 0.4 0.3 0.3 0.20 0.1
#> 5 0.1 0.1 0.1 0.1 0.10 0.0 0.10 0.00 0.10 0.00 0.1 0.5 1.0 0.5 0.4 0.3 0.20 0.1
#> 6 0.1 0.1 0.1 0.1 0.05 0.0 0.00 0.05 0.10 0.05 0.1 0.4 0.9 0.4 0.4 0.3 0.25 0.1
#> YG9 YG10 R1 R2 R3 R4 R5 R6 R7 R8
#> 1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.10
#> 2 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.0 0.1 0.00
#> 3 0.1 0.1 0.1 0.1 0.1 0.0 0.1 0.1 0.1 0.00
#> 4 0.1 0.1 0.1 0.1 0.1 0.1 0.0 0.0 0.1 0.10
#> 5 0.1 0.1 0.1 0.1 0.1 0.0 0.0 0.0 0.1 0.00
#> 6 0.1 0.1 0.1 0.1 0.1 0.1 0.0 0.0 0.0 0.05
As you can tell, we processed Luciernaga_QC()
with
increments set at 0.1 so there was a lot of splitting into specific
Clusters for this fluorophore. This can be overwhelming for
Luciernaga_Plots()
default arguments in some individual
circumstances, such as the example below:
TheFluorophoreOrder <- read.csv(CSV, check.names = FALSE)
TheFluorophore <- TheFluorophoreOrder %>% filter(Fluorophore %in% "BUV615")
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.001,
outfolder=NULL, filename="LuciernagaReport", returntype="patchwork",
LinePlots=TRUE, CosinePlots=TRUE, StackedBarPlots = TRUE,
HeatmapPlots = TRUE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport[[1]]
To work around this, when the data.frame is handed to
Luciernaga_Plot()
, we can filter by CellPopRatio to dictate
what percentage of the total outputed cells a Cluster needs to be to be
visualized. For the clusters that are excluded, these are gathered by
the function and classified as Cluster “Other”. Let’s see this in action
by setting CellPopRatio to 0.05 (so a cluster is retained if it makes up
5% stained cells):
TheFluorophoreOrder <- read.csv(CSV, check.names = FALSE)
TheFluorophore <- TheFluorophoreOrder %>% filter(Fluorophore %in% "BUV615")
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="patchwork",
LinePlots=TRUE, CosinePlots=TRUE, StackedBarPlots = TRUE,
HeatmapPlots = TRUE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport[[1]]
From the above we can see the basic available formats of the
Luciernaga_Plots()
outputs. Namely, from the
Luciernaga_QC()
output we can visualize LinePlots (showing
visualized signatures), CosinePlots (showing the cosine similarity
matrix values of individual signatures relative to each other),
StackedBarPlots and HeatmapPlots (which in different ways show relative
abundance of the cluster signatures).
For the above example, we are using the returntype=“patchwork”
argument. As with other Luciernaga
packages, it takes the
same arguments that are passed to the Utility_Patchwork()
function to dictate layout. Similarly, we can set returntype = “pdf” to
generate a .pdf file with the report contents sent to the location
specified by the outfolder and filename.
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="patchwork",
LinePlots=TRUE, CosinePlots=TRUE, StackedBarPlots = TRUE,
HeatmapPlots = TRUE, reference = TheFluorophore, thecolumns=2,
therows=2, width=7, height=9)
#> names not matching, no reorderring according to panel order
ThePlotReport[[1]]
In the cases above, the report returned all four plots. These can be turned on or off as desired. For example, if we want to only retrieve only individual plot elements, we would leave our desired plot value as TRUE, set the other plot arguments to FALSE.
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="patchwork",
LinePlots=TRUE, CosinePlots=FALSE, StackedBarPlots = FALSE,
HeatmapPlots = TRUE, reference = TheFluorophore, thecolumns=2,
therows=2, width=7, height=9)
#> names not matching, no reorderring according to panel order
ThePlotReport[[1]]
Additionally, we would switch from returntype = “patchwork” to
“plots” to retrieve the actual ggplot2 object of interest. The returned
objects are still in a list format, so we use
rCRANpkg("purrr")
flatten function to get rid of the list,
allowing the ggplot2 object to be handed to
rCRANpkg("plotly")
ggplotly function to allow for
interactive elements.
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="plots",
LinePlots=TRUE, CosinePlots=FALSE, StackedBarPlots = FALSE,
HeatmapPlots = FALSE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport <- purrr::flatten(ThePlotReport)
plotly::ggplotly(ThePlotReport[[1]])
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="plots",
LinePlots=FALSE, CosinePlots=TRUE, StackedBarPlots = FALSE,
HeatmapPlots = FALSE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport <- purrr::flatten(ThePlotReport)
plotly::ggplotly(ThePlotReport[[1]])
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="plots",
LinePlots=FALSE, CosinePlots=FALSE, StackedBarPlots = TRUE,
HeatmapPlots = FALSE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport <- purrr::flatten(ThePlotReport)
plotly::ggplotly(ThePlotReport[[1]])
ThePlotReport <- Luciernaga_Plots(data=BUV615, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="plots",
LinePlots=FALSE, CosinePlots=FALSE, StackedBarPlots = FALSE,
HeatmapPlots = TRUE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport <- purrr::flatten(ThePlotReport)
plotly::ggplotly(ThePlotReport[[1]])
Since the returned plots are ggplot2 objects, you can additionally
modify them further using ggplot2 arguments to change respective
elements appearance and aesthetics however you see fit. Please refer to
rCRANpkg("ggplot2")
vignettes and tutorials on how to do
this, as it’s outside of our scope for this vignette.
Having characterized the pieces of Luciernaga_Plots()
for a single fluorophore, let’s quickly see how it behaves without the
initial filtering for the entire SC_Data
TheFluorophoreOrder <- read.csv(CSV, check.names = FALSE)
ThePlotReport <- Luciernaga_Plots(data=SingleColor_Data, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="patchwork",
LinePlots=TRUE, CosinePlots=TRUE, StackedBarPlots = TRUE,
HeatmapPlots = TRUE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport[1:4]
#> [[1]]
#>
#> [[2]]
#>
#> [[3]]
#>
#> [[4]]
As can be seen, it automatically processed the data for each individual fluorophore. As with the above, the arguments can be altered to turn on/off individual plot elements, change the orientation, and alter the return type as with the examples above.
TheFluorophoreOrder <- read.csv(CSV, check.names = FALSE)
ThePlotReport <- Luciernaga_Plots(data=SingleColor_Data, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="plots",
LinePlots=FALSE, CosinePlots=FALSE, StackedBarPlots = FALSE,
HeatmapPlots = TRUE, reference = TheFluorophore)
#> names not matching, no reorderring according to panel order
ThePlotReport[1:4]
#> [[1]]
#> [[1]][[1]]
#>
#>
#> [[2]]
#> [[2]][[1]]
#>
#>
#> [[3]]
#> [[3]][[1]]
#>
#>
#> [[4]]
#> [[4]][[1]]
The examples above relied on LuciernagaQC()
ExportType =
“data” output to generate the desired reports and plots. This can be
saved by individual users as a .csv that can be retrieved for later
use.
# Saving Elsewhere
StorageLocation <- file.path("C:", "Users", "JohnDoe", "Desktop")
TheName <- "SingleColorData.csv"
TheFinalLocation <- file.path(StorageLocation, TheName)
write.csv(SingleColor_Data, TheFinalLocation, row.names=FALSE)
# Reading in Later
TheRetrievedData <- read.csv(TheFinalLocation, check.names=FALSE)
Luciernaga_FCSToReport
Luciernaga_FCSToReport()
is a function that handles
cases when there is no LuciernagaQC()
ExportType = “data”
to allow for the generation of plots and reports, and instead, we need
to take the LuciernagaQC()
ExportType = “fcs” outputs from
their storage folder and re-derrive the equivalent data to be used with
Luciernaga_Plots()
.
To demonstrate this, let’s first switch the
Luciernaga_QC()
ExportType argument to “fcs” and store the
same single-color output .fcs files within the temporary folder in a
specific folder where we can retrieve them again when needed:
StorageLocation <- file.path(tempdir(), "LuciernagaTemporaryExamples")
if (!dir.exists(StorageLocation)) {
dir.create(StorageLocation)
}
SingleColor_Data <- map(.x=MyGatingSet[c(1:22, 25:30)], .f=Luciernaga_QC, subsets="lymphocytes",
removestrings=removestrings, sample.name="GUID",
unmixingcontroltype = "cells", Unstained = FALSE,
ratiopopcutoff = 0.001, Verbose = FALSE,
AFOverlap = AFOverlap, stats = "median",
ExportType = "fcs", Brightness=TRUE, SignatureReturnNow = FALSE,
outpath = StorageLocation, Increments=0.1,
SecondaryPeaks=2, experiment = "FirstExperiment",
condition = "ILTPanel", Subtraction = "Internal",
CellAF=TheCellAF, SCData="subtracted",
NegativeType="default")
#> No second peak
#> No second peak
#> No second peak
#> Only a single detector present. If this was not an autofluorescence overlap
#> fluourophore, it would suggest there was no antibody staining, or everything
#> was overstained. Please investigate further.
#> No second peak
#> No second peak
#> No second peak
TheLuciernagaOutputs_FCS <- list.files(StorageLocation, pattern="fcs", full.names = TRUE)
head(TheLuciernagaOutputs_FCS, 4)
#> [1] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/CCR4_BUV615(Cells)_UV1010YG308V1003.fcs"
#> [2] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/CCR4_BUV615(Cells)_UV1010YG308V1004.fcs"
#> [3] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/CCR4_BUV615(Cells)_UV1010YG309V1003.fcs"
#> [4] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/CCR4_BUV615(Cells)_UV1010YG309V1004.fcs"
TheLuciernagaOutputs_CSV <- list.files(StorageLocation, pattern="csv", full.names = TRUE)
head(TheLuciernagaOutputs_CSV, 4)
#> [1] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/RelativeBrightnessCCR4_BUV615(Cells).csv"
#> [2] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/RelativeBrightnessCCR6_BV786(Cells).csv"
#> [3] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/RelativeBrightnessCCR7_BV650(Cells).csv"
#> [4] "C:\\Users\\12692\\AppData\\Local\\Temp\\RtmpyeBMqE/LuciernagaTemporaryExamples/RelativeBrightnessCD107a_APC-R700(Cells).csv"
We can now proceed to evaluate
Luciernaga_FCSToReport()
:
ReferencePath <- system.file("extdata", package = "Luciernaga")
PanelPath <- file.path(ReferencePath, "Panel.csv")
#PanelNames <- read.csv(PanelPath, check.names = FALSE)
#PanelNames <- PanelNames %>% pull(Fluorophore) %>% gsub("-A", "", .)
ReportOutput <- Luciernaga_FCSToReport(path=StorageLocation, reference=PanelPath, stats="median",
RetainedType = "normalized", experiment="FirstExperiment",
condition="ILTExperiment", TheSummary = TRUE)
Sample | Experiment | Condition | Cluster | Count | UV1 | UV2 | UV3 | UV4 | UV5 | UV6 | UV7 | UV8 | UV9 | UV10 | UV11 | UV12 | UV13 | UV14 | UV15 | UV16 | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | V11 | V12 | V13 | V14 | V15 | V16 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | YG1 | YG2 | YG3 | YG4 | YG5 | YG6 | YG7 | YG8 | YG9 | YG10 | R1 | R2 | R3 | R4 | R5 | R6 | R7 | R8 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
BUV395(Cells) | FirstExperiment | ILTExperiment | UV210 | 3177 | 0.253 | 1.000 | 0.475 | 0.347 | 0.305 | 0.281 | 0.138 | 0.030 | 0.001 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.0000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 |
BUV395(Cells) | FirstExperiment | ILTExperiment | UV210V702 | 199 | 0.251 | 1.000 | 0.472 | 0.362 | 0.322 | 0.330 | 0.218 | 0.101 | 0.080 | 0.024 | 0.019 | 0.010 | 0.007 | 0.012 | 0.004 | 0.013 | 0.006 | 0.045 | 0.042 | 0.049 | 0.091 | 0.081 | 0.141 | 0.077 | 0.068 | 0.077 | 0.056 | 0.035 | 0.028 | 0.035 | 0.036 | 0.025 | 0.035 | 0.056 | 0.048 | 0.033 | 0.035 | 0.022 | 0.022 | 0.009 | 0.014 | 0.006 | 0.010 | 0.013 | 0.014 | 0.014 | 0.010 | 0.012 | 0.007 | 0.011 | 0.013 | 0.005 | 0.0280 | 0.004 | 0.008 | 0.000 | 0.003 | 0.007 | 0.011 | 0.008 | 0.007 | 0.002 | 0.004 | 0.009 |
BUV496(Cells) | FirstExperiment | ILTExperiment | UV710V602 | 543 | 0.009 | 0.033 | 0.025 | 0.023 | 0.032 | 0.184 | 1.000 | 0.533 | 0.249 | 0.061 | 0.016 | 0.006 | 0.005 | 0.004 | 0.002 | 0.001 | 0.000 | 0.003 | 0.014 | 0.069 | 0.218 | 0.163 | 0.170 | 0.071 | 0.035 | 0.029 | 0.009 | 0.003 | 0.002 | 0.002 | 0.001 | 0.001 | 0.066 | 0.042 | 0.033 | 0.010 | 0.005 | 0.004 | 0.002 | 0.001 | 0.001 | 0.001 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 | 0.000 | 0.001 | 0.000 | 0.000 | 0.0010 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 | 0.000 | 0.000 | 0.000 | 0.001 |
BUV496(Cells) | FirstExperiment | ILTExperiment | UV710 | 283 | 0.004 | 0.001 | 0.000 | 0.000 | 0.000 | 0.071 | 1.000 | 0.494 | 0.138 | 0.043 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.034 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.0000 | 0.007 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.005 | 0.000 | 0.017 |
BUV496(Cells) | FirstExperiment | ILTExperiment | UV710V603 | 157 | 0.010 | 0.047 | 0.026 | 0.027 | 0.034 | 0.196 | 1.000 | 0.562 | 0.264 | 0.067 | 0.022 | 0.007 | 0.006 | 0.008 | 0.008 | 0.000 | 0.001 | 0.022 | 0.036 | 0.100 | 0.268 | 0.232 | 0.217 | 0.108 | 0.058 | 0.055 | 0.015 | 0.009 | 0.016 | 0.009 | 0.006 | 0.001 | 0.080 | 0.052 | 0.051 | 0.024 | 0.009 | 0.019 | 0.008 | 0.009 | 0.009 | 0.007 | 0.001 | 0.002 | 0.000 | 0.004 | 0.005 | 0.005 | 0.004 | 0.009 | 0.002 | 0.003 | 0.0110 | 0.000 | 0.000 | 0.000 | 0.004 | 0.004 | 0.000 | 0.004 | 0.006 | 0.000 | 0.003 | 0.001 |
BUV496(Cells) | FirstExperiment | ILTExperiment | UV710V502 | 71 | 0.005 | 0.027 | 0.017 | 0.023 | 0.010 | 0.156 | 1.000 | 0.537 | 0.216 | 0.057 | 0.010 | 0.005 | 0.000 | 0.000 | 0.000 | 0.000 | 0.004 | 0.000 | 0.000 | 0.031 | 0.154 | 0.093 | 0.069 | 0.024 | 0.003 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.036 | 0.015 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.006 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.0020 | 0.000 | 0.000 | 0.000 | 0.005 | 0.005 | 0.000 | 0.002 | 0.000 | 0.000 | 0.003 | 0.003 |
BUV563(Cells) | FirstExperiment | ILTExperiment | UV910YG105B402 | 2384 | 0.007 | 0.031 | 0.024 | 0.020 | 0.021 | 0.021 | 0.016 | 0.339 | 1.000 | 0.253 | 0.057 | 0.024 | 0.013 | 0.009 | 0.005 | 0.002 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.010 | 0.051 | 0.019 | 0.013 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.089 | 0.186 | 0.093 | 0.057 | 0.016 | 0.009 | 0.007 | 0.002 | 0.001 | 0.000 | 0.000 | 0.000 | 0.412 | 0.194 | 0.115 | 0.031 | 0.017 | 0.012 | 0.0080 | 0.002 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 |
BUV563(Cells) | FirstExperiment | ILTExperiment | UV910YG104B402 | 1639 | 0.009 | 0.033 | 0.026 | 0.023 | 0.025 | 0.028 | 0.029 | 0.345 | 1.000 | 0.252 | 0.057 | 0.024 | 0.013 | 0.009 | 0.005 | 0.002 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.011 | 0.051 | 0.019 | 0.013 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.084 | 0.177 | 0.088 | 0.053 | 0.013 | 0.008 | 0.005 | 0.001 | 0.000 | 0.000 | 0.000 | 0.000 | 0.388 | 0.185 | 0.109 | 0.029 | 0.015 | 0.010 | 0.0060 | 0.001 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 |
BUV563(Cells) | FirstExperiment | ILTExperiment | UV910YG105B403 | 496 | 0.007 | 0.030 | 0.023 | 0.020 | 0.021 | 0.020 | 0.015 | 0.340 | 1.000 | 0.253 | 0.056 | 0.023 | 0.012 | 0.009 | 0.004 | 0.002 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.012 | 0.054 | 0.020 | 0.014 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 | 0.097 | 0.206 | 0.100 | 0.061 | 0.017 | 0.010 | 0.007 | 0.002 | 0.001 | 0.001 | 0.000 | 0.000 | 0.419 | 0.197 | 0.117 | 0.032 | 0.017 | 0.012 | 0.0085 | 0.002 | 0.001 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 |
BUV615(Cells) | FirstExperiment | ILTExperiment | UV1010YG309V1003 | 95 | 0.014 | 0.039 | 0.027 | 0.031 | 0.031 | 0.051 | 0.058 | 0.040 | 0.242 | 1.000 | 0.408 | 0.220 | 0.120 | 0.112 | 0.064 | 0.031 | 0.008 | 0.016 | 0.013 | 0.011 | 0.019 | 0.016 | 0.022 | 0.032 | 0.097 | 0.260 | 0.088 | 0.044 | 0.025 | 0.013 | 0.010 | 0.000 | 0.000 | 0.004 | 0.007 | 0.002 | 0.036 | 0.066 | 0.032 | 0.019 | 0.021 | 0.008 | 0.002 | 0.000 | 0.001 | 0.001 | 0.079 | 0.383 | 0.843 | 0.385 | 0.288 | 0.221 | 0.1990 | 0.069 | 0.048 | 0.021 | 0.007 | 0.006 | 0.009 | 0.004 | 0.004 | 0.001 | 0.001 | 0.001 |
As you can see, we have returned a Luciernaga_QC()
style
output that we can now evaluate using Luciernaga_Plots()
as
described above:
ThePlotReport <- Luciernaga_Plots(data=ReportOutput, RetainedType="normalized", CellPopRatio=0.05,
outfolder=NULL, filename="LuciernagaReport", returntype="plots",
LinePlots=FALSE, CosinePlots=FALSE, StackedBarPlots = FALSE,
HeatmapPlots = TRUE, reference = PanelPath)
#> names not matching, no reorderring according to panel order
ThePlotReport[1]
#> [[1]]
#> [[1]][[1]]
Luciernaga_Brightness
One advantage of retrieving the data from LuciernagaQC()
ExportType = “fcs” outputs is that we can generate an additional type of
plot to look at the individual brightness for the cells that clustered
within the isolated signatures. This is accomplished by switching up a
couple arguments in Luciernaga_FCSToReport()
and passing
the intermediate to the Luciernaga_Brightness()
function
ReferencePath <- system.file("extdata", package = "Luciernaga")
PanelPath <- file.path(ReferencePath, "Panel.csv")
PanelNames <- read.csv(PanelPath, check.names = FALSE)
PanelNames <- PanelNames %>% filter(!str_detect(Fluorophore, "Pacific"))
PanelNames <- PanelNames %>% mutate(Fluorophore = case_when(
Fluorophore == "FITC" ~ "AlexaFluor488",
TRUE ~ Fluorophore # Keep all other values unchanged
))
PanelItems <- PanelNames %>% pull(Fluorophore) %>% gsub("-A", "", .)
BrightnessOutput <- Luciernaga_FCSToReport(path=StorageLocation, reference=PanelNames, stats="median",
RetainedType = "raw", experiment="FirstExperiment", condition="ILTExperiement",
TheSummary = FALSE)
PanelItems <- gsub(".", "", fixed=TRUE, PanelItems)
PanelItems <- gsub(" ", "", fixed=TRUE, PanelItems)
#PanelItems <- gsub("-", "", fixed=TRUE, PanelItems)
BrightnessOutput$Sample <- gsub(".", "", fixed=TRUE, BrightnessOutput$Sample)
BrightnessOutput$Sample <- gsub(" ", "", fixed=TRUE, BrightnessOutput$Sample)
#BrightnessOutput$Sample <- gsub("-", "", fixed=TRUE, BrightnessOutput$Sample)
BrightnessPlots <- map(.x=PanelItems[c(28:29)], .f=Luciernaga_Brightness, data=BrightnessOutput, reference=PanelNames, Scaled=TRUE)
ThePlot <- BrightnessPlots[[8]]
ThePlot
plotly::ggplotly(ThePlot)
In the above example, we needed to modify the list to exclude
PacificBlue Fluorophore that failed to generate in
Luciernaga_QC()
. The Panel.CSV also had a mismatch (FITC
instead AlexaFluor488) that we had to rename. And in my version the
APC-Fire810 bugged. So resolve these to fix this vignette :( and make it
easier to work with.
The resulting brightness plot is a geom_density plot showing the MFI for the respective clustered signatures. As you can tell from the ggplot2 object, a bunch of the signatures are relatively dim, which reflects the case seen in signatures.
Luciernaga_Lists
Luciernaga_Lists()
is a wrapper function that allows us
to merge in the Luciernaga_Brightness()
plots with
Luciernaga_Plots()
plots to generate a more complete view
of the fluorescent signatures for given samples. In addition to being
able to return a “pdf” plot, it can also be used to generate a “html”
output that is interactive (at the cost of being more storage space used
on your computer)
FinalPlots <- Luciernaga_Lists(ListOfList = TheMainPlots, SecondaryList = BrightnessPlots, thecolumns = 2,
therows = 3, width=9, height=7, ReturnFolder = ReferencePath,
CurrentExperiment = "Test", PlotType = "html")
Visualizing Longitudinally
All of the above functions focused their work primarily in the
context of visualizing the variation in Luciernaga_QC()
isolated fluorescent signatures within the context of a single
experiment. But what happens when we want to look longitudinally across
a series of experiments to monitor for tandem degradation in an antibody
vial, or pinpoint if the instrumental issue impacted fluorophore
signatures on a particular day?
The following functions are still in active development, and require a little more upfront coding on the part of the user to ensure that the data.frame object is tidy compatible, but we attach the workflow below.
Conclusion
And this concludes the vignette covering how to visualize the
Luciernaga_QC()
outputs to leverage insight into what is
occuring within individual fluorophores for a given experiment and
across time. Thanks for your patience and happy visualizing.
#> R version 4.4.1 (2024-06-14 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 22631)
#>
#> Matrix products: default
#>
#>
#> locale:
#> [1] LC_COLLATE=English_United States.utf8
#> [2] LC_CTYPE=English_United States.utf8
#> [3] LC_MONETARY=English_United States.utf8
#> [4] LC_NUMERIC=C
#> [5] LC_TIME=English_United States.utf8
#>
#> time zone: America/New_York
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] htmltools_0.5.8.1 plotly_4.10.4 gt_0.11.1
#> [4] stringr_1.5.1 purrr_1.0.2 dplyr_1.1.4
#> [7] data.table_1.16.2 ggcyto_1.32.0 ncdfFlow_2.50.0
#> [10] BH_1.84.0-0 ggplot2_3.5.1 openCyto_2.16.1
#> [13] flowWorkspace_4.16.0 flowCore_2.16.0 Luciernaga_0.99.1
#> [16] BiocStyle_2.32.1
#>
#> loaded via a namespace (and not attached):
#> [1] RBGL_1.80.0 gridExtra_2.3 rlang_1.1.4
#> [4] magrittr_2.0.3 matrixStats_1.4.1 ggridges_0.5.6
#> [7] compiler_4.4.1 dir.expiry_1.12.0 png_0.1-8
#> [10] systemfonts_1.1.0 vctrs_0.6.5 reshape2_1.4.4
#> [13] pkgconfig_2.0.3 fastmap_1.2.0 magick_2.8.5
#> [16] labeling_0.4.3 utf8_1.2.4 rmarkdown_2.28
#> [19] graph_1.82.0 ragg_1.3.3 xfun_0.48
#> [22] zlibbioc_1.50.0 cachem_1.1.0 jsonlite_1.8.9
#> [25] highr_0.11 SnowballC_0.7.1 parallel_4.4.1
#> [28] R6_2.5.1 bslib_0.8.0 stringi_1.8.4
#> [31] RColorBrewer_1.1-3 reticulate_1.39.0 lubridate_1.9.3
#> [34] jquerylib_0.1.4 figpatch_0.2 Rcpp_1.0.13
#> [37] bookdown_0.41 knitr_1.48 zoo_1.8-12
#> [40] Matrix_1.7-0 timechange_0.3.0 tidyselect_1.2.1
#> [43] rstudioapi_0.17.0 yaml_2.3.10 viridis_0.6.5
#> [46] lattice_0.22-6 tibble_3.2.1 plyr_1.8.9
#> [49] Biobase_2.64.0 basilisk.utils_1.16.0 withr_3.0.1
#> [52] evaluate_1.0.1 Rtsne_0.17 desc_1.4.3
#> [55] xml2_1.3.6 pillar_1.9.0 lsa_0.73.3
#> [58] BiocManager_1.30.25 filelock_1.0.3 stats4_4.4.1
#> [61] generics_0.1.3 S4Vectors_0.42.1 munsell_0.5.1
#> [64] scales_1.3.0 glue_1.8.0 lazyeval_0.2.2
#> [67] tools_4.4.1 hexbin_1.28.4 fs_1.6.4
#> [70] XML_3.99-0.17 grid_4.4.1 flowClust_3.42.0
#> [73] tidyr_1.3.1 RProtoBufLib_2.16.0 crosstalk_1.2.1
#> [76] colorspace_2.1-1 patchwork_1.3.0 basilisk_1.16.0
#> [79] cli_3.6.3 textshaping_0.4.0 fansi_1.0.6
#> [82] cytolib_2.16.0 viridisLite_0.4.2 uwot_0.2.2
#> [85] Rgraphviz_2.48.0 gtable_0.3.5 sass_0.4.9
#> [88] digest_0.6.37 BiocGenerics_0.50.0 htmlwidgets_1.6.4
#> [91] farver_2.1.2 pkgdown_2.1.1 lifecycle_1.0.4
#> [94] httr_1.4.7