# Automated alternative to the current manual gating practice In flowDensity: Sequential Flow Cytometry Data Gating

## Multiple calls for a single cell population identification

flowDensity can be used recursively to gate a cell population of interest. In the example below flowDensity has been used to gate lymphocytes'' from CD45 vs SSC. In order to gate lymphocytes more accurate and tighter, flowDensity can be called several times. First time it finds the thresholds for both channels, then returns SSC-CD45+ as an input for the second call. In the last call thresholds of CD45 from the first call and thresholds of SSC from the second call is given to flowDensity to draw ellipse around the lymphocyte population. In some cases CD45 has only one peak so the percentile of 0.25 is given to flowDensity to detect the right population. For SSC 0.85 would give the optimum threshold.

library(flowCore)
library(flowDensity)
data_dir <- system.file("extdata", package = "flowDensity")
load(list.files(pattern = 'sampleFCS_2', data_dir, full = TRUE))
f2
channels <- c("V500-A", "SSC-A")
# First call to flowDensity
tmp.cp1 <- flowDensity(obj=f2, channels=channels,
position=c(TRUE, FALSE), percentile=c(0.25, NA))
# Second call to flowDensity
tmp.cp2 <- flowDensity(obj=tmp.cp1, channels=channels,
position=c(TRUE, FALSE), gates=c(FALSE, NA),
percentile=c(NA, 0.85))
# Final call to flowDensity
lymph <- flowDensity(obj=f2, channels=channels,
position=c(TRUE, FALSE), gates=c(tmp.cp1@gates[1],
tmp.cp2@gates[2]), ellip.gate=TRUE, scale=.99)

plot(f2, tmp.cp1)

plot(f2, tmp.cp2)

par(mfrow=c(1,1))
plotDens(f2, channels=channels,axes=T)
lines(lymph@filter, type="l", col=2, lwd=2)
legend("topleft",legend = paste0("count: ",lymph@cell.count),bty = "n")


It is possible to extract the flowFrame object from CellPopulation, by getflowFrame() function.

getflowFrame(lymph)


### Gating cells using a control sample

To utilize matched control samples (e.g. FMO controls), the flowDensity(.) function has parameters that allow control data to be included. When this option is used, the gating threshold is calculated in the control data and applied to the stimulated data. Control samples are added using two parameters:

• use.control: When set to TRUE, flowDensity uses matched control data to calculate gating thresholds. This argument can be set for both channels. For example: use.control=c(TRUE, FALSE)}.
• control: This argument accepts flowFrame or CellPopulation objects containing control data matched to the specified stimulated data (passed in the obj argument). Control samples can be included for one or both of the channels. If no control is to be used, the argument should be passed an NA value (default). For example, if the first channel should be gated using a control but the second channel should be gated normally (using the stimulated data), the user would specify control=c(fmo.data, NA).

When control data is used, the other gating arguments (upper, percentile, n.sd, etc.) are applied to finding the threshold in the control sample instead of the stimulated sample.

For example, an FMO control (i.e. negative control) for the BV421-A channel can be used for gating as follows:

load(list.files(pattern = 'sampleFCS_3.Rdata', data_dir, full = TRUE))
f3
load(list.files(pattern = 'sampleFCS_3_FMO', data_dir, full = TRUE))
f3.fmo
f3.gated <- flowDensity(obj=f3, channels=c('BV421-A', 'FSC-A'),
position = c(TRUE, NA),use.control = c(TRUE, F)
, control = c(f3.fmo, NA),verbose=F)
f3.fmo.gated <- flowDensity(obj=f3.fmo, channels=c('BV421-A', 'FSC-A'),
position=c(TRUE, NA),
gates=c(f3.gated@gates[1], NA),verbose=F)
plot(f3.fmo, f3.fmo.gated)

plot(f3, f3.gated)


When only one peak is present in density, flowDensity prints out a message that can be suppressed by verbose=FALSE for each of the marker. This message prints out how cutoff was calculated based on the present arguments (percentile, upper, sd.threshold). For finer control, additional gating arguments can be passed that will be applied to the control sample. For example, the below example will gate using the 98-th percentile in control data:

f3.gated.98p <- flowDensity(obj=f3, channels=c('BV421-A', 'FSC-A'),
position = c(TRUE, NA),use.percentile = c(TRUE, NA),
percentile = 0.98, use.control = c(TRUE, FALSE),
control = c(f3.fmo, NA))
f3.fmo.gated.98p <- flowDensity(obj=f3.fmo, channels=c('BV421-A', 'FSC-A'),
position = c(TRUE, NA),
gates=c(f3.gated.98p@gates[1], NA))
plot(f3.fmo, f3.fmo.gated.98p)

plot(f3, f3.gated.98p)


Note: When using controls, setting position=TRUE will treat the data as a negative control and extract the population above the threshold. Setting position=FALSE will treat it as a positive control.

## Selecting threshold using deGate()

Another option beside flowDensity is deGate() function, which gives better control over cutoffs. The output is either a number or a vector of all possible cutoffs if all.cuts=T. In the example below, some of the possibilities are provided.

load(list.files(pattern = 'sampleFCS_2', data_dir, full = TRUE))
thresholds <- deGate(obj = f2,channel = 9)
#Percentile default is .95, which can be changed
thresholds.prcnt <- deGate(f2,channel = 9,use.percentile=T,percentile=.3)
thresholds.lo <- deGate(f2,channel = 9,use.upper=T,upper=F,alpha = .9)
thresholds.hi <- deGate(f2,channel = 9,use.upper=T,upper=T,alpha = .9)

plotDens(f2,c(9,12))
abline(v=c(thresholds,thresholds.prcnt,thresholds.lo,thresholds.hi),col=c(1,2,3,4))


## Gating using notSubFrame

Sometimes user would like to remove a population, and continue the gating sequence. This is possible using notSubFrame.

cd19.gate <- deGate(f, channel = 8)
cd20.gate <- deGate(f,channel = 9)
cd20.neg <- notSubFrame(f, channels = c(8,9),position = c(F,F),gates=c(cd19.gate,cd20.gate))
plotDens(f,c(8,9),axes=T)
lines(cd20.neg@filter, type="l")

plotDens(cd20.neg,c(8,9),main="Not CD19-CD20-")


# Latest update features

Multiple arguments have been added to deGate, and plotDens, please check the man page for these functions. Some of these arguments are:

• after.peak: When TRUE, it returns a cutoff that is after the maximum peaks.

• bimodal: When TRUE, it returns a cutoff that is after the maximum peaks.

• slope.w: Sets window.width for tracking the slope, when there is only one peak.

• count.lim: Minimum limit for events count in order to calculate the threshold. Default is 20.

• density.overlay: When c(TRUE,TRUE), it overlays density curves over the dot plot.

## Peak extraction

Function getPeaks returns all the peaks in a specified channel of flowFrame. It also takes a vector or density object as input.

load(list.files(pattern = 'sampleFCS_2', data_dir, full = TRUE))
getPeaks(f2,channel = 9)


You can specify the sensitivity of both getPeaks and deGate for small peaks, and twin peaks (peaks that are fairly close, and similar in height and their corresponding valleys). This can be done by tinypeak.removal and twin.factor. See ?deGate() for more detail.

## Density overlay

It is possible to overlay density curves over the bi-axial plot, using plotDens function.

load(list.files(pattern = 'sampleFCS_2', data_dir, full = TRUE))

plotDens(f2, channels = c(9,12),density.overlay = c(T,T))


# Licensing

Under the Artistic License, you are free to use and redistribute this software.

## Try the flowDensity package in your browser

Any scripts or data that you put into this service are public.

flowDensity documentation built on Nov. 8, 2020, 5:55 p.m.