The common data files (FCS files for the practical workshop) are located in /data/OpenCyto. The following will move the gating template csv file to your home directory under ~/data.

Please do not touch or modify the shared gating template. Work rather on your own copy.

# Common files
FCSPATH="/data/OpenCyto/data/FCS/"
WORKSPACE="/data/OpenCyto/data/workspace/080 batch 0882.xml"
OUTPATH="~"
MANUAL<-file.path(OUTPATH,"data","manual")
AUTO<-file.path(OUTPATH,"data","auto")
TEMPLATE="/data/OpenCyto/data/template/gt_080.csv"
ANNOTATIONS="/data/OpenCyto/data/workspace/pd_submit.csv"

# Move the template into your home directory
if(!file.exists("~/data")){
  dir.create("~/data")
}
file.copy(TEMPLATE,file.path("~/data",basename(TEMPLATE)),overwrite = TRUE)
## [1] TRUE
file.copy(ANNOTATIONS,file.path("~/data",basename(ANNOTATIONS)),overwrite = TRUE)
## [1] TRUE
TEMPLATE<-"~/data/gt_080.csv"
ANNOTATIONS<-"~/data/pd_submit.csv"

Load libraries

require(openCyto)
## Loading required package: openCyto
## Loading required package: flowWorkspace
## Loading required package: flowCore
## Loading required package: flowViz
## Loading required package: lattice
## KernSmooth 2.23 loaded
## Copyright M. P. Wand 1997-2009
## Loading required package: ncdfFlow
## Loading required package: gridExtra
## Loading required package: grid
require(ggplot2)
## Loading required package: ggplot2
require(plyr)
## Loading required package: plyr
require(reshape2)
## Loading required package: reshape2
require(data.table)
## Loading required package: data.table

Open the workspace

The first thing to do is open the workspace file.

ws<-openWorkspace(WORKSPACE)
show(ws)
## FlowJo Workspace Version  2.0 
## File location:  /data/OpenCyto/data/workspace 
## File name:  080 batch 0882.xml 
## Workspace is open. 
## 
## Groups in Workspace
##           Name Num.Samples
## 1  All Samples         158
## 2   0882-L-080         157
## 3        Comps          13
## 4 0882 Samples          76

We see different sample groups in the workspace. The data we’re concerned with is the 0882 Samples group. The data are already compensated and transformed.

Parse the workspace data

The following code snippet parses the contents of the workspace, loads the FCS data, compensates and transforms it according to the instructions in the FlowJo workspace file, and stores the results in a gating_set.
This can take some time depending on the bandwidth of the attached storage device (local vs network disk).
Some arguments to parseWorkspace
The name argument specifies which group to import.
The path argument tells flowWorkspace where to look for the FCS files.
The subset argument allows you to parse a subset of samples. It is a numeric index. The isNcdf argument allows you specify whether or not to use HDF5 / NetCDF for disk-based data access (TRUE), or whether to store the data in RAM (FALSE). Large data sets can’t practically be analyzed in RAM, set this to TRUE most of the time.

# Parse the worspace only if we haven't already done so, and save it.
if(!file.exists(MANUAL)){
  G<-parseWorkspace(ws,isNcdf=TRUE,name="0882 Samples",path=FCSPATH)
  save_gs(G,MANUAL)
}else{
  G<-load_gs(MANUAL)
}

G is now a GatingSet object. This is a set of GatingHierarchy objects, each of which represents an FCS file in the workspace / group that you imported.

Explore the GatingSet object

show(G)
## A GatingSet with 76 samples

We see the object G has 76 samples. The usual R operators can be used to subset the data. - Subset by index (not preferred) - Extract sample names - Subset by sample names (preferred)

G[1:10] # Subset by numeric index.. not the preferred way of doing things.
## A GatingSet with 10 samples
sampleNames(G)  # Get the sample names
##  [1] "769097.fcs" "769098.fcs" "769099.fcs" "769101.fcs" "769103.fcs"
##  [6] "769105.fcs" "769107.fcs" "769109.fcs" "769111.fcs" "769119.fcs"
## [11] "769121.fcs" "769122.fcs" "769124.fcs" "769125.fcs" "769127.fcs"
## [16] "769128.fcs" "769130.fcs" "769131.fcs" "769133.fcs" "769134.fcs"
## [21] "769136.fcs" "769137.fcs" "769145.fcs" "769147.fcs" "769149.fcs"
## [26] "769151.fcs" "769153.fcs" "769155.fcs" "769161.fcs" "769163.fcs"
## [31] "769165.fcs" "769167.fcs" "769169.fcs" "769171.fcs" "769177.fcs"
## [36] "769179.fcs" "769181.fcs" "769183.fcs" "769185.fcs" "769187.fcs"
## [41] "769193.fcs" "769195.fcs" "769197.fcs" "769199.fcs" "769201.fcs"
## [46] "769203.fcs" "769209.fcs" "769211.fcs" "769213.fcs" "769215.fcs"
## [51] "769217.fcs" "769219.fcs" "769225.fcs" "769227.fcs" "769229.fcs"
## [56] "769231.fcs" "769233.fcs" "769235.fcs" "769241.fcs" "769243.fcs"
## [61] "769245.fcs" "769247.fcs" "769249.fcs" "769251.fcs" "769257.fcs"
## [66] "769259.fcs" "769261.fcs" "769263.fcs" "769265.fcs" "769267.fcs"
## [71] "769273.fcs" "769275.fcs" "769277.fcs" "769279.fcs" "769281.fcs"
## [76] "769283.fcs"
G[sampleNames(G)[1:10]] # Subset by sample name.. preferred.
## A GatingSet with 10 samples

Visualize transformations

There is one data transformation per transformed channel. In this case there are no differences between the transformations on the different channels. The FlowJo transformation is a biexponential but it maps input data into “channel space” from 0 to 4095. The output data are effectively binned. flowWorkspace interpolate the transformation function to give continuous values between 0 and 4095.

raw<-seq(1,2.5e5,by=1000) #Input data range on the raw scale
transformed<-lapply(getTransformations(G[[1]]),function(x)matrix(x(raw))) # transform with each transformation
transformed<-do.call(cbind,transformed) # group output
colnames(transformed)<-gsub("^ ","",names(getTransformations(G[[1]])))
transformed<-melt(transformed)
transformed<-(cbind(transformed,raw))
setnames(transformed,c("index","parameter","transformed","raw"))
ggplot(data.frame(raw,transformed))+geom_line(aes(x=raw,y=transformed))+facet_wrap(~parameter)+theme_minimal()

plot of chunk unnamed-chunk-7

Compensation Matrices

We can extract the compensation matrices from the GatingSet as well, and visualize them.

getCompensationMatrices(G[[1]]) #Compensation for the first GatingHierarchy
## Compensation object 'defaultCompensation':
##                       FITC-A PerCP Cy55 Blue-A Pacific Blue-A  Am Cyan-A
## FITC-A             1.000e+00          0.117360      1.375e-03  9.008e-03
## PerCP Cy55 Blue-A  5.425e-06          1.000000      1.140e-04  3.689e-05
## Pacific Blue-A     5.084e-04          0.004963      1.000e+00  2.455e-02
## Am Cyan-A          4.314e-02          0.064777      4.833e-01  1.000e+00
## APC-A              2.848e-04          0.035541      2.395e-04  1.022e-04
## Alexa 680-A        3.616e-04          0.049498      2.752e-04  1.155e-04
## APC Cy7-A         -7.741e-04         -0.002257     -5.087e-04 -2.697e-04
## PE Green laser-A   2.025e-04          0.144410      8.921e-06  9.473e-06
## PE Tx RD-A         5.456e-04          0.915790      1.920e-04  4.865e-05
## PE Cy7-A           4.590e-04          0.048309      5.165e-05  2.110e-05
##                       APC-A Alexa 680-A APC Cy7-A PE Green laser-A
## FITC-A            0.0012730    0.001554 4.906e-04        0.0289250
## PerCP Cy55 Blue-A 0.0092128    0.390170 2.259e-02        0.0004728
## Pacific Blue-A    0.0012361    0.006692 1.086e-03        0.0014149
## Am Cyan-A         0.0197610    0.032842 2.797e-03        0.0350400
## APC-A             1.0000000    3.122700 1.409e-01        0.0010204
## Alexa 680-A       0.0020035    1.000000 7.197e-02        0.0007192
## APC Cy7-A         0.0150370    0.047991 1.000e+00       -0.0015137
## PE Green laser-A  0.0006007    0.001064 4.363e-05        1.0000000
## PE Tx RD-A        0.0039865    0.008877 4.263e-04        0.2067800
## PE Cy7-A          0.0003989    0.003547 3.853e-02        0.0505200
##                   PE Tx RD-A  PE Cy7-A
## FITC-A             0.0089330 0.0005243
## PerCP Cy55 Blue-A  0.0003445 0.0510200
## Pacific Blue-A     0.0011251 0.0011551
## Am Cyan-A          0.0274790 0.0058747
## APC-A              0.0008323 0.0153530
## Alexa 680-A        0.0008401 0.0152670
## APC Cy7-A         -0.0017165 0.1681300
## PE Green laser-A   0.2480800 0.0059821
## PE Tx RD-A         1.0000000 0.0522140
## PE Cy7-A           0.0141130 1.0000000
ggplot(melt(getCompensationMatrices(G[[1]])@spillover,value.name = "Coefficient"))+geom_tile(aes(x=Var1,y=Var2,fill=Coefficient))+scale_fill_continuous(guide="colourbar")+theme(axis.text.x=element_text(angle=45,hjust=1))

plot of chunk unnamed-chunk-8

Get the names of all manually derived pouplations

The getNodes function will extract the node names (population names) of all populations defined in a GatingSet or a GatingHierarchy.

getNodes(G)
##   [1] "root"                               
##   [2] "/S"                                 
##   [3] "/S/Lv"                              
##   [4] "/S/Lv/L"                            
##   [5] "/S/Lv/L/3+"                         
##   [6] "/S/Lv/L/3+/4+"                      
##   [7] "/S/Lv/L/3+/4+/57+"                  
##   [8] "/S/Lv/L/3+/4+/57-"                  
##   [9] "/S/Lv/L/3+/4+/Perforin+"            
##  [10] "/S/Lv/L/3+/4+/Granzyme B+"          
##  [11] "/S/Lv/L/3+/4+/Granzyme B-"          
##  [12] "/S/Lv/L/3+/4+/GZB+IFN+IL2+TNF+"     
##  [13] "/S/Lv/L/3+/4+/GZB+IFN+IL2+TNF-"     
##  [14] "/S/Lv/L/3+/4+/GZB+IFN+IL2-TNF+"     
##  [15] "/S/Lv/L/3+/4+/GZB+IFN+IL2-TNF-"     
##  [16] "/S/Lv/L/3+/4+/GZB+IFN-IL2+TNF+"     
##  [17] "/S/Lv/L/3+/4+/GZB+IFN-IL2+TNF-"     
##  [18] "/S/Lv/L/3+/4+/GZB+IFN-IL2-TNF+"     
##  [19] "/S/Lv/L/3+/4+/GZB+IFN-IL2-TNF-"     
##  [20] "/S/Lv/L/3+/4+/GZB-IFN+IL2+TNF+"     
##  [21] "/S/Lv/L/3+/4+/GZB-IFN+IL2+TNF-"     
##  [22] "/S/Lv/L/3+/4+/GZB-IFN+IL2-TNF+"     
##  [23] "/S/Lv/L/3+/4+/GZB-IFN+IL2-TNF-"     
##  [24] "/S/Lv/L/3+/4+/GZB-IFN-IL2+TNF+"     
##  [25] "/S/Lv/L/3+/4+/GZB-IFN-IL2+TNF-"     
##  [26] "/S/Lv/L/3+/4+/GZB-IFN-IL2-TNF+"     
##  [27] "/S/Lv/L/3+/4+/GZB-IFN-IL2-TNF-"     
##  [28] "/S/Lv/L/3+/4+/IFN+IL2+"             
##  [29] "/S/Lv/L/3+/4+/IFN+IL2+TNF+"         
##  [30] "/S/Lv/L/3+/4+/IFN+IL2+TNF-"         
##  [31] "/S/Lv/L/3+/4+/IFN+IL2-"             
##  [32] "/S/Lv/L/3+/4+/IFN+IL2-TNF+"         
##  [33] "/S/Lv/L/3+/4+/IFN+IL2-TNF-"         
##  [34] "/S/Lv/L/3+/4+/IFN-IL2+"             
##  [35] "/S/Lv/L/3+/4+/IFN-IL2+TNF+"         
##  [36] "/S/Lv/L/3+/4+/IFN-IL2+TNF-"         
##  [37] "/S/Lv/L/3+/4+/IFN-IL2-"             
##  [38] "/S/Lv/L/3+/4+/IFN-IL2-TNF+"         
##  [39] "/S/Lv/L/3+/4+/IFN-IL2-TNF-"         
##  [40] "/S/Lv/L/3+/4+/IFNg+"                
##  [41] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa+GzB+57+"
##  [42] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa+GzB+57-"
##  [43] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa+GzB-57+"
##  [44] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa+GzB-57-"
##  [45] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa-GzB+57+"
##  [46] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa-GzB+57-"
##  [47] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa-GzB-57+"
##  [48] "/S/Lv/L/3+/4+/IFNg+IL2+TNFa-GzB-57-"
##  [49] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa+GzB+57+"
##  [50] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa+GzB+57-"
##  [51] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa+GzB-57+"
##  [52] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa+GzB-57-"
##  [53] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa-GzB+57+"
##  [54] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa-GzB+57-"
##  [55] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa-GzB-57+"
##  [56] "/S/Lv/L/3+/4+/IFNg+IL2-TNFa-GzB-57-"
##  [57] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa+GzB+57+"
##  [58] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa+GzB+57-"
##  [59] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa+GzB-57+"
##  [60] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa+GzB-57-"
##  [61] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa-GzB+57+"
##  [62] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa-GzB+57-"
##  [63] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa-GzB-57+"
##  [64] "/S/Lv/L/3+/4+/IFNg-IL2+TNFa-GzB-57-"
##  [65] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa+GzB+57+"
##  [66] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa+GzB+57-"
##  [67] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa+GzB-57+"
##  [68] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa+GzB-57-"
##  [69] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa-GzB+57+"
##  [70] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa-GzB+57-"
##  [71] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa-GzB-57+"
##  [72] "/S/Lv/L/3+/4+/IFNg-IL2-TNFa-GzB-57-"
##  [73] "/S/Lv/L/3+/4+/IFN\\IL2"             
##  [74] "/S/Lv/L/3+/4+/IL2+"                 
##  [75] "/S/Lv/L/3+/4+/TNFa+"                
##  [76] "/S/Lv/L/3+/8+"                      
##  [77] "/S/Lv/L/3+/8+/57+"                  
##  [78] "/S/Lv/L/3+/8+/57-"                  
##  [79] "/S/Lv/L/3+/8+/Granzyme B+"          
##  [80] "/S/Lv/L/3+/8+/Granzyme B-"          
##  [81] "/S/Lv/L/3+/8+/GZB+IFN+IL2+TNF+"     
##  [82] "/S/Lv/L/3+/8+/GZB+IFN+IL2+TNF-"     
##  [83] "/S/Lv/L/3+/8+/GZB+IFN+IL2-TNF+"     
##  [84] "/S/Lv/L/3+/8+/GZB+IFN+IL2-TNF-"     
##  [85] "/S/Lv/L/3+/8+/GZB+IFN-IL2+TNF+"     
##  [86] "/S/Lv/L/3+/8+/GZB+IFN-IL2+TNF-"     
##  [87] "/S/Lv/L/3+/8+/GZB+IFN-IL2-TNF+"     
##  [88] "/S/Lv/L/3+/8+/GZB+IFN-IL2-TNF-"     
##  [89] "/S/Lv/L/3+/8+/GZB-IFN+IL2+TNF+"     
##  [90] "/S/Lv/L/3+/8+/GZB-IFN+IL2+TNF-"     
##  [91] "/S/Lv/L/3+/8+/GZB-IFN+IL2-TNF+"     
##  [92] "/S/Lv/L/3+/8+/GZB-IFN+IL2-TNF-"     
##  [93] "/S/Lv/L/3+/8+/GZB-IFN-IL2+TNF+"     
##  [94] "/S/Lv/L/3+/8+/GZB-IFN-IL2+TNF-"     
##  [95] "/S/Lv/L/3+/8+/GZB-IFN-IL2-TNF+"     
##  [96] "/S/Lv/L/3+/8+/GZB-IFN-IL2-TNF-"     
##  [97] "/S/Lv/L/3+/8+/IFN+IL2+"             
##  [98] "/S/Lv/L/3+/8+/IFN+IL2+TNF+"         
##  [99] "/S/Lv/L/3+/8+/IFN+IL2+TNF-"         
## [100] "/S/Lv/L/3+/8+/IFN+IL2-"             
## [101] "/S/Lv/L/3+/8+/IFN+IL2-TNF+"         
## [102] "/S/Lv/L/3+/8+/IFN+IL2-TNF-"         
## [103] "/S/Lv/L/3+/8+/IFN-IL2+"             
## [104] "/S/Lv/L/3+/8+/IFN-IL2+TNF+"         
## [105] "/S/Lv/L/3+/8+/IFN-IL2+TNF-"         
## [106] "/S/Lv/L/3+/8+/IFN-IL2-"             
## [107] "/S/Lv/L/3+/8+/IFN-IL2-TNF+"         
## [108] "/S/Lv/L/3+/8+/IFN-IL2-TNF-"         
## [109] "/S/Lv/L/3+/8+/IFNg+"                
## [110] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa+GzB+57+"
## [111] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa+GzB+57-"
## [112] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa+GzB-57+"
## [113] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa+GzB-57-"
## [114] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa-GzB+57+"
## [115] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa-GzB+57-"
## [116] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa-GzB-57+"
## [117] "/S/Lv/L/3+/8+/IFNg+IL2+TNFa-GzB-57-"
## [118] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa+GzB+57+"
## [119] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa+GzB+57-"
## [120] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa+GzB-57+"
## [121] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa+GzB-57-"
## [122] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa-GzB+57+"
## [123] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa-GzB+57-"
## [124] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa-GzB-57+"
## [125] "/S/Lv/L/3+/8+/IFNg+IL2-TNFa-GzB-57-"
## [126] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa+GzB+57+"
## [127] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa+GzB+57-"
## [128] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa+GzB-57+"
## [129] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa+GzB-57-"
## [130] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa-GzB+57+"
## [131] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa-GzB+57-"
## [132] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa-GzB-57+"
## [133] "/S/Lv/L/3+/8+/IFNg-IL2+TNFa-GzB-57-"
## [134] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa+GzB+57+"
## [135] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa+GzB+57-"
## [136] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa+GzB-57+"
## [137] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa+GzB-57-"
## [138] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa-GzB+57+"
## [139] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa-GzB+57-"
## [140] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa-GzB-57+"
## [141] "/S/Lv/L/3+/8+/IFNg-IL2-TNFa-GzB-57-"
## [142] "/S/Lv/L/3+/8+/IFN\\IL2"             
## [143] "/S/Lv/L/3+/8+/IL2+"                 
## [144] "/S/Lv/L/3+/8+/Perforin+"            
## [145] "/S/Lv/L/3+/8+/TNFa+"                
## [146] "/S/Lv/L/Not 4+"                     
## [147] "/S/Lv/L/Not 4+/IFNg+"

This manually gated data has 147 distinct populations.

Additional arguments to getNodes and getPopStats

The population names can be unwieldy and long. One particularly useful argument is the path= argument. You can set path="auto", which will extract the node name as the shortest unique path name for each cell population.

getNodes(G,path="auto")
##   [1] "root"                     "S"                       
##   [3] "Lv"                       "L"                       
##   [5] "3+"                       "4+"                      
##   [7] "4+/57+"                   "4+/57-"                  
##   [9] "4+/Perforin+"             "4+/Granzyme B+"          
##  [11] "4+/Granzyme B-"           "4+/GZB+IFN+IL2+TNF+"     
##  [13] "4+/GZB+IFN+IL2+TNF-"      "4+/GZB+IFN+IL2-TNF+"     
##  [15] "4+/GZB+IFN+IL2-TNF-"      "4+/GZB+IFN-IL2+TNF+"     
##  [17] "4+/GZB+IFN-IL2+TNF-"      "4+/GZB+IFN-IL2-TNF+"     
##  [19] "4+/GZB+IFN-IL2-TNF-"      "4+/GZB-IFN+IL2+TNF+"     
##  [21] "4+/GZB-IFN+IL2+TNF-"      "4+/GZB-IFN+IL2-TNF+"     
##  [23] "4+/GZB-IFN+IL2-TNF-"      "4+/GZB-IFN-IL2+TNF+"     
##  [25] "4+/GZB-IFN-IL2+TNF-"      "4+/GZB-IFN-IL2-TNF+"     
##  [27] "4+/GZB-IFN-IL2-TNF-"      "4+/IFN+IL2+"             
##  [29] "4+/IFN+IL2+TNF+"          "4+/IFN+IL2+TNF-"         
##  [31] "4+/IFN+IL2-"              "4+/IFN+IL2-TNF+"         
##  [33] "4+/IFN+IL2-TNF-"          "4+/IFN-IL2+"             
##  [35] "4+/IFN-IL2+TNF+"          "4+/IFN-IL2+TNF-"         
##  [37] "4+/IFN-IL2-"              "4+/IFN-IL2-TNF+"         
##  [39] "4+/IFN-IL2-TNF-"          "4+/IFNg+"                
##  [41] "4+/IFNg+IL2+TNFa+GzB+57+" "4+/IFNg+IL2+TNFa+GzB+57-"
##  [43] "4+/IFNg+IL2+TNFa+GzB-57+" "4+/IFNg+IL2+TNFa+GzB-57-"
##  [45] "4+/IFNg+IL2+TNFa-GzB+57+" "4+/IFNg+IL2+TNFa-GzB+57-"
##  [47] "4+/IFNg+IL2+TNFa-GzB-57+" "4+/IFNg+IL2+TNFa-GzB-57-"
##  [49] "4+/IFNg+IL2-TNFa+GzB+57+" "4+/IFNg+IL2-TNFa+GzB+57-"
##  [51] "4+/IFNg+IL2-TNFa+GzB-57+" "4+/IFNg+IL2-TNFa+GzB-57-"
##  [53] "4+/IFNg+IL2-TNFa-GzB+57+" "4+/IFNg+IL2-TNFa-GzB+57-"
##  [55] "4+/IFNg+IL2-TNFa-GzB-57+" "4+/IFNg+IL2-TNFa-GzB-57-"
##  [57] "4+/IFNg-IL2+TNFa+GzB+57+" "4+/IFNg-IL2+TNFa+GzB+57-"
##  [59] "4+/IFNg-IL2+TNFa+GzB-57+" "4+/IFNg-IL2+TNFa+GzB-57-"
##  [61] "4+/IFNg-IL2+TNFa-GzB+57+" "4+/IFNg-IL2+TNFa-GzB+57-"
##  [63] "4+/IFNg-IL2+TNFa-GzB-57+" "4+/IFNg-IL2+TNFa-GzB-57-"
##  [65] "4+/IFNg-IL2-TNFa+GzB+57+" "4+/IFNg-IL2-TNFa+GzB+57-"
##  [67] "4+/IFNg-IL2-TNFa+GzB-57+" "4+/IFNg-IL2-TNFa+GzB-57-"
##  [69] "4+/IFNg-IL2-TNFa-GzB+57+" "4+/IFNg-IL2-TNFa-GzB+57-"
##  [71] "4+/IFNg-IL2-TNFa-GzB-57+" "4+/IFNg-IL2-TNFa-GzB-57-"
##  [73] "4+/IFN\\IL2"              "4+/IL2+"                 
##  [75] "4+/TNFa+"                 "8+"                      
##  [77] "8+/57+"                   "8+/57-"                  
##  [79] "8+/Granzyme B+"           "8+/Granzyme B-"          
##  [81] "8+/GZB+IFN+IL2+TNF+"      "8+/GZB+IFN+IL2+TNF-"     
##  [83] "8+/GZB+IFN+IL2-TNF+"      "8+/GZB+IFN+IL2-TNF-"     
##  [85] "8+/GZB+IFN-IL2+TNF+"      "8+/GZB+IFN-IL2+TNF-"     
##  [87] "8+/GZB+IFN-IL2-TNF+"      "8+/GZB+IFN-IL2-TNF-"     
##  [89] "8+/GZB-IFN+IL2+TNF+"      "8+/GZB-IFN+IL2+TNF-"     
##  [91] "8+/GZB-IFN+IL2-TNF+"      "8+/GZB-IFN+IL2-TNF-"     
##  [93] "8+/GZB-IFN-IL2+TNF+"      "8+/GZB-IFN-IL2+TNF-"     
##  [95] "8+/GZB-IFN-IL2-TNF+"      "8+/GZB-IFN-IL2-TNF-"     
##  [97] "8+/IFN+IL2+"              "8+/IFN+IL2+TNF+"         
##  [99] "8+/IFN+IL2+TNF-"          "8+/IFN+IL2-"             
## [101] "8+/IFN+IL2-TNF+"          "8+/IFN+IL2-TNF-"         
## [103] "8+/IFN-IL2+"              "8+/IFN-IL2+TNF+"         
## [105] "8+/IFN-IL2+TNF-"          "8+/IFN-IL2-"             
## [107] "8+/IFN-IL2-TNF+"          "8+/IFN-IL2-TNF-"         
## [109] "8+/IFNg+"                 "8+/IFNg+IL2+TNFa+GzB+57+"
## [111] "8+/IFNg+IL2+TNFa+GzB+57-" "8+/IFNg+IL2+TNFa+GzB-57+"
## [113] "8+/IFNg+IL2+TNFa+GzB-57-" "8+/IFNg+IL2+TNFa-GzB+57+"
## [115] "8+/IFNg+IL2+TNFa-GzB+57-" "8+/IFNg+IL2+TNFa-GzB-57+"
## [117] "8+/IFNg+IL2+TNFa-GzB-57-" "8+/IFNg+IL2-TNFa+GzB+57+"
## [119] "8+/IFNg+IL2-TNFa+GzB+57-" "8+/IFNg+IL2-TNFa+GzB-57+"
## [121] "8+/IFNg+IL2-TNFa+GzB-57-" "8+/IFNg+IL2-TNFa-GzB+57+"
## [123] "8+/IFNg+IL2-TNFa-GzB+57-" "8+/IFNg+IL2-TNFa-GzB-57+"
## [125] "8+/IFNg+IL2-TNFa-GzB-57-" "8+/IFNg-IL2+TNFa+GzB+57+"
## [127] "8+/IFNg-IL2+TNFa+GzB+57-" "8+/IFNg-IL2+TNFa+GzB-57+"
## [129] "8+/IFNg-IL2+TNFa+GzB-57-" "8+/IFNg-IL2+TNFa-GzB+57+"
## [131] "8+/IFNg-IL2+TNFa-GzB+57-" "8+/IFNg-IL2+TNFa-GzB-57+"
## [133] "8+/IFNg-IL2+TNFa-GzB-57-" "8+/IFNg-IL2-TNFa+GzB+57+"
## [135] "8+/IFNg-IL2-TNFa+GzB+57-" "8+/IFNg-IL2-TNFa+GzB-57+"
## [137] "8+/IFNg-IL2-TNFa+GzB-57-" "8+/IFNg-IL2-TNFa-GzB+57+"
## [139] "8+/IFNg-IL2-TNFa-GzB+57-" "8+/IFNg-IL2-TNFa-GzB-57+"
## [141] "8+/IFNg-IL2-TNFa-GzB-57-" "8+/IFN\\IL2"             
## [143] "8+/IL2+"                  "8+/Perforin+"            
## [145] "8+/TNFa+"                 "Not 4+"                  
## [147] "Not 4+/IFNg+"

Operations that utilize node names can match a unique path to a node, so this gives an easy way to extract the shortest unique name for a cell population.

Extracting cell population statistics

getPopStats will extract cell population statistics, for a GatingSet or a GatingHierarchy. You can specify whether you want the cell counts or the cell frequencies.

freq_gs<-getPopStats(G[1:5],statistic="freq")
head(freq_gs)
##                     769097.fcs 769098.fcs 769099.fcs 769101.fcs 769103.fcs
## 3+                     0.79054    0.79106  0.8159666  7.163e-01  7.793e-01
## 4+                     0.63934    0.63238  0.6581814  6.150e-01  6.393e-01
## 4+/57+                 0.05689    0.05853  0.0489381  2.319e-02  1.078e-02
## 4+/57-                 0.94311    0.94147  0.9510619  9.768e-01  9.892e-01
## 4+/GZB+IFN+IL2+TNF+    0.00000    0.00000  0.0004208  1.506e-03  3.705e-04
## 4+/GZB+IFN+IL2+TNF-    0.00000    0.00000  0.0000000  8.425e-05  4.005e-05
counts_gh<-getPopStats(G[1:5],statistic="count")
head(counts_gh)
##                     769097.fcs 769098.fcs 769099.fcs 769101.fcs 769103.fcs
## 3+                      116492     111962     129990     154397     156216
## 4+                       74478      70802      85557      94950      99869
## 4+/57+                    4237       4144       4187       2202       1077
## 4+/57-                   70241      66658      81370      92748      98792
## 4+/GZB+IFN+IL2+TNF+          0          0         36        143         37
## 4+/GZB+IFN+IL2+TNF-          0          0          0          8          4

The output of getPopStats is a matrix wtih each entry representing the cell counts or cell frequencies (relative to the parent population) for a cell population and a sample.

Plotting

We can plot the gating tree for a sample or a set of samples using plot. To plot a gate use plotGate.

# The gating tree for this gating set
plot(G[[1]],boolean=FALSE)

plot of chunk plot

There is a lone IFNg+ gate floating, unattached to other nodes. If we look more closely at the node names, we see that its parent is “Not 4+”, which is hidden. We can set attributes of a node using setNode.

plot of chunk hiding_nodes

Plotting gates is done using plotGate. The infrastructre will extract the event-level data and plot it directly.

#plot one specific gate from one sample
p1<-plotGate(G[[2]],"4+/TNFa+",arrange=FALSE)
#plot one gate from two samples - automatic faceting
p2<-plotGate(G[2:3],"4+/TNFa+",arrange=FALSE)
#oops! population names must be unique
try(plotGate(G[1:2],"TNFa+"))

#binning using xbin (or not)
p4<-plotGate(G[[2]], "4+/TNFa+",xbin=128,arrange=FALSE)  #smaller bins (default is 32), more detail
# use gridExtra for layout
require(gridExtra)
grid.arrange(p1[[1]],p2,p4[[1]]) # Single plot is a list with element 1 being the plot object. Multiple plots are trellis objects directly.

plot of chunk plotGate

#plot an entire layout (boolean gates are skipped automatically)
p3<-plotGate(G[[2]]) # a little slower since we read all the event-level data. Arrange is TRUE by default
## skipping boolean gates!