# 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