changeset 0:8e568997abda draft

"planemo upload for repository https://github.com/ImmPortDB/immport-galaxy-tools/tree/master/flowtools/fcs_merge_downsample commit 2fe0269eaff92916ca51729a7ca8d2017f65f89f"
author azomics
date Mon, 22 Jun 2020 20:35:09 -0400
parents
children 04afe468b234
files FCSMergeDownsample.R FCSMergeDownsample.xml test-data/input1.fcs test-data/input2.fcs test-data/input3.fcs test-data/merge1.flowframe test-data/merge2.fcs
diffstat 7 files changed, 264 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FCSMergeDownsample.R	Mon Jun 22 20:35:09 2020 -0400
@@ -0,0 +1,115 @@
+#!/usr/bin/Rscript
+# Aggregate FCS files Module for Galaxy
+# with FlowSOM AggregateFlowFrames
+######################################################################
+#                  Copyright (c) 2017 Northrop Grumman.
+#                          All rights reserved.
+######################################################################
+#
+# Version 1
+# Cristel Thomas
+#
+#
+library(FlowSOM)
+library(flowCore)
+
+downsampleMergeFCS <- function(fcs_files, nb_cells, output="", flag_fcs=FALSE) {
+  ff <- AggregateFlowFrames(fcs_files, nb_cells, writeOutput = FALSE)
+  n <- length(colnames(ff)) - 2
+  exprs(ff) <- exprs(ff)[,1:n]
+  if (flag_fcs) {
+    write.FCS(ff, output)
+  } else {
+    saveRDS(ff, file=output)
+  }
+}
+
+checkFCSfiles <- function(fcsfiles, ds_factor=0.1, out_file ="",
+                         flag_fcs=FALSE) {
+  isValid <- F
+  nb_events <- 0
+  markerCheck <- T
+
+  for (i in 1:length(fcsfiles)){
+    is_file_valid <- F
+    tryCatch({
+      fcs <- read.FCS(fcsfiles[i], transformation=FALSE)
+      is_file_valid <- T
+      nb_events <- nb_events + as.numeric(fcs@description$`$TOT`)
+    }, error = function(ex) {
+      print(paste(ex))
+    })
+    if (is_file_valid){
+      if (i == 1) {
+        m1 <- as.vector(pData(parameters(fcs))$desc)
+      } else {
+        m2 <- as.vector(pData(parameters(fcs))$desc)
+        if (is.na(all(m1==m2))) {
+          mm1 <- is.na(m1)
+          mm2 <- is.na(m2)
+          if (all(mm1==mm2)){
+            if (!all(m1==m2, na.rm=TRUE)){
+              markerCheck <- F
+            }
+          } else {
+            markerCheck <- F
+          }
+        } else if (!all(m1==m2)) {
+          markerCheck <- F
+        }
+      }
+    } else {
+      quit(save = "no", status = 10, runLast = FALSE)
+    }
+  }
+
+  if (markerCheck) {
+    isValid <- T
+  } else {
+    quit(save = "no", status = 12, runLast = FALSE)
+  }
+
+  ## translate ds_factor to nb of events
+  nb_cell <- floor(ds_factor*nb_events)
+
+  if (isValid) {
+    downsampleMergeFCS(fcsfiles, nb_cell, out_file, flag_fcs)
+  } else {
+    quit(save = "no", status = 10, runLast = FALSE)
+  }
+}
+
+args <- commandArgs(trailingOnly = TRUE)
+flag_fcs <- FALSE
+
+if (args[2] == "FCS"){
+  flag_fcs <- TRUE
+}
+
+if (args[3] == "" || args[3] == "i.e.:0.1 or 10X") {
+  factor <- 0.1
+} else {
+  #rm last X if it's there
+  ds <- gsub("X", "", args[3])
+  if (!is.na(as.numeric(ds))) {
+    factor <- as.numeric(ds)
+    if (factor > 1 && factor <= 100) {
+      factor <- as.numeric(ds) / 100
+    } else if (factor > 100){
+      quit(save = "no", status = 11, runLast = FALSE)
+    }
+  } else {
+    quit(save = "no", status = 11, runLast = FALSE)
+  }
+}
+
+nb_files <- (length(args) - 3)
+fcsfiles <- character(nb_files)
+j <- 1
+## get files and file names
+for (i in 4:length(args)) {
+    fcsfiles[[j]] <- args[i]
+    j <- j + 1
+}
+
+checkFCSfiles(fcsfiles, factor, args[1], flag_fcs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FCSMergeDownsample.xml	Mon Jun 22 20:35:09 2020 -0400
@@ -0,0 +1,149 @@
+<tool id="fcs_merge_downsample" name="Merge and downsample" version="1.0+galaxy1">
+  <description>FCS files with FlowSOM</description>
+  <requirements>
+    <requirement type="package" version="1.18.0">bioconductor-flowsom</requirement>
+  </requirements>
+  <stdio>
+    <exit_code range="10" level="fatal" description="One or more FCS files is not valid. See stderr for more details." />
+    <exit_code range="11" level="fatal" description="Please provide a numeric value [0,1] for the downsampling factor." />
+    <exit_code range="12" level="fatal" description="There are inconsistencies in marker names between FCS files." />
+  </stdio>
+  <command><![CDATA[
+      FCSMergeDownsample.R '${output_file}' '${outformat}' '${factorDS}'
+  #for $f in $input
+    '${f}'
+  #end for
+  ]]>
+  </command>
+  <inputs>
+    <param format="fcs" name="input" type="data_collection" collection_type="list" label="FCS files Collection"/>
+    <param name="factorDS" type="text" label="Downsample by:" value="i.e.:0.1 or 10%" optional="true" help="By default 0.1"/>
+    <param name="outformat" type="select" label="Output Format">
+      <option value="flowFrame">R Data, flowFrame</option>
+      <option value="FCS">FCS 3.0</option>
+    </param>
+  </inputs>
+  <outputs>
+    <data format="flowframe" name="output_file" label="Merged FCS from ${input.name} in ${outformat}">
+      <change_format>
+        <when input="outformat" value="FCS" format="fcs" />
+      </change_format>
+    </data>
+  </outputs>
+  <tests>
+    <test>
+      <param name="input">
+        <collection type="list">
+          <element name="input1.fcs" value="input1.fcs"/>
+          <element name="input2.fcs" value="input2.fcs"/>
+          <element name="input3.fcs" value="input3.fcs"/>
+        </collection>
+      </param>
+      <param name="factorDS" value=".8"/>
+      <param name="outformat" value="flowFrame"/>
+      <output name="output_file" file="merge1.flowframe" compare="sim_size" delta="1000000"/>
+    </test>
+    <test>
+      <param name="input">
+        <collection type="list">
+          <element name="input1.fcs" value="input1.fcs"/>
+          <element name="input2.fcs" value="input2.fcs"/>
+          <element name="input3.fcs" value="input3.fcs"/>
+        </collection>
+      </param>
+      <param name="factorDS" value="i.e.:0.1 or 10%"/>
+      <param name="outformat" value="FCS"/>
+      <output name="output_file" file="merge2.fcs" compare="sim_size" delta="1000000"/>
+    </test>
+  </tests>
+  <help><![CDATA[
+Merge and downsample using FlowSOM
+-------------------
+
+This tool merges and downsamples multiple FCS files into one flowframe or FCS file using FlowSOM.
+
+**Input files**
+
+This tool requires a collection of FCS files as input.
+
+.. class:: warningmark
+
+Input files **MUST** have the same markers *and* channels. The following tools in the FCS Files tool section can help harmonize channels and/or markers in the FCS files collection:
+
+- Get list of markers or channels in FCS files.
+- Edit markers or channels in FCS files
+
+**Downsampling**
+
+By default, files are downsampled to 10% of the total number of events across input files. If a downsampling factor is provided, each file in the input dataset collection will be downsampled randomly without replacement as follows:
+
+- If n is between 0 and 1, the size of the output will be n times that of the input files.
+- If n is between 1 and 100, the size of the output will be n% that of the input files.
+
+.. class:: infomark
+
+Downsampling is implemented such that each file will contribute an equal number of event to the aggregate.
+
+.. class:: warningmark
+
+At this time, up-sampling is not supported. If the number provided is greater than 100, the tool will exit.
+
+**Output file**
+
+The output file contains an aggregation of events from the input files provided all are valid FCS files. If a downsampling factor is provided, the corresponding proportion of each input file ONLY will be read in. Output can be provided in FCS format or in a RData object containing a flowFrame.
+
+.. class:: infomark
+
+The output generated contains data for all markers present in the original files. No information is added, or removed.
+
+-----
+
+**Example**
+
+*File1*: 20K events::
+
+   Marker1 Marker2 Marker3 ...
+   34      45      12      ...
+   33      65      10      ...
+   87      26      76      ...
+   24      56      32      ...
+   95      83      53      ...
+   ...     ...     ...     ...
+
+*File2*: 20K events::
+
+   Marker1 Marker2 Marker3 ...
+   19      62      98      ...
+   12      36      58      ...
+   41      42      68      ...
+   76      74      53      ...
+   62      34      45      ...
+   ...     ...     ...     ...
+
+*Output*: 4K events::
+
+   Marker1 Marker2 Marker3 ...
+   34      45      12      ...
+   87      26      76      ...
+   12      36      58      ...
+   62      34      45      ...
+   ...     ...     ...     ...
+
+.. class:: infomark
+
+With a downsampling factor of 0.5: 20K events::
+
+   Marker1 Marker2 Marker3 ...
+   34      45      12      ...
+   24      56      32      ...
+   95      83      53      ...
+   19      62      98      ...
+   12      36      58      ...
+   62      34      45      ...
+   ...     ...     ...     ...
+ ]]>
+  </help>
+  <citations>
+    <citation type="doi">10.1002/cyto.a.22625</citation>
+  </citations>
+</tool>
Binary file test-data/input1.fcs has changed
Binary file test-data/input2.fcs has changed
Binary file test-data/input3.fcs has changed
Binary file test-data/merge1.flowframe has changed
Binary file test-data/merge2.fcs has changed