# HG changeset patch
# User azomics
# Date 1592872234 14400
# Node ID c28c2e680bf525fb623ba82b4a38742c95a2c1b4
# Parent 78b8ab344edd0a47896ad29ebdf42ae82bc06018
"planemo upload for repository https://github.com/ImmPortDB/immport-galaxy-tools/tree/master/flowtools/fcs_gate_trans commit f34ed6ca8e77b9792a270890262c2936b13e30b9"
diff -r 78b8ab344edd -r c28c2e680bf5 FCSGateTrans.R
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FCSGateTrans.R Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,474 @@
+#!/usr/bin/env Rscript
+######################################################################
+# Copyright (c) 2016 Northrop Grumman.
+# All rights reserved.
+######################################################################
+# ImmPort FCS conversion program
+# Authors: Yue Liu and Yu "Max" Qian
+#
+# Reference: FCSTrans: An open source software system for FCS
+# file conversion and data transformation
+# Qian Y, Liu Y, Campbell J, Thomson E, Kong YM,
+# Scheuermann RH. 2012 Cytometry Part A. 81A(5)
+# doi.org/10.1002/cyto.a.22037
+#
+# To run in R
+# 1) library(flowCore)
+# 2) source("FCSTrans.R")
+# 3) transformFCS("filename")
+#
+#
+# Automated Gating of Lymphocytes with FlowDensity
+# Authors of FlowDensity: Jafar Taghiyar, Mehrnoush Malek
+#
+# Reference: flowDensity: reproducing manual gating of flow
+# cytometry data by automated density-based cell
+# population identification
+# Malek M, Taghiyar MJ, Chong L, Finak G,
+# Gottardo R, Brinkman RR. 2015 Bioinformatics 31(4)
+# doi: 10.1093/bioinformatics/btu677
+#
+#
+# Version 1.5
+# March 2016 -- added lines to run directly from command line (cristel thomas)
+# May 2016 -- added automated gating (cristel thomas)
+# August 2016 -- added options for data transformation (cristel thomas)
+# April 2017 -- added logicle to transformation options (cristel thomas)
+# July 2017 -- added options for outputs (cristel thomas)
+
+library(flowCore)
+library(flowDensity)
+library(GEOmap)
+#
+# Set output to 0 when input is less than cutoff value
+#
+ipfloor <- function (x, cutoff=0, target=0) {
+ y <- x
+ if (x <= cutoff) {
+ y <- target
+ }
+ return(y)
+}
+#
+# Set output to 0 when input is less than cutoff value
+#
+ipceil <- function (x, cutoff=0, target=0) {
+ y <- x
+ if (x >= cutoff) {
+ y <- target
+ }
+ return(y)
+}
+#
+# Calculation core of iplogicle
+#
+iplogicore <- function (x, w, r, d, scale) {
+ tol <- .Machine$double.eps^0.8
+ maxit <- as.integer(5000)
+ d <- d * log(10)
+ scale <- scale / d
+ p <- if (w == 0) {
+ 1
+ } else {
+ uniroot(function(p) -w + 2 * p * log(p)/(p + 1), c(.Machine$double.eps,
+ 2 * (w + d)))$root
+ }
+ a <- r * exp(-(d - w))
+ b <- 1
+ c <- r * exp(-(d - w)) * p^2
+ d <- 1/p
+ f <- a * (p^2 - 1)
+ y <- .Call("flowCore_biexponential_transform", PACKAGE= 'flowCore',
+ as.double(x), a, b, c, d, f, w, tol, maxit)
+ y <- sapply(y * scale, ipfloor)
+ return(y)
+}
+#
+# Function for calculating w
+#
+iplogiclew <- function (w, cutoff=-111, r=262144, d=4.5, scale=1) {
+ if (w > d)
+ w <- d
+ y <- iplogicore(cutoff, w, r, d, scale) - .Machine$double.eps^0.6
+ return(y)
+}
+#
+# ImmPort logicle function - convert fluorescent marker values to channel output
+#
+iplogicle <- function (x, r=262144, d=4.5, range=4096, cutoff=-111, w=-1) {
+ if (w > d) {
+ stop("Negative range decades must be smaller than total number of decades")
+ }
+ if (w < 0) {
+ w = uniroot(iplogiclew, c(0, d), cutoff=cutoff)$root
+ }
+ y <- iplogicore(x, w, r, d, range)
+ return(y)
+}
+#
+# Convert fluorescent values to channel output using log transformation
+#
+iplog <- function(x) {
+ x <- sapply(x, ipfloor, cutoff=1, target=1)
+ y <- 1024 * log10(x) - 488.6
+ return(y)
+}
+#
+# ImmPort linear function - convert scatter values to channel output
+# linear transformation
+#
+ipscatter <- function (x, channelrange=262144) {
+ y <- 4095.0 * x / channelrange
+ y <- sapply(y, ipfloor)
+ y <- sapply(y, ipceil, cutoff=4095, target=4095)
+ return(y)
+}
+#
+# ImmPort time function - convert time values to channel output
+# linear transformation
+iptime <- function (x, channelrange) {
+ # use simple cutoff for now
+ y <- sapply(x, ipfloor)
+ return(y)
+}
+#
+# Determine the type of marker. Marker type is used
+# to determine type of transformation to apply for this channel.
+# Before 2010 FLUO_AREA type used iplogicile and
+# FLOU_NON_AREA type used iplog. In 2010 Yue, changed code so
+# all fluorescent channels use iplogicle. Below is the note from SVN
+#
+# Version 1.1
+# 2010-07-02
+# -----------
+# Added data type checking on both FCS version 2 and 3
+# Removed log conversion for non-area fluorescent channel
+# Applied logicle conversion for all fluorescent channels
+#
+# The GenePattern version uses iplog for FLOU_NON_AREA, rather
+# than iplogicle.
+#
+getMarkerType <- function(name,debug=FALSE) {
+ type <- ""
+ prefix2 <- toupper(substr(name, 1, 2))
+ prefix3 <- toupper(substr(name, 1, 3))
+ prefix4 <- toupper(substr(name, 1, 4))
+ if (prefix2 == "FS" || prefix2 == "SS") {
+ type <- "SCATTER"
+ } else if (prefix3 == "FSC" || prefix3 == "SSC") {
+ type <- "SCATTER"
+ } else if (prefix4 == "TIME") {
+ type <- "TIME"
+ } else {
+ pieces <- unlist(strsplit(name, "-"))
+ if (toupper(pieces[length(pieces)]) == "A") {
+ type <- "FLUO_AREA"
+ } else {
+ type <- "FLUO_NON_AREA"
+ }
+ }
+ if (debug) {
+ print(paste("Marker:", name, ", Type:", type))
+ }
+ return(type)
+}
+#
+# Scale data
+#
+scaleData <- function(data, channelrange=0) {
+ datamax <- range(data)[2] # range() returns [min, max]
+ if (datamax > channelrange) {
+ channelrange <- datamax
+ }
+ #if (channelrange == 0) {
+ # channelrange = range(data)[2]
+ #}
+ data <- 262144 * data / channelrange
+ return(data)
+}
+#
+# Check if AccuriData. Accuri data needs different conversion
+#
+isAccuriData <- function(keywords) {
+ isTRUE(as.character(keywords$"$CYT") == "Accuri C6")
+}
+#
+# Convert FCS file
+#
+convertFCS <- function(fcs, debug=FALSE) {
+ # Check file type and FCS version
+ if (class(fcs)[1] != "flowFrame") {
+ print("convertFCS requires flowFrame object as input")
+ return(FALSE)
+ }
+ keywords <- keyword(fcs)
+ markers <- colnames(fcs)
+ params <- fcs@parameters
+ list_description <- fcs@description
+
+ if (debug) {
+ print("****Inside convertFCS")
+ print(paste(" FCS version:", keywords$FCSversion))
+ print(paste(" DATATYPE:", keywords['$DATATYPE']))
+ }
+ if (keywords$FCSversion == "2" || keywords$FCSversion == "3" ||
+ keywords$FCSversion == "3.1" ) {
+ datatype <- unlist(keywords['$DATATYPE'])
+ if (datatype == 'F') {
+ # Process fcs expression data, using transformation
+ # based on category of the marker.
+ fcs_exprs <- exprs(fcs)
+ fcs_channel <- NULL
+ for (i in 1:length(markers)){
+ markertype <- getMarkerType(markers[i], debug)
+ rangekeyword <- paste("$P", i, "R", sep="")
+ flowcore_min <- paste("flowCore_", rangekeyword, "min", sep="")
+ flowcore_max <- paste("flowCore_", rangekeyword, "max", sep="")
+ channelrange <- as.numeric(keywords[rangekeyword])
+ if (debug) {
+ print(paste(" Marker name:", markers[i]))
+ print(paste(" Marker type:", markertype))
+ print(paste(" Range value:", keywords[rangekeyword]))
+ }
+
+ if (markertype == "TIME") {
+ channel <- iptime(fcs_exprs[, i])
+ } else {
+ if (markertype == "SCATTER") {
+ channel <- ipscatter(scaleData(fcs_exprs[, i], channelrange))
+ } else {
+ # Apply logicle transformation on fluorescent channels
+ channel <- iplogicle(scaleData(fcs_exprs[, i], channelrange))
+ }
+ # adjust range in parameters and list description
+ if (params@data$range[i] > 4096){
+ params@data$range[i] <- 4096
+ params@data$minRange[i] <- 0
+ params@data$maxRange[i] <- 4096
+ list_description[rangekeyword] <- 4096
+ list_description[flowcore_min] <- 0
+ list_description[flowcore_max] <- 4096
+ }
+ }
+ fcs_channel <- cbind(fcs_channel, round(channel))
+ }
+ colnames(fcs_channel) <- markers
+ } else {
+ if (datatype != 'I') {
+ print(paste("Data type", datatype, "in FCS 3 is not supported"))
+ }
+ fcs_channel <- exprs(fcs)
+ colnames(fcs_channel) <- markers
+ }
+ } else {
+ print(paste("FCS version", keyword(fcs)$FCSversion, "is not supported"))
+ fcs_channel <- exprs(fcs)
+ colnames(fcs_channel) <- markers
+ }
+ newfcs <- flowFrame(fcs_channel, params, list_description)
+ return(newfcs)
+}
+#
+# Starting function for processing a FCS file
+#
+processFCSFile <- function(input_file, output_file="", compensate=FALSE,
+ outformat="flowtext", gate=FALSE,
+ graph_file="", report="", method="",
+ scaling_factor, logicle_w=0.5, logicle_t=262144,
+ logicle_m=4.5, debug=FALSE) {
+ #
+ # Generate the file names for the output_file
+ #
+ pieces <- unlist(strsplit(input_file, .Platform$file.sep))
+ filename <- pieces[length(pieces)]
+ if (debug) {
+ print (paste("Converting file: ",input_file))
+ print (paste("Original file name: ",filename))
+ print (paste("Output file name: ",output_file))
+ }
+ fcs <- read.FCS(input_file, transformation=F)
+ keywords <- keyword(fcs)
+ markers <- colnames(fcs)
+ print_markers <- as.vector(pData(parameters(fcs))$desc)
+ # Update print_markers if the $P?S not in the FCS file
+ for (i in 1:length(print_markers)) {
+ if (is.na(print_markers[i])) {
+ print_markers[[i]] <- markers[i]
+ }
+ }
+ #
+ # Compensate
+ #
+ spill <- keywords$SPILL
+
+ if (is.null(spill) == FALSE && compensate == TRUE) {
+ if (debug) {
+ print("Attempting compensation")
+ }
+ tryCatch({fcs = compensate(fcs, spill)},
+ error = function(ex) {str(ex); })
+ }
+ #
+ # Transform the data
+ #
+ transformed_data <- fcs
+ channels_to_exclude <- c(grep(colnames(fcs), pattern="FSC"),
+ grep(colnames(fcs), pattern="SSC"),
+ grep(colnames(fcs), pattern="Time"))
+ list_channels <- colnames(fcs)[-channels_to_exclude]
+ if (isAccuriData(keywords)) {
+ print("Accuri data is not supported")
+ } else if (method != "None"){
+ if (method == "fcstrans"){
+ transformed_data <- convertFCS(fcs, debug)
+ } else if (method == "logicle_auto"){
+ lgcl <- estimateLogicle(fcs, channels = list_channels)
+ transformed_data <- transform(fcs, lgcl)
+ } else {
+ if (method == "arcsinh"){
+ trans <- arcsinhTransform(transformationId="defaultArcsinhTransform",
+ a = 0, b = scaling_factor, c = 0)
+ } else if (method == "logicle"){
+ trans <- logicleTransform(w = logicle_w, t = logicle_t, m = logicle_m)
+ }
+ translist <- transformList(list_channels, trans)
+ transformed_data <- transform(fcs, translist)
+ }
+ }
+ trans_gated_data <- transformed_data
+ #
+ # Gate data
+ #
+ if (gate){
+ # check that there are SSC and FSC channels to gate on
+ chans <- c(grep(colnames(transformed_data), pattern="FSC"),
+ grep(colnames(transformed_data), pattern="SSC"))
+ totalchans <- chans
+ if (length(chans) > 2) {
+ #get first FSC and corresponding SSC
+ chans <- c(grep(colnames(transformed_data), pattern="FSC-A"),
+ grep(colnames(transformed_data), pattern="SSC-A"))
+ if (length(chans) == 0) {
+ chans <- c(grep(colnames(transformed_data), pattern="FSC-H"),
+ grep(colnames(transformed_data), pattern="SSC-H"))
+ if (length(chans) == 0) {
+ chans <- c(grep(colnames(transformed_data), pattern="FSC-W"),
+ grep(colnames(transformed_data), pattern="SSC-W"))
+ }
+ }
+ }
+ if (length(chans) == 0) {
+ warning('No forward/side scatter channels found, gating aborted.')
+ } else {
+ # gate lymphocytes
+ lymph <- flowDensity(obj=transformed_data, channels=chans,
+ position=c(TRUE, NA),
+ debris.gate=c(TRUE, FALSE))
+ # gate singlets if A and H/W
+ if (length(totalchans) > 2) {
+ trans_gated_data <- getflowFrame(flowDensity(obj=lymph,
+ singlet.gate=TRUE))
+ } else {
+ trans_gated_data <- getflowFrame(lymph)
+ }
+ # report
+ pregating_summary <- capture.output(summary(transformed_data))
+ pregating_dim <- capture.output(dim(transformed_data))
+ postgating_summary <- capture.output(summary(trans_gated_data))
+ postgating_dim <- capture.output(dim(trans_gated_data))
+ sink(report)
+ cat("#########################\n")
+ cat("## BEFORE GATING ##\n")
+ cat("#########################\n")
+ cat(pregating_dim, pregating_summary, sep="\n")
+ cat("\n#########################\n")
+ cat("## AFTER GATING ##\n")
+ cat("#########################\n")
+ cat(postgating_dim, postgating_summary, sep="\n")
+ sink()
+ # plots
+ time_channel <- grep(toupper(colnames(transformed_data)), pattern="TIME")
+ nb_markers <- length(colnames(transformed_data)) - length(time_channel)
+ nb_rows <- ceiling(((nb_markers-1)*nb_markers)/4)
+ h <- 400 * nb_rows
+ maxrange <- transformed_data@parameters@data$range[1]
+
+ png(graph_file, type="cairo", height=h, width=800)
+ par(mfrow=c(nb_rows,2))
+ for (m in 1:(nb_markers - 1)) {
+ for (n in (m+1):nb_markers) {
+ plotDens(transformed_data, c(m,n), xlab = print_markers[m],
+ ylab = print_markers[n], main = "Before Gating",
+ ylim = c(0, maxrange), xlim = c(0, maxrange))
+ plotDens(trans_gated_data, c(m,n), xlab = print_markers[m],
+ ylab = print_markers[n], main = "After Gating",
+ ylim = c(0, maxrange), xlim = c(0, maxrange))
+ }
+ }
+ dev.off()
+ }
+ }
+ if (outformat=="FCS") {
+ write.FCS(trans_gated_data, output_file)
+ } else if (outformat=="flowFrame") {
+ saveRDS(trans_gated_data, file = output_file)
+ } else {
+ output_data <- exprs(trans_gated_data)
+ colnames(output_data) <- print_markers
+ write.table(output_data, file=output_file, quote=F,
+ row.names=F,col.names=T, sep='\t', append=F)
+ }
+}
+# Convert FCS file using FCSTrans logicile transformation
+# @param input_file FCS file to be transformed
+# @param output_file FCS file transformed ".txt" extension
+# @param compensate Flag indicating whether to apply compensation
+# matrix if it exists.
+transformFCS <- function(input_file, output_file, compensate=FALSE,
+ outformat="flowtext", gate=FALSE, graph_file="",
+ report_file="", trans_met="", scaling_factor=1/150,
+ w=0.5, t=262144, m=4.5, debug=FALSE) {
+ isValid <- F
+ # Check file beginning matches FCS standard
+ tryCatch({
+ isValid <- isFCSfile(input_file)
+ }, error = function(ex) {
+ print (paste(" ! Error in isFCSfile", ex))
+ })
+ if (isValid) {
+ processFCSFile(input_file, output_file, compensate, outformat,
+ gate, graph_file, report_file, trans_met, scaling_factor,
+ w, t, m)
+ } else {
+ print (paste(input_file, "does not meet FCS standard"))
+ }
+}
+#
+# Run FCS Gate-Trans
+#
+args <- commandArgs(trailingOnly = TRUE)
+graphs <- ""
+report <- ""
+gate <- FALSE
+trans_method <- "None"
+scaling_factor <- 1 / 150
+w <- 0.5
+t <- 262144
+m <- 4.5
+if (args[5]!="None") {
+ gate <- TRUE
+ graphs <- args[5]
+ report <- args[6]
+}
+if (args[7]!="None"){
+ trans_method <- args[7]
+ if (args[7] == "arcsinh"){
+ scaling_factor <- 1 / as.numeric(args[8])
+ } else if (args[7] == "logicle"){
+ w <- args[8]
+ t <- args[9]
+ m <- args[10]
+ }
+}
+transformFCS(args[1], args[2], args[3], args[4], gate, graphs,
+ report, trans_method, scaling_factor, w, t, m)
diff -r 78b8ab344edd -r c28c2e680bf5 FCSGateTrans.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/FCSGateTrans.xml Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,175 @@
+
+ with optional compensation and automated gating with flowDensity.
+
+ bioconductor-flowdensity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (gate)
+
+
+ (gate)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.1002/cyto.a.22037
+ 10.1093/bioinformatics/btu677
+ 10.1186/1471-2105-10-106
+
+
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/FCSGateTrans.R
--- a/fcs_gate_trans/FCSGateTrans.R Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,454 +0,0 @@
-######################################################################
-# Copyright (c) 2016 Northrop Grumman.
-# All rights reserved.
-######################################################################
-# ImmPort FCS conversion program
-# Authors: Yue Liu and Yu "Max" Qian
-#
-# Reference: FCSTrans: An open source software system for FCS
-# file conversion and data transformation
-# Qian Y, Liu Y, Campbell J, Thomson E, Kong YM,
-# Scheuermann RH. 2012 Cytometry Part A. 81A(5)
-# doi.org/10.1002/cyto.a.22037
-#
-# To run in R
-# 1) library(flowCore)
-# 2) source("FCSTrans.R")
-# 3) transformFCS("filename")
-#
-#
-# Automated Gating of Lymphocytes with FlowDensity
-# Authors of FlowDensity: Jafar Taghiyar, Mehrnoush Malek
-#
-# Reference: flowDensity: reproducing manual gating of flow
-# cytometry data by automated density-based cell
-# population identification
-# Malek M, Taghiyar MJ, Chong L, Finak G,
-# Gottardo R, Brinkman RR. 2015 Bioinformatics 31(4)
-# doi: 10.1093/bioinformatics/btu677
-#
-#
-# Version 1.5
-# March 2016 -- added lines to run directly from command line (cristel thomas)
-# May 2016 -- added automated gating (cristel thomas)
-# August 2016 -- added options for data transformation (cristel thomas)
-
-library(flowCore)
-library(flowDensity)
-library(GEOmap)
-#
-# Set output to 0 when input is less than cutoff value
-#
-ipfloor <- function (x, cutoff=0, target=0) {
- y <- x
- if (x <= cutoff) {
- y <- target
- }
- return(y)
-}
-#
-# Set output to 0 when input is less than cutoff value
-#
-ipceil <- function (x, cutoff=0, target=0) {
- y <- x
- if (x >= cutoff) {
- y <- target
- }
- return(y)
-}
-#
-# Calculation core of iplogicle
-#
-iplogicore <- function (x, w, r, d, scale) {
- tol <- .Machine$double.eps^0.8
- maxit <- as.integer(5000)
- d <- d * log(10)
- scale <- scale / d
- p <- if (w == 0) {
- 1
- } else {
- uniroot(function(p) -w + 2 * p * log(p)/(p + 1), c(.Machine$double.eps,
- 2 * (w + d)))$root
- }
- a <- r * exp(-(d - w))
- b <- 1
- c <- r * exp(-(d - w)) * p^2
- d <- 1/p
- f <- a * (p^2 - 1)
- y <- .Call("flowCore_biexponential_transform", PACKAGE= 'flowCore',
- as.double(x), a, b, c, d, f, w, tol, maxit)
- y <- sapply(y * scale, ipfloor)
- return(y)
-}
-#
-# Function for calculating w
-#
-iplogiclew <- function (w, cutoff=-111, r=262144, d=4.5, scale=1) {
- if (w > d)
- w <- d
- y <- iplogicore(cutoff, w, r, d, scale) - .Machine$double.eps^0.6
- return(y)
-}
-#
-# ImmPort logicle function - convert fluorescent marker values to channel output
-#
-iplogicle <- function (x, r=262144, d=4.5, range=4096, cutoff=-111, w=-1) {
- if (w > d) {
- stop("Negative range decades must be smaller than total number of decades")
- }
- if (w < 0) {
- w = uniroot(iplogiclew, c(0, d), cutoff=cutoff)$root
- }
- y <- iplogicore(x, w, r, d, range)
- return(y)
-}
-#
-# Convert fluorescent values to channel output using log transformation
-#
-iplog <- function(x) {
- x <- sapply(x, ipfloor, cutoff=1, target=1)
- y <- 1024 * log10(x) - 488.6
- return(y)
-}
-#
-# ImmPort linear function - convert scatter values to channel output
-# linear transformation
-#
-ipscatter <- function (x, channelrange=262144) {
- y <- 4095.0 * x / channelrange
- y <- sapply(y, ipfloor)
- y <- sapply(y, ipceil, cutoff=4095, target=4095)
- return(y)
-}
-#
-# ImmPort time function - convert time values to channel output
-# linear transformation
-iptime <- function (x, channelrange) {
- # use simple cutoff for now
- y <- sapply(x, ipfloor)
- return(y)
-}
-#
-# Determine the type of marker. Marker type is used
-# to determine type of transformation to apply for this channel.
-# Before 2010 FLUO_AREA type used iplogicile and
-# FLOU_NON_AREA type used iplog. In 2010 Yue, changed code so
-# all fluorescent channels use iplogicle. Below is the note from SVN
-#
-# Version 1.1
-# 2010-07-02
-# -----------
-# Added data type checking on both FCS version 2 and 3
-# Removed log conversion for non-area fluorescent channel
-# Applied logicle conversion for all fluorescent channels
-#
-# The GenePattern version uses iplog for FLOU_NON_AREA, rather
-# than iplogicle.
-#
-getMarkerType <- function(name,debug=FALSE) {
- type <- ""
- prefix2 <- toupper(substr(name, 1, 2))
- prefix3 <- toupper(substr(name, 1, 3))
- prefix4 <- toupper(substr(name, 1, 4))
- if (prefix2 == "FS" || prefix2 == "SS") {
- type <- "SCATTER"
- } else if (prefix3 == "FSC" || prefix3 == "SSC") {
- type <- "SCATTER"
- } else if (prefix4 == "TIME") {
- type <- "TIME"
- } else {
- pieces <- unlist(strsplit(name, "-"))
- if (toupper(pieces[length(pieces)]) == "A") {
- type <- "FLUO_AREA"
- } else {
- type <- "FLUO_NON_AREA"
- }
- }
- if (debug) {
- print(paste("Marker:", name, ", Type:", type))
- }
- return(type)
-}
-#
-# Scale data
-#
-scaleData <- function(data, channelrange=0) {
- datamax <- range(data)[2] # range() returns [min, max]
- if (datamax > channelrange) {
- channelrange <- datamax
- }
- #if (channelrange == 0) {
- # channelrange = range(data)[2]
- #}
- data <- 262144 * data / channelrange
- return(data)
-}
-#
-# Check if AccuriData. Accuri data needs different conversion
-#
-isAccuriData <- function(keywords) {
- isTRUE(as.character(keywords$"$CYT") == "Accuri C6")
-}
-#
-# Convert FCS file
-#
-convertFCS <- function(fcs,compensate=FALSE,debug=FALSE) {
- # Check file type and FCS version
- if (class(fcs)[1] != "flowFrame") {
- print("convertFCS requires flowFrame object as input")
- return(FALSE)
- }
- keywords <- keyword(fcs)
- markers <- colnames(fcs)
- params <- fcs@parameters
- list_description <- fcs@description
-
- if (debug) {
- print("****Inside convertFCS")
- print(paste(" FCS version:", keywords$FCSversion))
- print(paste(" DATATYPE:", keywords['$DATATYPE']))
- }
- if (keywords$FCSversion == "2" || keywords$FCSversion == "3" ||
- keywords$FCSversion == "3.1" ) {
- datatype <- unlist(keywords['$DATATYPE'])
- if (datatype == 'F') {
- # Apply compensation if available and requested
- spill <- keyword(fcs)$SPILL
-
- if (is.null(spill) == FALSE && compensate == TRUE) {
- if (debug) {
- print("Attempting compensation")
- }
- tryCatch({fcs = compensate(fcs, spill)},
- error = function(ex) {str(ex); })
- }
- # Process fcs expression data, using transformation
- # based on category of the marker.
- fcs_exprs <- exprs(fcs)
- fcs_channel <- NULL
- for (i in 1:length(markers)){
- markertype <- getMarkerType(markers[i], debug)
- rangekeyword <- paste("$P", i, "R", sep="")
- flowcore_min <- paste("flowCore_", rangekeyword, "min", sep="")
- flowcore_max <- paste("flowCore_", rangekeyword, "max", sep="")
- channelrange <- as.numeric(keywords[rangekeyword])
- if (debug) {
- print(paste(" Marker name:", markers[i]))
- print(paste(" Marker type:", markertype))
- print(paste(" Range value:", keywords[rangekeyword]))
- }
-
- if (markertype == "TIME") {
- channel <- iptime(fcs_exprs[, i])
- } else {
- if (markertype == "SCATTER") {
- channel <- ipscatter(scaleData(fcs_exprs[, i], channelrange))
- } else {
- # Apply logicle transformation on fluorescent channels
- channel <- iplogicle(scaleData(fcs_exprs[, i], channelrange))
- }
- # adjust range in parameters and list description
- if (params@data$range[i] > 4096){
- params@data$range[i] <- 4096
- params@data$minRange[i] <- 0
- params@data$maxRange[i] <- 4096
- list_description[rangekeyword] <- 4096
- list_description[flowcore_min] <- 0
- list_description[flowcore_max] <- 4096
- }
- }
- fcs_channel <- cbind(fcs_channel, round(channel))
- }
- colnames(fcs_channel) <- markers
- } else {
- if (datatype != 'I') {
- print(paste("Data type", datatype, "in FCS 3 is not supported"))
- }
- fcs_channel <- exprs(fcs)
- colnames(fcs_channel) <- markers
- }
- } else {
- print(paste("FCS version", keyword(fcs)$FCSversion, "is not supported"))
- fcs_channel <- exprs(fcs)
- colnames(fcs_channel) <- markers
- }
- newfcs <- flowFrame(fcs_channel, params, list_description)
- return(newfcs)
-}
-#
-# Starting function for processing a FCS file
-#
-processFCSFile <- function(input_file, output_file="", compensate=FALSE,
- fcsformat=FALSE, fcsfile="",
- gate=FALSE, graph_file="", report="", method="",
- scaling_factor, debug=FALSE) {
- #
- # Generate the file names for the output_file
- #
- pieces <- unlist(strsplit(input_file, .Platform$file.sep))
- filename <- pieces[length(pieces)]
-
- if (debug) {
- print (paste("Converting file: ",input_file))
- print (paste("Original file name: ",filename))
- print (paste("Output file name: ",output_file))
- }
- fcs <- read.FCS(input_file, transformation=F)
- keywords <- keyword(fcs)
- markers <- colnames(fcs)
- print_markers <- as.vector(pData(parameters(fcs))$desc)
- # Update print_markers if the $P?S not in the FCS file
- for (i in 1:length(print_markers)) {
- if (is.na(print_markers[i])) {
- print_markers[i] <- markers[i]
- }
- }
- #
- # Transform the data
- #
- transformed_data <- fcs
- if (isAccuriData(keywords)) {
- print("Accuri data is not supported")
- } else {
- if (method == "arcsinh"){
- channels_to_exclude <- c(grep(colnames(fcs), pattern="FSC"),
- grep(colnames(fcs), pattern="SSC"),
- grep(colnames(fcs), pattern="Time"))
- list_channels <- colnames(fcs)[-channels_to_exclude]
- trans <- arcsinhTransform(transformationId="defaultArcsinhTransform",
- a = 0, b = scaling_factor, c = 0)
- translist <- transformList(list_channels, trans)
- transformed_data <- transform(fcs, translist)
- } else if (method == "logicle"){
- transformed_data <- convertFCS(fcs,compensate,debug)
- }
- }
- trans_gated_data <- transformed_data
- #
- # Gate data
- #
- if (gate){
- # check that there are SSC and FSC channels to gate on
- chans <- c(grep(colnames(transformed_data), pattern="FSC"),
- grep(colnames(transformed_data), pattern="SSC"))
- totalchans <- chans
- if (length(chans) > 2) {
- #get first FSC and corresponding SSC
- chans <- c(grep(colnames(transformed_data), pattern="FSC-A"),
- grep(colnames(transformed_data), pattern="SSC-A"))
- if (length(chans) == 0) {
- chans <- c(grep(colnames(transformed_data), pattern="FSC-H"),
- grep(colnames(transformed_data), pattern="SSC-H"))
- if (length(chans) == 0) {
- chans <- c(grep(colnames(transformed_data), pattern="FSC-W"),
- grep(colnames(transformed_data), pattern="SSC-W"))
- }
- }
- }
- if (length(chans) == 0) {
- warning('No forward/side scatter channels found, gating aborted.')
- } else {
- # gate lymphocytes
- lymph <- flowDensity(obj=transformed_data, channels=chans,
- position=c(TRUE, NA),
- debris.gate=c(TRUE, FALSE))
- # gate singlets if A and H/W
- if (length(totalchans) > 2) {
- trans_gated_data <- getflowFrame(flowDensity(obj=lymph,
- singlet.gate=TRUE))
- } else {
- trans_gated_data <- getflowFrame(lymph)
- }
- # report
- pregating_summary <- capture.output(summary(transformed_data))
- pregating_dim <- capture.output(dim(transformed_data))
- postgating_summary <- capture.output(summary(trans_gated_data))
- postgating_dim <- capture.output(dim(trans_gated_data))
- sink(report)
- cat("#########################\n")
- cat("## BEFORE GATING ##\n")
- cat("#########################\n")
- cat(pregating_dim, pregating_summary, sep="\n")
- cat("\n#########################\n")
- cat("## AFTER GATING ##\n")
- cat("#########################\n")
- cat(postgating_dim, postgating_summary, sep="\n")
- sink()
- # plots
- pdf(graph_file, useDingbats=FALSE, onefile=TRUE)
- par(mfrow=c(2,2))
- time_channel <- grep(toupper(colnames(transformed_data)), pattern="TIME")
- nb_markers <- length(colnames(transformed_data)) - length(time_channel)
- maxrange <- transformed_data@parameters@data$range[1]
- for (m in 1:(nb_markers - 1)) {
- for (n in (m+1):nb_markers) {
- plotDens(transformed_data, c(m,n), xlab = print_markers[m],
- ylab = print_markers[n], main = "Before Gating",
- ylim = c(0, maxrange), xlim = c(0, maxrange))
- plotDens(trans_gated_data, c(m,n), xlab = print_markers[m],
- ylab = print_markers[n], main = "After Gating",
- ylim = c(0, maxrange), xlim = c(0, maxrange))
- }
- }
- dev.off()
- }
- }
- if (fcsformat) {
- write.FCS(trans_gated_data, fcsfile)
- }
- output_data <- exprs(trans_gated_data)
- colnames(output_data) <- print_markers
- write.table(output_data, file=output_file, quote=F,
- row.names=F,col.names=T, sep='\t', append=F)
-}
-# Convert FCS file using FCSTrans logicile transformation
-# @param input_file FCS file to be transformed
-# @param output_file FCS file transformed ".txt" extension
-# @param compensate Flag indicating whether to apply compensation
-# matrix if it exists.
-transformFCS <- function(input_file, output_file, compensate=FALSE,
- fcsformat=FALSE, fcsfile="", gate=FALSE, graph_file="",
- report_file="", trans_met="", scaling_factor="",
- debug=FALSE) {
- isValid <- F
- # Check file beginning matches FCS standard
- tryCatch({
- isValid = isFCSfile(input_file)
- }, error = function(ex) {
- print (paste(" ! Error in isFCSfile", ex))
- })
- if (isValid) {
- processFCSFile(input_file, output_file, compensate, fcsformat, fcsfile,
- gate, graph_file, report_file, trans_met, scaling_factor)
- } else {
- print (paste(input_file, "does not meet FCS standard"))
- }
-}
-#
-# Run FCS Gate-Trans
-#
-args <- commandArgs(trailingOnly = TRUE)
-graphs <- ""
-report <- ""
-fcsoutput_file <- ""
-fcsoutput <- FALSE
-gate <- FALSE
-trans_method <- "None"
-scaling_factor <- 1 / 150
-if (args[5]!="None") {
- fcsoutput <- TRUE
- fcsoutput_file <- args[5]
-}
-if (args[6]!="None") {
- gate <- TRUE
- graphs <- args[6]
- report <- args[7]
-}
-if (args[8]!="None"){
- trans_method <- args[8]
- if (args[8] == "arcsinh"){
- scaling_factor <- 1 / as.numeric(args[9])
- }
-}
-transformFCS(args[2], args[3], args[4], fcsoutput, fcsoutput_file, gate, graphs,
- report, trans_method, scaling_factor)
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/FCSGateTrans.xml
--- a/fcs_gate_trans/FCSGateTrans.xml Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-
- using FlowDensity and the FCSTrans tranformation.
-
- r
- bioconductor-flowcore
- bioconductor-flowdensity
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- format=="TRUE"
-
-
- gate=="TRUE"
-
-
- gate=="TRUE"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 10.1002/cyto.a.22037
- 10.1093/bioinformatics/btu677
- 10.1186/1471-2105-10-106
-
-
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/static/images/flowdensity.png
Binary file fcs_gate_trans/static/images/flowdensity.png has changed
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/arcsinh150.flowtext
--- a/fcs_gate_trans/test-data/arcsinh150.flowtext Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
-9081 8811 19575.009765625 18578 -0.487166708542563 3.35237355048648 1.37750753926965 0.127057863991919 0.0255972040496283 0.866588972868883 0.760737973767117 2.53759317435759 0
-13879.5 11372 76400.875 66800 -0.455305138250274 0.963556030409229 0.915968891776551 0.511296170657329 0.339065738526448 0.531430131763512 -0.0326608602630583 -0.0783199078087399 0
-53197.5 49698 32821.8828125 30290 1.26289278746875 2.94666707290312 1.14932176211125 0.429535971137743 2.2879860496209 2.40333638820057 -0.0587661676654274 0.264762535136808 0
-94011.75 85861 46558.33203125 45425 -0.361914067420137 1.0099842999029 2.09568229265804 0.645771470660991 2.00391041851356 5.22898742425766 0.277363344871173 0.226719371107561 0.100000001490116
-56965.5 51060 42377.79296875 41492 3.34704579398504 5.11946885007392 1.24661362703293 4.79178721936253 3.51920619886312 3.47901108455652 2.12708633691257 3.11956116515719 0.100000001490116
-102877.5 91646 74486.234375 70382 3.67436877786622 4.72663049856952 1.57481462914001 1.37173870350081 5.15150145193671 4.8565806734818 1.59337073197003 1.13689659390179 0.200000002980232
-170482.5 135955 126331.6640625 106115 1.08590805588046 4.06062066240107 3.22122665934363 2.95167516373086 2.51312270311573 5.0850832349334 1.33604037616411 2.53656608596143 0.200000002980232
-140555.25 100224 108512.046875 72196 0.986973889697097 2.66146938806969 2.92800487646568 1.81362880902413 2.92526952883318 5.79683993164786 1.14069148921356 1.02981250583848 0.200000002980232
-46518.75 37218 138006.046875 113970 0.478108970811769 2.930079809471 3.47524128111705 2.31934440314287 1.78816416611445 4.6146323442977 1.1444747475952 1.25623958268597 0.200000002980232
-11892.75 11583 10502.310546875 10123 -0.245784525134546 1.17763111672424 0.362101658041819 0.322006394180742 -0.0511776555829312 0.0511776555829312 -0.0848315483504115 0.424837896402236 0.300000011920929
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/comp_gated.fcs
Binary file fcs_gate_trans/test-data/comp_gated.fcs has changed
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/graph.pdf
Binary file fcs_gate_trans/test-data/graph.pdf has changed
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/nocomp.flowtext
--- a/fcs_gate_trans/test-data/nocomp.flowtext Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
-142 138 306 290 133 2178 1297 546 478 1018 955 1835 0
-217 178 1193 1043 154 1074 1047 800 688 813 438 407 0
-831 776 513 473 1237 2009 1177 747 1726 1776 421 638 0
-1469 1341 727 710 217 1100 1640 885 1598 2935 647 613 0
-890 798 662 648 2176 2891 1229 2760 2246 2230 1654 2081 0
-1607 1432 1164 1099 2310 2734 1395 1294 2904 2786 1404 1170 0
-2663 2124 1973 1658 1142 2467 2124 2011 1824 2877 1275 1834 0
-2196 1566 1695 1128 1087 1888 2001 1510 2000 3160 1172 1111 0
-727 581 2156 1780 779 2002 2228 1739 1498 2689 1174 1234 0
-186 181 164 158 295 1192 703 677 426 495 403 744 0
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/notrans.flowtext
--- a/fcs_gate_trans/test-data/notrans.flowtext Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
-9081 8811 19575.009765625 18578 -76 2140.15991210938 278.460021972656 19.1100006103516 3.83999991416931 146.879989624023 125.440002441406 942.760009765625 0
-13879.5 11372 76400.875 66800 -70.6800003051758 167.959991455078 157.43000793457 80.0800018310547 51.8400001525879 83.5199966430664 -4.90000009536743 -11.7600002288818 0
-53197.5 49698 32821.8828125 30290 243.959991455078 1424.23999023438 212.940002441406 66.4300003051758 731.519958496094 822.719970703125 -8.81999969482422 40.1800003051758 0
-94011.75 85861 46558.33203125 45425 -55.4799995422363 178.599990844727 600.600036621094 103.740005493164 546.239990234375 13994.8798828125 42.1399993896484 34.2999992370605 0.100000001490116
-56965.5 51060 42377.79296875 41492 2128.76000976562 12543.0400390625 239.330001831055 9038.1201171875 2529.59985351562 2429.76000976562 620.340026855469 1694.42004394531 0.100000001490116
-102877.5 91646 74486.234375 70382 2954.8798828125 8467.919921875 346.710021972656 276.640014648438 12951.359375 9643.2001953125 353.779998779297 209.720001220703 0.200000002980232
-170482.5 135955 126331.6640625 106115 196.839996337891 4349.47998046875 1876.42004394531 1431.43005371094 919.679992675781 12119.0400390625 265.580017089844 941.780029296875 0.200000002980232
-140555.25 100224 108512.046875 72196 173.279998779297 1068.55993652344 1397.76000976562 447.720001220703 1393.919921875 24694.080078125 210.699996948242 183.260009765625 0.200000002980232
-46518.75 37218 138006.046875 113970 74.4799957275391 1400.67993164062 2420.60009765625 755.300048828125 435.839996337891 7570.56005859375 211.68000793457 242.059997558594 0.200000002980232
-11892.75 11583 10502.310546875 10123 -37.2399978637695 220.399993896484 55.5100021362305 49.1400032043457 -7.67999982833862 7.67999982833862 -12.7399997711182 65.6600036621094 0.300000011920929
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/report.txt
--- a/fcs_gate_trans/test-data/report.txt Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-=========================
-== BEFORE GATING ==
-=========================
- events parameters
- 10 13
- FSC-A FSC-H SSC-A SSC-H APC-A APC-H7-A FITC-A PerCP-Cy5-5-A V450-A
-Min. 142.0 138.0 164.0 158.0 89.0 1094 603 363 387.0
-1st Qu. 344.5 281.0 550.2 516.8 179.0 1328 1068 675 501.2
-Median 860.5 787.0 945.5 876.5 564.5 1977 1214 913 1214.0
-Mean 1093.0 911.5 1055.0 898.7 811.7 1923 1284 1183 1271.0
-3rd Qu. 1572.0 1409.0 1570.0 1121.0 1141.0 2348 1421 1505 1663.0
-Max. 2663.0 2124.0 2156.0 1780.0 2300.0 2830 2175 2756 2904.0
- V500-A PE-A PE-Cy7-A Time
-Min. 0.0 0.0 140.0 0
-1st Qu. 701.2 5.0 463.2 0
-Median 1427.0 152.5 849.0 0
-Mean 1657.0 379.3 968.1 0
-3rd Qu. 2816.0 480.5 1578.0 0
-Max. 3155.0 1484.0 1835.0 0
-
-=========================
-== AFTER GATING ==
-=========================
- events parameters
- 9 13
- FSC-A FSC-H SSC-A SSC-H APC-A APC-H7-A FITC-A PerCP-Cy5-5-A V450-A
-Min. 186 178.0 164 158.0 122 1094 603 652 387
-1st Qu. 727 581.0 662 648.0 269 1157 1042 717 676
-Median 890 798.0 1164 1043.0 623 1960 1146 1083 1473
-Mean 1198 997.4 1139 966.3 892 1901 1284 1274 1363
-3rd Qu. 1607 1432.0 1695 1128.0 1211 2424 1466 1555 1718
-Max. 2663 2124.0 2156 1780.0 2300 2830 2175 2756 2904
- V500-A PE-A PE-Cy7-A Time
-Min. 0 0.0 140.0 0
-1st Qu. 613 0.0 425.0 0
-Median 1587 242.0 711.0 0
-Mean 1734 419.2 874.9 0
-3rd Qu. 2863 547.0 1087.0 0
-Max. 3155 1484.0 1835.0 0
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/testfcs1.fcs
Binary file fcs_gate_trans/test-data/testfcs1.fcs has changed
diff -r 78b8ab344edd -r c28c2e680bf5 fcs_gate_trans/test-data/withcomp.flowtext
--- a/fcs_gate_trans/test-data/withcomp.flowtext Mon Feb 27 12:51:24 2017 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
-142 138 306 290 89 2121 1285 363 443 966 20 1807 0
-217 178 1193 1043 122 1106 1042 743 676 613 63 370 0
-831 776 513 473 1211 1994 1144 652 1718 1267 0 425 0
-1469 1341 727 710 149 1094 603 717 387 2935 547 578 0
-890 798 662 648 1916 2830 1146 2756 2237 1587 1484 1835 0
-1607 1432 1164 1099 2300 2706 1282 1083 2904 0 1156 140 0
-2663 2124 1973 1658 623 2424 2001 1947 1497 2863 0 1741 0
-2196 1566 1695 1128 932 1840 1466 1354 1473 3155 281 987 0
-727 581 2156 1780 506 1960 2175 1555 954 2676 0 1087 0
-186 181 164 158 269 1157 701 661 421 506 242 711 0
diff -r 78b8ab344edd -r c28c2e680bf5 static/images/flowtools/flowdensity.png
Binary file static/images/flowtools/flowdensity.png has changed
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/arcsinh150.flowtext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/arcsinh150.flowtext Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,11 @@
+FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
+9081 8811 19575.009765625 18578 -0.487166708542563 3.35237355048648 1.37750753926965 0.127057863991919 0.0255972040496283 0.866588972868883 0.760737973767117 2.53759317435759 0
+13879.5 11372 76400.875 66800 -0.455305138250274 0.963556030409229 0.915968891776551 0.511296170657329 0.339065738526448 0.531430131763512 -0.0326608602630583 -0.0783199078087399 0
+53197.5 49698 32821.8828125 30290 1.26289278746875 2.94666707290312 1.14932176211125 0.429535971137743 2.2879860496209 2.40333638820057 -0.0587661676654274 0.264762535136808 0
+94011.75 85861 46558.33203125 45425 -0.361914067420137 1.0099842999029 2.09568229265804 0.645771470660991 2.00391041851356 5.22898742425766 0.277363344871173 0.226719371107561 0.100000001490116
+56965.5 51060 42377.79296875 41492 3.34704579398504 5.11946885007392 1.24661362703293 4.79178721936253 3.51920619886312 3.47901108455652 2.12708633691257 3.11956116515719 0.100000001490116
+102877.5 91646 74486.234375 70382 3.67436877786622 4.72663049856952 1.57481462914001 1.37173870350081 5.15150145193671 4.8565806734818 1.59337073197003 1.13689659390179 0.200000002980232
+170482.5 135955 126331.6640625 106115 1.08590805588046 4.06062066240107 3.22122665934363 2.95167516373086 2.51312270311573 5.0850832349334 1.33604037616411 2.53656608596143 0.200000002980232
+140555.25 100224 108512.046875 72196 0.986973889697097 2.66146938806969 2.92800487646568 1.81362880902413 2.92526952883318 5.79683993164786 1.14069148921356 1.02981250583848 0.200000002980232
+46518.75 37218 138006.046875 113970 0.478108970811769 2.930079809471 3.47524128111705 2.31934440314287 1.78816416611445 4.6146323442977 1.1444747475952 1.25623958268597 0.200000002980232
+11892.75 11583 10502.310546875 10123 -0.245784525134546 1.17763111672424 0.362101658041819 0.322006394180742 -0.0511776555829312 0.0511776555829312 -0.0848315483504115 0.424837896402236 0.300000011920929
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/comp_gated.fcs
Binary file test-data/comp_gated.fcs has changed
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/comp_gated.flowframe
Binary file test-data/comp_gated.flowframe has changed
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/graph.png
Binary file test-data/graph.png has changed
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/log_auto.flowtext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/log_auto.flowtext Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,11 @@
+FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
+9081 8811 19575.009765625 18578 0.107479124810262 2.35164738676305 1.51547790699466 -0.061144697655589 0.0727004353282969 1.0310154450652 0.920209897843012 1.99410837204498 0
+13879.5 11372 76400.875 66800 0.141918443020496 1.34057200406832 1.27535742057765 0.859619581391869 0.757287908989254 0.806024677138336 0.931167043347637 0.344291698038674 0
+53197.5 49698 32821.8828125 30290 1.32996655818878 2.21946402561959 1.37817868469598 0.693917032223876 1.93363870355052 1.29555433841389 0.903402347005641 0.414719908039034 0
+94011.75 85861 46558.33203125 45425 0.170044792628609 1.32785138845132 0.613436522714762 0.816014064753624 -0.120476243761579 3.21906467299472 1.03908966576781 0.609424339597542 0.100000001490116
+56965.5 51060 42377.79296875 41492 2.10496707356995 3.11285471648376 1.38046165828125 3.03169168395389 2.47337708819967 1.65465462148336 1.40913169375994 2.02403522679516 0.100000001490116
+102877.5 91646 74486.234375 70382 2.52661315104717 2.97831779896819 1.51233127836149 1.28799123310603 3.19362378141846 0.203337149955779 1.21248531400732 0.0629088410989671 0.200000002980232
+170482.5 135955 126331.6640625 106115 0.685388506041053 2.67401770934787 2.22702400487437 2.16510272175412 1.71324776390477 3.13856154739856 0.479627404287715 1.92232282805069 0.200000002980232
+140555.25 100224 108512.046875 72196 1.02416936742608 2.06106292101106 1.69029796800271 1.56337104138741 1.6891398732786 3.46303980790081 0.98218001527827 1.10022743700787 0.200000002980232
+46518.75 37218 138006.046875 113970 0.556880464785503 2.184289140016 2.40849403736854 1.76427221905667 1.16035436242247 2.92923921449263 0.205172611029758 1.21351045807734 0.200000002980232
+11892.75 11583 10502.310546875 10123 0.298237181517127 1.39052550843584 0.83195511458194 0.711752082172111 -0.00442271222864163 0.74599469163953 0.973358662285888 0.775069435849609 0.300000011920929
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/logicle.flowtext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/logicle.flowtext Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,11 @@
+FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
+9081 8811 19575.009765625 18578 -1.6293942999728 3.76974100476528 2.93017965793824 -0.997939391264497 -0.194203172099747 2.60336430784137 -1.71463667729579 3.44536695084947 0
+13879.5 11372 76400.875 66800 -1.5840733542375 2.75309713006762 2.68675752232576 2.30274701604099 2.17363003610139 2.0116343929528 -1.66323120389061 -0.967469067449625 0
+53197.5 49698 32821.8828125 30290 2.85778541652942 3.63736232998847 2.79126399575401 2.11671108768611 3.35547371121447 2.91274365811979 -1.78341915019574 -0.518105269415561 0
+94011.75 85861 46558.33203125 45425 -1.54447361584222 2.74017319822191 1.97955410826578 2.25606402858623 -0.867115556068752 4.64630775715082 1.74827734155717 1.88966574033294 0.100000001490116
+56965.5 51060 42377.79296875 41492 3.55681159035635 4.53139977884887 2.79357911635882 4.45096953943852 3.89301514021491 3.2245462020143 3.12405192538511 3.47350370315712 0.100000001490116
+102877.5 91646 74486.234375 70382 3.95951152059644 4.39682850283845 2.92700229083233 2.72925132265477 4.61244973427904 -2.05643453095272 2.8027923722487 -1.55884230697896 0.200000002980232
+170482.5 135955 126331.6640625 106115 2.04073940622877 4.09239761100632 3.64493518330581 3.58822146469605 3.13681794532191 4.56750614949651 -2.4857191048391 3.37822057115119 0.200000002980232
+140555.25 100224 108512.046875 72196 2.56487764222724 3.47863126902702 3.10636507698575 2.9967641826576 3.11293718457071 4.88655172248296 -1.28411150350962 2.6264008550107 0.200000002980232
+46518.75 37218 138006.046875 113970 1.4368421226907 3.60212444237819 3.82665481021533 3.19308477259654 2.58962009351151 4.36412693196154 -2.71593675596755 2.73379360122108 0.200000002980232
+11892.75 11583 10502.310546875 10123 -1.31628440605225 2.80378227144781 2.22513621888898 2.13810302731895 -0.566190241111517 1.4381341222805 -1.37759538094841 2.24385504403792 0.300000011920929
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/nocomp.flowtext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/nocomp.flowtext Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,11 @@
+FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
+142 138 306 290 133 2178 1297 546 478 1018 955 1835 0
+217 178 1193 1043 154 1074 1047 800 688 813 438 407 0
+831 776 513 473 1237 2009 1177 747 1726 1776 421 638 0
+1469 1341 727 710 217 1100 1640 885 1598 2935 647 613 0
+890 798 662 648 2176 2891 1229 2760 2246 2230 1654 2081 0
+1607 1432 1164 1099 2310 2734 1395 1294 2904 2786 1404 1170 0
+2663 2124 1973 1658 1142 2467 2124 2011 1824 2877 1275 1834 0
+2196 1566 1695 1128 1087 1888 2001 1510 2000 3160 1172 1111 0
+727 581 2156 1780 779 2002 2228 1739 1498 2689 1174 1234 0
+186 181 164 158 295 1192 703 677 426 495 403 744 0
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/notrans.flowtext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/notrans.flowtext Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,11 @@
+FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
+9081 8811 19575.009765625 18578 -76 2140.15991210938 278.460021972656 19.1100006103516 3.83999991416931 146.879989624023 125.440002441406 942.760009765625 0
+13879.5 11372 76400.875 66800 -70.6800003051758 167.959991455078 157.43000793457 80.0800018310547 51.8400001525879 83.5199966430664 -4.90000009536743 -11.7600002288818 0
+53197.5 49698 32821.8828125 30290 243.959991455078 1424.23999023438 212.940002441406 66.4300003051758 731.519958496094 822.719970703125 -8.81999969482422 40.1800003051758 0
+94011.75 85861 46558.33203125 45425 -55.4799995422363 178.599990844727 600.600036621094 103.740005493164 546.239990234375 13994.8798828125 42.1399993896484 34.2999992370605 0.100000001490116
+56965.5 51060 42377.79296875 41492 2128.76000976562 12543.0400390625 239.330001831055 9038.1201171875 2529.59985351562 2429.76000976562 620.340026855469 1694.42004394531 0.100000001490116
+102877.5 91646 74486.234375 70382 2954.8798828125 8467.919921875 346.710021972656 276.640014648438 12951.359375 9643.2001953125 353.779998779297 209.720001220703 0.200000002980232
+170482.5 135955 126331.6640625 106115 196.839996337891 4349.47998046875 1876.42004394531 1431.43005371094 919.679992675781 12119.0400390625 265.580017089844 941.780029296875 0.200000002980232
+140555.25 100224 108512.046875 72196 173.279998779297 1068.55993652344 1397.76000976562 447.720001220703 1393.919921875 24694.080078125 210.699996948242 183.260009765625 0.200000002980232
+46518.75 37218 138006.046875 113970 74.4799957275391 1400.67993164062 2420.60009765625 755.300048828125 435.839996337891 7570.56005859375 211.68000793457 242.059997558594 0.200000002980232
+11892.75 11583 10502.310546875 10123 -37.2399978637695 220.399993896484 55.5100021362305 49.1400032043457 -7.67999982833862 7.67999982833862 -12.7399997711182 65.6600036621094 0.300000011920929
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/report.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/report.txt Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,39 @@
+#########################
+## BEFORE GATING ##
+#########################
+ events parameters
+ 10 13
+ FSC-A FSC-H SSC-A SSC-H APC-A APC-H7-A FITC-A PerCP-Cy5-5-A
+Min. 142.0 138.00 164.00 158.00 89.00 1094.00 603.00 363.00
+1st Qu. 344.5 281.00 550.25 516.75 179.00 1327.75 1067.50 675.00
+Median 860.5 787.00 945.50 876.50 564.50 1977.00 1214.00 913.00
+Mean 1092.8 911.50 1055.30 898.70 811.70 1923.20 1284.50 1183.10
+3rd Qu. 1572.5 1409.25 1569.50 1120.75 1141.25 2348.25 1420.75 1504.75
+Max. 2663.0 2124.00 2156.00 1780.00 2300.00 2830.00 2175.00 2756.00
+ V450-A V500-A PE-A PE-Cy7-A Time
+Min. 387.00 0.00 0.0 140.00 0
+1st Qu. 501.25 701.25 5.0 463.25 0
+Median 1213.50 1427.00 152.5 849.00 0
+Mean 1271.00 1656.80 379.3 968.10 0
+3rd Qu. 1662.75 2816.25 480.5 1577.50 0
+Max. 2904.00 3155.00 1484.0 1835.00 0
+
+#########################
+## AFTER GATING ##
+#########################
+ events parameters
+ 9 13
+ FSC-A FSC-H SSC-A SSC-H APC-A APC-H7-A FITC-A
+Min. 186.000 178.0000 164.000 158.0000 122 1094.000 603.000
+1st Qu. 727.000 581.0000 662.000 648.0000 269 1157.000 1042.000
+Median 890.000 798.0000 1164.000 1043.0000 623 1960.000 1146.000
+Mean 1198.444 997.4444 1138.556 966.3333 892 1901.222 1284.444
+3rd Qu. 1607.000 1432.0000 1695.000 1128.0000 1211 2424.000 1466.000
+Max. 2663.000 2124.0000 2156.000 1780.0000 2300 2830.000 2175.000
+ PerCP-Cy5-5-A V450-A V500-A PE-A PE-Cy7-A Time
+Min. 652.000 387 0.000 0.0000 140.0000 0
+1st Qu. 717.000 676 613.000 0.0000 425.0000 0
+Median 1083.000 1473 1587.000 242.0000 711.0000 0
+Mean 1274.222 1363 1733.556 419.2222 874.8889 0
+3rd Qu. 1555.000 1718 2863.000 547.0000 1087.0000 0
+Max. 2756.000 2904 3155.000 1484.0000 1835.0000 0
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/testfcs1.fcs
Binary file test-data/testfcs1.fcs has changed
diff -r 78b8ab344edd -r c28c2e680bf5 test-data/withcomp.flowtext
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/withcomp.flowtext Mon Jun 22 20:30:34 2020 -0400
@@ -0,0 +1,10 @@
+FSC-A FSC-H SSC-A SSC-H CD127 CD45RO LIVE CD4 CD3 HLA-DR CD25 CCR4 Time
+217 178 1193 1043 122 1106 1042 743 676 613 63 370 0
+831 776 513 473 1211 1994 1144 652 1718 1267 0 425 0
+1469 1341 727 710 149 1094 603 717 387 2935 547 578 0
+890 798 662 648 1916 2830 1146 2756 2237 1587 1484 1835 0
+1607 1432 1164 1099 2300 2706 1282 1083 2904 0 1156 140 0
+2663 2124 1973 1658 623 2424 2001 1947 1497 2863 0 1741 0
+2196 1566 1695 1128 932 1840 1466 1354 1473 3155 281 987 0
+727 581 2156 1780 506 1960 2175 1555 954 2676 0 1087 0
+186 181 164 158 269 1157 701 661 421 506 242 711 0