changeset 0:d0c26c9430f2 draft default tip

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/seurat_v5 commit a9214c07b0cc929a51fd92a369bb89c675b6c88d
author iuc
date Wed, 11 Sep 2024 10:21:11 +0000
parents
children
files create_seurat.xml macros.xml
diffstat 2 files changed, 974 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/create_seurat.xml	Wed Sep 11 10:21:11 2024 +0000
@@ -0,0 +1,537 @@
+<tool id="seurat_create" name="Seurat Create" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="@PROFILE@">
+    <description>- Prepare data for the pipeline</description>
+    <macros>
+        <import>macros.xml</import>
+    </macros>
+    <expand macro="requirements"/>
+    <expand macro="version_command"/>
+    <command detect_errors="exit_code"><![CDATA[
+#if str($method.method) == 'CreateSeuratObject':
+    #if str($method.input_type.input_type) == 'mtx':
+    ln -s '$method.input_type.matrix' matrix.mtx &&
+    ln -s '$method.input_type.gene_names' genes.tsv &&
+    ln -s '$method.input_type.cell_barcodes' barcodes.tsv &&
+    #else if str($method.input_type.input_type) == 'tab':
+    ln -s '$method.input_type.input_tab' input.tab;
+        #if str($method.input_type.citeseq.citeseq) == 'true':
+        ln -s '$method.input_type.citeseq.citeseq_table' citeseq.tab &&
+        #end if
+    #end if
+    cat '$script_file' > $hidden_output &&
+    Rscript '$script_file' >> $hidden_output
+#else:
+@CMD@
+#end if
+    ]]></command>
+    <configfiles>
+        <configfile name="script_file"><![CDATA[
+@CMD_imports@
+
+#if $method.method == 'CreateSeuratObject'
+    #if $method.input_type.input_type == 'mtx'
+        counts<-Read10X(
+            data.dir = '.',
+            gene.column = $method.input_type.gene_column,
+            cell.column = $method.input_type.cell_column,
+            unique.features = $method.input_type.unique_features,
+            strip.suffix = $method.input_type.strip_suffix
+        )
+
+        #if $method.meta_data
+        meta_data<-read.table(
+            "$method.meta_data",
+            header = TRUE,
+            row.names = 1,
+            sep = "\t"
+        )
+        for (name in colnames(meta_data)) {
+        meta_data[[name]]<-gsub("^$", "N/A", trimws(meta_data[[name]]))
+        meta_data[[name]][is.na(meta_data[[name]])]<-"N/A"
+        }
+        #end if
+
+        seurat_obj<-CreateSeuratObject(
+            counts,
+            assay = '$method.assay',
+            #if $method.names_field != ''
+            names.field = $method.names_field,
+            #end if
+            #if $method.names_delim != ''
+            names.delim = '$method.names_delim',
+            #end if
+            #if $method.min_cells
+            min.cells = $method.min_cells,
+            #end if
+            #if $method.min_features
+            min.features = $method.min_features,
+            #end if
+            #if $method.meta_data
+            meta.data = meta_data
+            #end if
+        )
+
+        #if $method.percent_mt.percent_mt == 'true'
+        seurat_obj[["percent.mt"]]<-PercentageFeatureSet(
+            seurat_obj,
+            pattern = '$method.percent_mt.pattern',
+        )
+        #end if
+
+        #if $method.input_type.citeseq_boolean == 'true'
+        seurat_obj[['ADT']]<-CreateAssayObject(counts[['Antibody Capture']], colnames(x = seurat_obj))
+        #end if
+
+    #else if $method.input_type.input_type == 'tab'
+        counts<-read.table(
+            'input.tab',
+            header = TRUE,
+            row.names = 1,
+            sep = "\t"
+        )
+
+        #if $method.meta_data
+        meta_data<-read.table(
+            "$method.meta_data",
+            header = TRUE,
+            row.names = 1,
+            sep = "\t"
+        )
+        for (name in colnames(meta_data)) {
+        meta_data[[name]]<-gsub("^$", "N/A", trimws(meta_data[[name]]))
+        meta_data[[name]][is.na(meta_data[[name]])]<-"N/A"
+        }
+        #end if
+
+        seurat_obj<-CreateSeuratObject(
+            counts,
+            assay = '$method.assay',
+            #if $method.names_field != ''
+            names.field = $method.names_field,
+            #end if
+            #if $method.names_delim != ''
+            names.delim = '$method.names_delim',
+            #end if
+            #if $method.min_cells
+            min.cells = $method.min_cells,
+            #end if
+            #if $method.min_features
+            min.features = $method.min_features,
+            #end if
+            #if $method.meta_data
+            meta.data = meta_data
+            #end if
+        )
+
+        #if $method.percent_mt.percent_mt == 'true'
+        seurat_obj[["percent.mt"]]<-PercentageFeatureSet(
+            seurat_obj,
+            pattern = '$method.percent_mt.pattern',
+        )
+        #end if
+        
+        #if $method.input_type.citeseq.citeseq == 'true'
+            citeseq<-read.table(
+                'citeseq.tab',
+                header = TRUE,
+                row.names = 1,
+                sep = "\t"
+            )
+        
+            seurat_obj[['ADT']]<-CreateAssay5Object(counts = citeseq)
+        #end if
+    #end if
+
+#else if $method.method == 'Add_QC_Metrics'
+@CMD_read_inputs@
+
+    #if $method.match.match == 'list'
+    features_list<-paste(readLines('$method.match.features'), collapse=",")
+    #end if
+
+seurat_obj[['$method.col_name']]<-PercentageFeatureSet(
+    seurat_obj,
+    #if $method.match.match == 'pattern'
+    pattern = '$method.match.pattern',
+    #else if $method.match.match == 'list'
+    features = c(unlist(strsplit(features_list, ","))),
+    #end if
+    #if $method.assay != ''
+    assay = '$method.assay'
+    #end if
+)
+
+#else if $method.method == 'FilterCells'
+@CMD_read_inputs@
+    #if $method.minimum_nFeature_RNA
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = nFeature_RNA > $method.minimum_nFeature_RNA
+    )
+    #end if
+    #if $method.maximum_nFeature_RNA
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = nFeature_RNA < $method.maximum_nFeature_RNA
+    )
+    #end if
+    #if $method.minimum_nCount_RNA
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = nCount_RNA > $method.minimum_nCount_RNA
+    )
+    #end if
+    #if $method.maximum_nCount_RNA
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = nCount_RNA < $method.maximum_nCount_RNA
+    )
+    #end if
+    #if $method.minimum_percent_mt
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = percent.mt> $method.minimum_percent_mt
+    )
+    #end if
+    #if $method.maximum_percent_mt
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = percent.mt < $method.maximum_percent_mt
+    )
+    #end if
+    #if $method.other.other == 'true'
+        #if $method.other.minimum
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = $method.other.other_variable > $method.other.minimum
+    )
+        #end if
+        #if $method.other.maximum
+    seurat_obj<-subset(
+        seurat_obj,
+        subset = $method.other.other_variable < $method.other.maximum
+    )
+        #end if
+    #end if
+
+#end if
+
+@CMD_rds_write_outputs@
+
+]]></configfile>
+    </configfiles>
+    <inputs>
+        <conditional name="method">
+            <param name="method" type="select" label="Method used">
+                <option value="CreateSeuratObject">Create Seurat Object</option>
+                <option value="Add_QC_Metrics">Add QC Metrics</option>
+                <option value="FilterCells">Filter cells by QC metrics</option>
+            </param>
+            <when value="CreateSeuratObject">
+                <conditional name="input_type">
+                    <param name="input_type" type="select" label="Select format of input">
+                        <option value="mtx" selected="true">matrix market (for e.g. 10x data)</option>
+                        <option value="tab">tab-delimited text</option>
+                    </param>
+                    <when value="mtx">
+                        <param name="matrix" type="data" format="mtx" label="Counts matrix with features as rows, cells as columns (.mtx)"/>
+                        <param name="citeseq_boolean" type="boolean" truevalue="true" falsevalue="false" checked="false" label="Matrix includes citeseq data"/>
+                        <param name="gene_names" type="data" format="tsv,tabular" label="List of gene names (for rows)"/>
+                        <param name="cell_barcodes" type="data" format="tsv,tabular" label="List of cell barcodes (for columns)"/>
+                        <param name="gene_column" type="integer" value="2" label="Column of gene table to use as gene names" help="(gene.column)"/>
+                        <param name="cell_column" type="integer" value="1" label="Column of cell table to use as cell names" help="(cell.column)"/>
+                        <param name="unique_features" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="true" label="Make feature names unique" help="(unique.features)"/>
+                        <param name="strip_suffix" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Remove trailing -1 if present in all cell barcodes" help="(strip.suffix)"/>
+                    </when>
+                    <when value="tab">
+                        <param name="input_tab" type="data" format="tsv,tabular" label="Expression table with features as rows, cells as columns" help="(file)"/>
+                        <conditional name="citeseq">
+                            <param name="citeseq" type="select" label="Add citeseq assay">
+                                <option value="false" selected="true">No</option>
+                                <option value="true">Yes</option>
+                            </param>
+                            <when value="false"></when>
+                            <when value="true">
+                                <param name="citeseq_table" type="data" format ="tsv,tabular" label="CITE-Seq data to add"/>
+                            </when>
+                        </conditional>
+                    </when>
+                </conditional>
+                <param name="meta_data" type="data" format="tsv,tabular" optional="true" label="Additional cell metadata to add" help="table with cell names in first column (meta.data)"/>
+                <param argument="assay" type="text" value="RNA" label="Name of assay to create">
+                    <expand macro="valid_name"/>
+                </param>
+                <param name="min_cells" type="integer" optional="true" value="0" label="Include features detected in at least this many cells" help="(min.cells)"/>
+                <param name="min_features" type="integer" optional="true" value="0" label="Include cells where at least this many features are detected" help="(min.features)"/>
+                <param name="names_field" type="integer" optional="true" value="" label="Field of cell names to use as cell identity class" help="(names.field)"/>
+                <param name="names_delim" type="text" optional="true" value="" label="Delimiter for cell names" help="(names.delim)"/>
+                <conditional name="percent_mt">
+                    <param name="percent_mt" type="select" label="Calculate percentage of mito genes in each cell">
+                        <option value="false" selected="true">No</option>
+                        <option value="true">Yes</option>
+                    </param>
+                    <when value="false">
+                    </when>
+                    <when value="true">
+                        <param argument="pattern" type="text" value="^MT-" label="Pattern/regex to match in gene names" help="e.g. the default '^MT-' matches gene names starting with 'MT-' which are human mitochondrial genes"/>
+                    </when>
+                </conditional>
+            </when>
+            <when value="Add_QC_Metrics">
+                <expand macro="input_rds"/>
+                <conditional name="match">
+                    <param name="match" type="select" label="Calculate percentage of reads based on">
+                        <option value="pattern" selected="true">Pattern in gene names</option>
+                        <option value="list">List of features</option>
+                    </param>
+                    <when value="pattern">
+                        <param argument="pattern" type="text" value="^MT-" label="Pattern/regex to match in gene names" help="e.g. the default '^MT-' matches gene names starting with 'MT-' which are human mitochondrial genes"/>
+                    </when>
+                    <when value="list">
+                        <param argument="features" type="data" format="txt,tabular" label="List of genes to match" help="text file with one feature on each line"/>
+                    </when>
+                </conditional>
+                <param name="col_name" type="text" value="percent.mt" label="Name to store the variable as">
+                    <expand macro="valid_name"/>
+                </param>
+                <expand macro="select_assay"/>
+            </when>
+            <when value="FilterCells">
+                <expand macro="input_rds"/>
+                <param name="minimum_nFeature_RNA" type="integer" optional="true" value="" label="Minimum nFeature_RNA"/>
+                <param name="maximum_nFeature_RNA" type="integer" optional="true" value="" label="Maximum nFeature_RNA"/>
+                <param name="minimum_nCount_RNA" type="integer" optional="true" value="" label="Minimum nCount_RNA"/>
+                <param name="maximum_nCount_RNA" type="integer" optional="true" value="" label="Maximum nCount_RNA"/>
+                <param name="minimum_percent_mt" type="float" optional="true" value="" label="Minimum percent.mt"/>
+                <param name="maximum_percent_mt" type="float" optional="true" value="" label="Maximum percent.mt"/>
+                <conditional name="other">
+                    <param name="other" type="select" label="Filter by a different metric">
+                        <option value="false" selected="true">No</option>
+                        <option value="true">Yes</option>
+                    </param>
+                    <when value="false">
+                    </when>
+                    <when value="true">
+                        <param name="other_variable" type="text" value="" label="Enter name of cell metric to filter" help="e.g. percent.ribo or other metrics calculated using 'Add QC Metrics'"/>
+                        <param name="minimum" type="float" optional="true" value="" label="Minimum"/>
+                        <param name="maximum" type="float" optional="true" value="" label="Maximum"/>
+                    </when>
+                </conditional>
+            </when>
+        </conditional>
+        <expand macro="inputs_common_advanced"/>
+    </inputs>
+    <outputs>
+        <expand macro="seurat_outputs"/>
+    </outputs>
+    <tests>
+        <test expect_num_outputs="2">
+            <!-- test1: CreateSeuratObject from matrix -->
+            <conditional name="method">
+                <param name="method" value="CreateSeuratObject"/>
+                <conditional name="input_type">
+                    <param name="input_type" value="mtx"/>
+                    <param name="matrix" location="https://zenodo.org/records/13732784/files/matrix.mtx"/>
+                    <param name="gene_names" location="https://zenodo.org/records/13732784/files/genes.tsv"/>
+                    <param name="cell_barcodes" location="https://zenodo.org/records/13732784/files/barcodes.tsv"/>
+                    <param name="gene_column" value="1"/>
+                </conditional>
+                <conditional name="percent_mt">
+                    <param name="percent_mt" value="true"/>
+                    <param name="pattern" value="^Mt"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="Read10X"/>
+                    <has_text_matching expression="CreateSeuratObject"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/rawdata.rds" ftype="rds"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test2: CreateSeuratObject from tabular -->
+            <conditional name="method">
+                <param name="method" value="CreateSeuratObject"/>
+                <conditional name="input_type">
+                    <param name="input_type" value="tab"/>
+                    <param name="input_tab" location="https://zenodo.org/records/13732784/files/counts.tsv"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="read.table"/>
+                    <has_text_matching expression="CreateSeuratObject"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/rawdata2.rds" ftype="rds"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test3: CreateSeuratObject with CITE-Seq -->
+            <conditional name="method">
+                <param name="method" value="CreateSeuratObject"/>
+                <conditional name="input_type">
+                    <param name="input_type" value="tab"/>
+                    <param name="input_tab" location="https://zenodo.org/records/13732784/files/rna.tab"/>
+                    <conditional name="citeseq">
+                        <param name="citeseq" value="true"/>
+                        <param name="citeseq_table" location="https://zenodo.org/records/13732784/files/adt.tab"/>
+                    </conditional>
+                </conditional>
+            </conditional>
+            <param name="min_features" value=""/>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="read.table"/>
+                    <has_text_matching expression="CreateSeuratObject"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/citeseq.rds" ftype="rds"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test4: Add_QC_Metrics -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/rawdata.rds"/>
+            <conditional name="method">
+                <param name="method" value="Add_QC_Metrics"/>
+                <conditional name="match">
+                    <param name="match" value="pattern"/>
+                    <param name="pattern" value="^Rp"/>
+                </conditional>
+                <param name="col_name" value="percent.ribo"/>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="PercentageFeatureSet"/>
+                    <has_text_matching expression="percent.ribo"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/ribodata.rds" ftype="rds"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test5: FilterCells -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/ribodata.rds"/>
+            <conditional name="method">
+                <param name="method" value="FilterCells"/>
+                <param name="minimum_nCount_RNA" value="1"/>
+                <param name="maximum_nCount_RNA" value="20000000"/>
+                <conditional name="other">
+                    <param name="other" value="true"/>
+                    <param name="other_variable" value="percent.mt"/>
+                    <param name="maximum" value="2"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="subset"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/filtered.rds" ftype="rds"/>
+        </test>
+    </tests>
+    <help><![CDATA[
+Seurat
+======
+
+Seurat is an R package designed for QC, analysis, and exploration of single-cell RNA-seq data. 
+
+Seurat aims to enable users to identify and interpret sources of heterogeneity from single-cell transcriptomic measurements, and to integrate diverse types of single-cell data.
+
+Creating a Seurat Object 
+========================
+
+Seurat objects can be created from single cell data in matrix market or tab-delimited table formats, using the Read10X or read.table functions followed by CreateSeuratObject. 
+The input should be a single cell matrix with cells as rows and genes as columns.
+
+Both RNA-seq and combined RNA and CITE-seq data can be used as inputs.
+
+Read10X 
+========
+
+Load sparse data matrices provided by 10X genomics.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/read10x>`__
+
+read.table
+==========
+
+Read a tab-delimited tsv or tabular file into an RDS file as a table. 
+
+More details on the `R documentation
+<https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/read.table>`__
+
+CreateSeuratObject
+==================
+
+Create a Seurat Object from raw data in RDS format. 
+
+names.field
+
+For the initial identity class for each cell, choose this field from the cell's name. 
+E.g. If your cells are named as BARCODE_CLUSTER_CELLTYPE in the input matrix, set names.field to 3 to set the initial identities to CELLTYPE.
+
+names.delim
+
+For the initial identity class for each cell, choose this delimiter from the cell's column name. 
+E.g. If your cells are named as BARCODE-CLUSTER-CELLTYPE, set this to “-” to separate the cell name into its component parts for picking the relevant field.
+
+meta.data
+
+Additional cell-level metadata to add to the Seurat object. Should be a data.frame where the rows are cell names and the columns are additional metadata fields. 
+Row names in the metadata need to match the column names of the counts matrix.
+
+Filtering can also be performed on:
+
+min.cells = only include features/genes detected in at least this many cells 
+
+min.features = only include cells where at least this many features are detected 
+
+Some QC metrics are added when creating a Seurat Object (nCount_RNA and nFeature_RNA).
+Mito percentage can optionally be calculated - it will be based on gene names starting with "MT-". If this pattern does not work for your gene names then you can use the separate 'Calculate QC Metrics' function instead.
+
+More details on the `seurat documentation
+<https://satijalab.github.io/seurat-object/reference/CreateSeuratObject.html>`__
+
+Calculate QC Metrics
+====================
+
+Calculate the percentage of all the counts belonging to a subset of the possible features for each cell. This is useful when trying to compute the percentage of transcripts that map to mitochondrial genes for example. 
+The calculation here is simply the column sum of the matrix present in the counts slot for features belonging to the set divided by the column sum for all features times 100.
+
+Feature sets can be defined by entering a list of genes or using a shared pattern in the gene names, such as "^MT-" or "^RP[LS]" for human mitochondrial or ribosomal genes.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/percentagefeatureset>`__
+
+Filter Cells
+============
+
+Filter cells based on QC metrics. 
+
+nFeature_RNA = number of unique genes identified in the cell
+
+ncounts_RNA = total number of RNAs found in the cell
+
+percent.mt = percentage of mitochondrial genes in the cell
+
+More details on the `R documentation
+<https://rdrr.io/r/base/subset.html>`__
+
+
+    ]]></help>
+    <expand macro="citations"/>
+</tool>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/macros.xml	Wed Sep 11 10:21:11 2024 +0000
@@ -0,0 +1,437 @@
+<macros>
+    <token name="@TOOL_VERSION@">5.0</token>
+    <token name="@VERSION_SUFFIX@">0</token>
+    <token name="@PROFILE@">23.0</token>
+    <xml name="requirements">
+        <requirements>
+            <requirement type="package" version="@TOOL_VERSION@">r-seurat</requirement>
+            <requirement type="package" version="1.2.1">fit-sne</requirement>
+            <requirement type="package" version="3.58.1">bioconductor-limma</requirement>
+            <requirement type="package" version="1.28.0">bioconductor-mast</requirement>
+            <requirement type="package" version="1.42.0">bioconductor-deseq2</requirement>
+            <requirement type="package" version="2.1.3">r-svglite</requirement>
+            <requirement type="package" version="1.1">r-metap</requirement>
+            <requirement type="package" version="1.14.0">bioconductor-glmGamPoi</requirement>
+            <requirement type="package" version="0.5.3">umap-learn</requirement> <!-- https://github.com/satijalab/seurat/issues/8283 -->
+            <requirement type="package" version="0.10.2">leidenalg</requirement>
+            <requirement type="package" version="1.2.0">r-harmony</requirement>
+            <requirement type="package" version="1.18.0">bioconductor-batchelor</requirement>
+            <requirement type="package" version="2.0.0">numpy</requirement>
+            <requirement type="package" version="2.2.2">pandas</requirement>
+        </requirements>
+    </xml>
+    <xml name="citations">
+        <citations>
+            <citation type="doi">10.1038/s41587-023-01767-y</citation>
+        </citations>
+    </xml>
+    <xml name="sanitize_query" token_validinitial="string.printable">
+        <sanitizer>
+            <valid initial="@VALIDINITIAL@">
+                <remove value="&apos;" />
+            </valid>
+       </sanitizer>
+    </xml>
+    <xml name="sanitize_vectors" token_validinitial="string.digits">
+        <sanitizer>
+            <valid initial="@VALIDINITIAL@">
+                <add value=","/>
+            </valid>
+        </sanitizer>
+    </xml>
+    <xml name="version_command">
+        <version_command><![CDATA[
+echo $(R --version | grep version | grep -v GNU)", Seurat version" $(R --vanilla --slave -e "library(Seurat); cat(sessionInfo()\$otherPkgs\$DESeq2\$Version)" 2> /dev/null | grep -v -i "WARNING: ")
+        ]]></version_command>
+    </xml>
+
+    <token name="@CMD_imports@"><![CDATA[
+library(Seurat)
+    ]]>
+    </token>
+    <token name="@reticulate_hack@"><![CDATA[
+library(reticulate)
+## HACK: CI biocontainers do not contain a useable conda binary, just the env.
+##  see: https://github.com/galaxyproject/tools-iuc/issues/5585#issuecomment-1803773923
+is_biocontainer = grepl("^# cmd: /opt/conda/bin/",
+                        paste0(reticulate:::python_info_condaenv_find("/usr/local/"),
+                               "-none"))
+if (is_biocontainer) {
+   ## conda detection false positive
+   assignInNamespace("is_conda_python", function(x) FALSE, ns="reticulate")
+   use_python("/usr/local/bin/python")
+} else {
+   conda_path = Sys.getenv("CONDA_PREFIX")
+   if (conda_path != "") {
+      ## Active conda env found
+      use_python(file.path(conda_path, "bin", "python3"))
+   } else {
+      ## Not biocontainer or conda, assume system python
+      use_python("/usr/bin/python3")
+   }
+}]]>
+    </token>
+    <xml name="input_rds">
+        <param name="seurat_rds" type="data" format="rds" label="Input file with the Seurat object"/>
+    </xml>
+    <token name="@CMD_read_inputs@"><![CDATA[
+seurat_obj = readRDS('seurat.rds')
+        ]]>
+    </token>
+    <token name="@CMD_read_expression_matrix@"><![CDATA[
+counts<-read.table("matrix.tab", header=TRUE, row.names=1, sep="\t")
+    ]]>]
+    </token>
+    <token name="@CMD@"><![CDATA[
+cp '$seurat_rds' seurat.rds &&
+cat '$script_file' > $hidden_output &&
+Rscript '$script_file' >> $hidden_output
+    ]]>
+    </token>
+    <xml name="inputs_common_advanced">
+        <section name="advanced_common" title="Advanced Output" expanded="false">
+            <param name="show_log" type="boolean" checked="false" label="Output Log?" />
+        </section>
+    </xml>
+    <xml name="outputs_common_advanced">
+        <data name="hidden_output" format="txt" label="Log file" >
+            <filter>advanced_common['show_log']</filter>
+        </data>
+    </xml>
+    <xml name="seurat_outputs">
+        <data name="rds_out" format="rds" from_work_dir="seurat.rds" label="${tool.name} (${method.method}) on ${on_string}: RDS">
+             <filter>method['method'] != 'Inspect'</filter>
+        </data>
+        <expand macro="outputs_common_advanced"/>
+    </xml>
+    <token name="@CMD_rds_write_outputs@"><![CDATA[
+saveRDS(seurat_obj, 'seurat.rds')
+        ]]>
+    </token>
+    <xml name="variable_out">
+        <data name="variable_tabular" format="txt" from_work_dir="variable_out.txt" label="${tool.name} (${method.method}) on ${on_string}: Top variable features list">
+            <filter>method['method'] == 'FindVariableFeatures' or method['method'] == 'SCTransform'</filter>
+            <filter>method['output_topN']['output_topN'] == 'true'</filter>
+        </data>
+    </xml>
+    <token name="@CMD_write_variable_tab@"><![CDATA[
+write.table(top_N, 'variable_out.txt', sep= "\t", col.names = FALSE, quote = FALSE)
+    ]]>
+    </token>
+    <xml name="markers_out">
+        <data name="markers_tabular" format="csv" from_work_dir="markers_out.csv" label="${tool.name} (${method.method}) on ${on_string}: Markers list">
+            <filter>method['method'] == 'FindAllMarkers' or method['method'] == 'FindMarkers' or method['method'] == 'FindConservedMarkers'</filter>
+        </data>
+    </xml>
+    <token name="@CMD_write_markers_tab@"><![CDATA[
+write.csv(seurat_obj, 'markers_out.csv', quote = FALSE)
+    ]]>
+    </token>
+    <xml name="print_top_pcs">
+        <data name="top_pcs" format="txt" from_work_dir="print_pcs.txt" label="${tool.name} Print PCs on ${on_string}">
+            <filter>method['method'] == 'RunPCA' and method['print_pcs']['print_pcs'] == 'true'</filter>
+        </data>
+    </xml>
+    <xml name="inspect_out">
+        <data name="inspect_tabular" format="tabular" from_work_dir="inspect_out.tab" label="${tool.name} Inspect (${method.inspect.inspect}) on ${on_string}">
+            <filter>method['method'] == 'Inspect' and method['inspect']['inspect'] != 'General'</filter>
+        </data>
+        <data name="inspect_general" format="txt" from_work_dir="inspect.txt" label="${tool.name} Inspect General on ${on_string}">
+            <filter>method['method'] == 'Inspect' and method['inspect']['inspect'] == 'General'</filter>
+        </data>
+    </xml>
+    <token name="@CMD_inspect_rds_outputs@"><![CDATA[
+write.table(inspect, 'inspect_out.tab', sep="\t", col.names = col.names, row.names = row.names, quote = FALSE)    
+    ]]>
+    </token>
+    <xml name="plot_out">
+        <data name="plot_out_png" format="png" from_work_dir="plot.png" label="${tool.name} (${method.method}) on ${on_string}: png plot">
+            <filter>plot_format == 'png'</filter>
+        </data>
+        <data name="plot_out_pdf" format="pdf" from_work_dir="plot.pdf" label="${tool.name} (${method.method}) on ${on_string}: pdf plot">
+            <filter>plot_format == 'pdf'</filter>
+        </data>
+        <data name="plot_out_svg" format="svg" from_work_dir="plot.svg" label="${tool.name} (${method.method}) on ${on_string}: svg plot">
+            <filter>plot_format == 'svg'</filter>
+        </data>
+        <data name="plot_out_jpeg" format="jpeg" from_work_dir="plot.jpeg" label="${tool.name} (${method.method}) on ${on_string}: jpeg plot">
+            <filter>plot_format == 'jpeg'</filter>
+        </data>
+        <data name="plot_out_tex" format="tex" from_work_dir="plot.tex" label="${tool.name} (${method.method}) on ${on_string}: tex plot">
+            <filter>plot_format == 'tex'</filter>
+        </data>
+        <data name="plot_out_tiff" format="tiff" from_work_dir="plot.tiff" label="${tool.name} (${method.method}) on ${on_string}: tiff plot">
+            <filter>plot_format == 'tiff'</filter>
+        </data>
+        <data name="plot_out_eps" format="eps" from_work_dir="plot.eps" label="${tool.name} (${method.method}) on ${on_string}: eps plot">
+            <filter>plot_format == 'eps'</filter>
+        </data>
+    </xml>
+    <xml name="param_eps" tokens="eps_value">
+        <param argument="eps" type="float" value="@EPS_VALUE@"  label="Small number to avoid numerical errors"/>
+    </xml>
+    <xml name="valid_name">
+        <validator type="regex" message="Please only use letters, numbers, or _ - .">^[\w\-.]+$</validator>
+    </xml>
+    <xml name="valid_reduction_key">
+        <validator type="regex" message="Please only use letters and _">^[A-Za-z_]+$</validator>
+    </xml>
+    <xml name="valid_list">
+        <validator type="regex" message="Please only use letters, numbers, or _ - . ,">^[\w\-., ]+$</validator>
+    </xml>
+    <xml name="valid_cell_name">
+        <validator type="regex" message="Please only use letters, numbers, or punctuation marks">^[\w[:punct:]]+$</validator>
+    </xml>
+    <xml name="valid_cell_list">
+        <validator type="regex" message="Please only use letters, numbers, or punctuation marks">^[\w[:punct:]]+$</validator>
+    </xml>
+    <xml name="select_assay">
+        <param argument="assay" type="text" optional="true" value="" label="Name of assay to use" help="leave blank to use default assay">
+            <expand macro="valid_name"/>
+        </param>
+    </xml>
+    <xml name="select_assay_RNA">
+        <param argument="assay" type="text" value="RNA" label="Name of assay to use">
+            <expand macro="valid_name"/>
+        </param>
+    </xml>
+    <xml name="select_slot_data">
+        <param argument="slot" type="select" label="Slot to pull data from">
+                    <option value="counts">counts</option>
+                    <option value="data" selected="true">data</option>
+                    <option value="scale.data">scale.data</option>
+                    <option value="raw.data">raw.data</option>
+        </param>
+    </xml>
+    <xml name="select_slot_scale">
+        <param argument="slot" type="select" label="Slot to pull data from">
+                    <option value="counts">counts</option>
+                    <option value="data">data</option>
+                    <option value="scale.data" selected="true">scale.data</option>
+                    <option value="raw.data">raw.data</option>
+        </param>
+    </xml>
+    <xml name="select_slot_counts">
+        <param argument="slot" type="select" label="Slot to pull data from">
+                    <option value="counts" selected="true">counts</option>
+                    <option value="data">data</option>
+                    <option value="scale.data">scale.data</option>
+                    <option value="raw.data">raw.data</option>
+        </param>
+    </xml>
+    <xml name="select_layer">
+        <param argument="layer" type="text" optional="true" value="" label="Layer to pull data from" help="leave blank to use default">
+            <expand macro="valid_name"/>
+        </param>
+    </xml>
+    <xml name="select_reduction_pca">
+        <param argument="reduction" type="text" value="pca" label="Name of reduction to use" help="default is pca">
+            <expand macro="valid_name"/>
+        </param>
+    </xml>
+    <xml name="select_reduction_umap">
+        <param argument="reduction" type="text" value="umap" label="Name of reduction to use" help="first defaults to umap, then tsne, then pca">
+            <expand macro="valid_name"/>
+        </param>
+    </xml>
+    <xml name="set_topN">
+        <param name="topN" type="integer" value="10" label="Number to show"/>
+    </xml>
+    <xml name="set_dims">
+        <param argument="dims" type="integer" optional="true" value="10" label="Number of dimensions from reduction to use as input"/>
+    </xml>
+    <xml name="normalize">
+        <conditional name="normalization_method">
+                    <param name="normalization_method" type="select" label="Method for normalization" help="(normalization.method)">
+                        <option value="LogNormalize" selected="true">LogNormalize</option>
+                        <option value="CLR">CLR</option>
+                        <option value="RC">RC</option>
+                    </param>
+                    <when value="LogNormalize"></when>
+                    <when value="CLR">
+                        <param argument="margin" type="select" checked="true" label="Normalize across features (1) or cells (2)">
+                            <option value="1" selected="true">features</option>
+                            <option value="2">cells</option>
+                        </param>
+                    </when>
+                    <when value="RC"></when>
+                </conditional>
+                <param name="scale_factor" type="integer" value="10000" label="Set scale factor for normalization" help="(scale.factor)"/>
+                <param name="block_size" type="integer" optional="true" value="" label="Number of cells to run in each block" help="(block.size)"/>
+    </xml>
+    <xml name="integration_inputs">
+        <param argument="dims" type="integer" value="30" label="Number of dimensions from reduction to use for integration"/>
+        <param name="dims_to_integrate" type="integer" optional="true" value="" label="Number of dimensions to return integrated values for" help="(dims.to.integrate)"/>
+        <param name="k_weight" type="integer" value="100" label="Number of neighbors to consider when weighting anchors" help="(k.weight)"/>
+        <param name="weight_reduction" type="text" optional="true" value="" label="Name of reduction(s) to use for calculating anchor weights" help="leave blank to use full corrected space (weight.reduction)">
+            <expand macro="valid_list"/>
+        </param>
+        <param name="sd_weight" type="float" value="1" label="Controls bandwidth of Gaussian kernel for weighting"/>
+        <param name="preserve_order" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Preserve order" help="do not reorder objects based on size for each pairwise integration (preserve.order)"/>
+    </xml>
+    <xml name="markers_inputs">
+        <param argument="features" type="data" format="txt,tabular" optional="true" value="" label="Features to test" help="text file with one feature on each line, leave empty to use all genes"/>
+        <param name="logfc_threshold" type="float" value="0.1" label="Minimum log-fold difference to test" help="(logfc.threshold)"/>
+        <conditional name="test_use">
+            <param name="test_use" type="select" label="Select test to run" help="(test.use)">
+                <option value="wilcox" selected="true">wilcox</option>
+                <option value="wilcox_limma">wilcox_limma</option>
+                <option value="bimod">bimod</option>
+                <option value="roc">roc</option>
+                <option value="t">t</option>
+                <option value="negbinom">negbinom</option>
+                <option value="poisson">poisson</option>
+                <option value="LR">LR</option>
+                <option value="MAST">MAST</option>
+                <option value="DESeq2">DESeq2</option>
+            </param>
+            <when value="wilcox">
+                <expand macro="select_slot_data"/>
+            </when>
+            <when value="wilcox_limma">
+                <expand macro="select_slot_data"/>
+            </when>
+            <when value="bimod">
+                <expand macro="select_slot_data"/>
+            </when>
+            <when value="roc">
+                <expand macro="select_slot_data"/>
+                <param name="return_thresh" type="float" value="0.01" min="0.0" max="1.0" label="Only return markers with a p-value below or power above this threshold" help="(return.thresh)"/>
+            </when>
+            <when value="t">
+                <expand macro="select_slot_data"/>
+            </when>
+            <when value="negbinom">
+                <expand macro="select_slot_counts"/>
+                <param name="latent_vars" type="text" optional="true" value="" label="Select variables to test" help="(latent.vars)"/>
+                <param name="min_cells_feature" type="integer" value="3" label="Minimum number of cells expressing the feature in at least one cluster" help="(min.cells.feature)"/>
+            </when>
+            <when value="poisson">
+                <expand macro="select_slot_counts"/>
+                <param name="latent_vars" type="text" optional="true" value="" label="Select variables to test" help="(latent.vars)"/>
+                <param name="min_cells_feature" type="integer" value="3" label="Minimum number of cells expressing the feature in at least one cluster" help="(min.cells.feature)"/>
+            </when>
+            <when value="LR">
+                <expand macro="select_slot_data"/>
+                <param name="latent_vars" type="text" optional="true" value="" label="Select variables to test" help="(latent.vars)"/>
+            </when>
+            <when value="MAST">
+                <expand macro="select_slot_data"/>
+                <param name="latent_vars" type="text" optional="true" value="" label="Select variables to test" help="(latent.vars)"/>
+            </when>
+            <when value="DESeq2">
+                <expand macro="select_slot_counts"/>
+            </when>
+        </conditional>
+    </xml>
+    <xml name="advanced_markers_inputs">
+        <expand macro="select_assay"/>
+        <param name="fc_name" type="text" optional="true" value="" label="Choose a name for the fold change, average difference, or custom function column" help="(fc.name)">
+            <expand macro="valid_name"/>
+        </param>
+        <param name="min_pct" type="float" value="0.01" min="0" max="100" label="Minimum percentage of cells genes must be present in to be tested" help="(min.pct)"/>
+        <param name="min_diff_pct" type="float" optional="true" value="" label="Minimum difference in percentage of expression between groups for genes to be tested" help="defaults to -Inf (min.diff.pct)"/>
+        <param name="only_pos" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Only return positive markers" help="(only.pos)"/>
+        <param name="max_cells_per_ident" type="integer" optional="true" value="" label="Downsample each identity class to a max number of cells" help="defaults to Inf for no downsampling (max.cells.per.ident)"/>
+        <param name="random_seed" type="integer" optional = "true" value="1" label="Set a random seed for downsampling" help="(random.seed)"/>
+        <param name="min_cells_group" type="integer" value="3" label="Minimum number of cells in one group" help="(min.cells.group)"/>
+        <param argument="densify" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Convert to dense matrix before running DE test"/>
+    </xml>
+    <xml name="plot_types">
+        <param name="plot_format" type="select" label="Format of plot to produce">
+        <option value="png">png</option>
+        <option value="pdf">pdf</option>
+        <option value="svg">svg</option>
+        <option value="jpeg">jpeg</option>
+        <option value="tex">tex</option>
+        <option value="tiff">tiff</option>
+        <option value="eps">eps</option>
+        </param>
+    </xml>
+    <xml name="plot_sizes">
+        <conditional name="resize">
+        <param name="resize" type="select" label="Change size of plot">
+            <option value="false" selected="true">No</option>
+            <option value="true">Yes</option>
+        </param>
+        <when value="false"></when>
+        <when value="true">
+            <param argument="width" type="integer" value="2100" label="Width of plot in pixels"/>
+            <param argument="height" type="integer" value="2100" label="Height of plot in pixels"/>
+        </when>
+        </conditional>
+    </xml>
+    <xml name="plot_cols">
+        <param argument="cols" type="text" optional="true" value="" label="Colours to use for plotting" help="comma separated list">
+            <expand macro="valid_list"/>
+        </param>
+    </xml>
+    <xml name="plot_log_scale">
+        <param argument="log" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Plot on a log scale"/>
+    </xml>
+    <xml name="plot_2_dims">
+        <param name="dims_1" type="integer" value="1" label="Dimension to plot on x axis"/>
+        <param name="dims_2" type="integer" value="2" label="Dimension to plot on y axis"/>
+    </xml>
+    <xml name="plot_projected_and_balanced">
+        <param argument="projected" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Use reduction values for full dataset" help="i.e. projected dimensional reduction values"/>
+        <param argument="balanced" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Return an equal number of genes with + and - scores"/>
+    </xml>
+    <xml name="plot_disp_min_max">
+        <param name="disp_min" type="float" optional="true" value="-2.5" label="Minimum display value" help="all values below are clipped (disp.min)"/>
+        <param name="disp_max" type="float" optional="true" value="" label="Maximum display value" help="all values above are clipped. Defaults to 2.5 if slot is scale.data, otherwise defaults to 6 (disp.max)"/>
+    </xml>
+    <xml name="plot_shuffle_and_seed">
+        <conditional name="shuffle">
+            <param argument="shuffle" type="select" label="Randomly shuffle order of points" help="can help with crowded plots if points of interest are hidden">
+                <option value="TRUE">Yes</option>
+                <option value="FALSE" selected="true">No</option>
+            </param>
+            <when value="TRUE">
+                <param argument="seed" type="integer" value="1" label="Set random seed for shuffling"/>
+            </when>
+            <when value="FALSE"></when>
+        </conditional>
+    </xml>
+    <xml name="plot_order">
+        <param argument="order" type="text" optional="true" value="" label="Specify the order of plotting for the idents" help="a full comma-separated list or the ident to be plotted last on the top">
+            <expand macro="valid_list"/>
+        </param>
+    </xml>
+    <xml name="plot_group_by">
+        <param name="group_by" type="text" optional="true" value="" label="Factor to group cells by" help="(group.by)"/>
+    </xml>
+    <xml name="plot_split_by">
+        <param name="split_by" type="text" optional="true" value="" label="Factor or identity to split the plot by" help="(split.by)"/>
+    </xml>
+    <xml name="plot_alpha">
+        <param argument="alpha" type="integer" value="1" label="Alpha value for points"/>
+    </xml>
+    <xml name="plot_pt_size">
+        <param name="pt_size" type="float" optional="true" value="" label="Point size for plot" help="(pt.size)"/>
+    </xml>
+    <xml name="plot_smooth">
+        <param argument="smooth" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Smooth the graph"/>
+    </xml>
+    <xml name="plot_ncol">
+        <param argument="ncol" type="integer" optional="true" value="" label="Number of columns to display"/>
+    </xml>
+    <xml name="raster_select">
+        <conditional name="raster">
+            <param argument="raster" type="select" label="Convert points to raster format" help="NULL will automatically use raster if more than 100,000 points plotted">
+                <option value="NULL" selected="true">NULL</option>
+                <option value="TRUE">TRUE</option>
+                <option value="FALSE">FALSE</option>
+            </param>
+            <when value="NULL"></when>
+            <when value="TRUE">
+                <param name="raster_x" type="integer" value="512" label="Horizontal length of raster plot (pixels)"/>
+                <param name="raster_y" type="integer" value="512" label="Vertical height of raster plot (pixels)"/>
+            </when>
+            <when value="FALSE"></when>
+        </conditional>
+    </xml>
+    <xml name="raster_boolean">
+        <param argument="raster" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="true" label="Convert to raster format"/>
+    </xml>
+</macros>