changeset 0:94f1b9c7286f 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:37 +0000
parents
children
files macros.xml neighbors_clusters_markers.xml
diffstat 2 files changed, 1268 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/macros.xml	Wed Sep 11 10:21:37 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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/neighbors_clusters_markers.xml	Wed Sep 11 10:21:37 2024 +0000
@@ -0,0 +1,831 @@
+<tool id="seurat_clustering" name="Seurat Find Clusters" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="@PROFILE@">
+    <description>- Neighbors and Markers</description>
+    <macros>
+        <import>macros.xml</import>
+    </macros>
+    <expand macro="requirements"/>
+    <expand macro="version_command"/>
+    <command detect_errors="exit_code"><![CDATA[
+@CMD@
+    ]]></command>
+    <configfiles>
+        <configfile name="script_file"><![CDATA[
+@CMD_imports@
+@CMD_read_inputs@
+
+#if $method.method == 'FindNeighbors'
+seurat_obj<-FindNeighbors(
+    seurat_obj,
+    #if $method.reduction != ''
+    reduction = '$method.reduction',
+    #end if
+    #if $method.dims != ''
+    dims = 1:$method.dims,
+    #end if
+    k.param = $method.k_param,
+    nn.method = '$method.nn_method.nn_method',
+    #if $method.nn_method.nn_method == 'rann'
+    nn.eps = $method.nn_method.nn_eps,
+    #else if $method.nn_method.nn_method == 'annoy'
+    annoy.metric = '$method.nn_method.annoy_metric',
+    #end if
+    compute.snn = $method.adv.compute_snn.compute_snn,
+    #if $method.adv.compute_snn.compute_snn == 'TRUE'
+        #if $method.adv.compute_snn.prune_snn
+        prune.snn = $method.adv.compute_snn.prune_snn,
+        #end if
+        distance.matrix = $method.adv.compute_snn.distance_matrix,
+    #else if $method.adv.compute_snn.compute_snn == 'FALSE'
+        distance.matrix = $method.adv.compute_snn.distance_matrix.distance_matrix,
+        #if $method.adv.compute_snn.distance_matrix.distance_matrix == 'FALSE'
+        return.neighbor = $method.adv.compute_snn.distance_matrix.return_neighbor,
+        #end if
+    #end if
+    l2.norm = $method.adv.l2_norm,
+    n.trees = $method.adv.n_trees
+)
+
+#else if $method.method == 'FindMultiModalNeighbors'
+seurat_obj<-FindMultiModalNeighbors(
+    seurat_obj,
+    reduction.list = list('$method.reduction_1', '$method.reduction_2'),
+    dims.list = list(1:$method.dims_1, 1:$method.dims_2),
+    k.nn = $method.k_nn,
+    knn.graph.name = '$method.adv.knn_graph_name',
+    snn.graph.name = '$method.adv.snn_graph_name',
+    weighted.nn.name = '$method.adv.weighted_nn_name',
+    #if $method.adv.modality_weight_name != ''
+    modality.weight.name = '$method.adv.modality_weight_name',
+    #end if
+    knn.range = $method.adv.knn_range
+)
+
+#else if $method.method == 'FindClusters'
+@reticulate_hack@
+seurat_obj<-FindClusters(
+    seurat_obj,
+    modularity.fxn = $method.modularity_fxn,
+    resolution = $method.resolution,
+    algorithm = $method.algorithm.algorithm,
+    #if $method.algorithm.algorithm == '4'
+        #if $method.algorithm.initial_membership
+        initial.membership = $method.algorithm.initial_membership,
+        #end if
+        #if $method.algorithm.node_sizes
+        node.sizes = $method.algorithm.node_sizes,
+        #end if
+        method = '$method.algorithm.method_cluster',
+    #end if
+    n.start = $method.n_start,
+    n.iter = $method.n_iter,
+    random.seed = $method.random_seed,
+    #if $method.graph_name != ''
+    graph.name = '$method.graph_name',
+    #end if
+    #if $method.cluster_name != ''
+    cluster.name = '$method.cluster_name'
+    #end if
+)
+
+#else if $method.method == 'FindAllMarkers'
+
+    #if $method.features
+    features_list<-paste(readLines('$method.features'), collapse=",")
+    #end if
+
+seurat_obj<-FindAllMarkers(
+    seurat_obj,
+    #if $method.features
+        features = c(unlist(strsplit(features_list, ","))),
+    #end if
+    logfc.threshold = $method.logfc_threshold,
+    test.use = '$method.test_use.test_use',
+    #if $method.test_use.test_use == 'negbinom'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+        min.cells.feature = $method.test_use.min_cells_feature,
+    #else if $method.test_use.test_use == 'poisson'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+        min.cells.feature = $method.test_use.min_cells_feature,
+    #else if $method.test_use.test_use =='LR'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+    #else if $method.test_use.test_use == 'MAST'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+    #else if $method.test_use.test_use == 'roc'
+        return.thresh = $method.test_use.return_thresh,
+    #end if
+    slot = '$method.slot',
+    #if $method.adv.assay != ''
+    assay = '$method.adv.assay',
+    #end if
+    min.pct = $method.adv.min_pct,
+    #if $method.adv.min_diff_pct
+    min.diff.pct = $method.adv.min_diff_pct,
+    #end if
+    only.pos = $method.adv.only_pos,
+    #if $method.adv.max_cells_per_ident
+    max.cells.per.ident = $method.adv.max_cells_per_ident,
+    #end if
+    #if $method.adv.random_seed
+    random.seed = $method.adv.random_seed,
+    #end if
+    min.cells.group = $method.adv.min_cells_group,
+    #if $method.fc_name != ''
+    fc.name = '$method.adv.fc_name',
+    #end if
+    base = $method.adv.base,
+    densify = $method.adv.densify
+)
+
+    #if $method.set_top_markers.set_top_markers == 'true'
+    N = $method.set_top_markers.topN
+    seurat_obj<-dplyr::slice_head(seurat_obj, n = N, by = cluster)
+    #end if
+
+@CMD_write_markers_tab@
+
+#else if $method.method == 'FindMarkers'
+
+    #if $method.features
+    features_list<-paste(readLines('$method.features'), collapse=",")
+    #end if
+    #if $method.cells.cells == 'true'
+    cell_1_list<-paste(readLines('$method.cells_1'), collapse=",")
+    cell_2_list<-paste(readLines('$method.cells_2'), collapse=",")
+    #end if
+
+seurat_obj<-FindMarkers(
+    seurat_obj,
+    slot = '$method.slot',
+    #if $method.cells.cells == 'true'
+    cells.1 = c(unlist(strsplit(cell_1_list, ","))),
+    cells.2 = c(unlist(strsplit(cell_2_list, ","))),
+    #end if
+    #if $method.regroup.regroup == 'true'
+    group.by = '$method.regroup.group_by',
+        #if $method.regroup.subset_ident != ''
+        subset.ident = '$method.regroup.subset_ident',
+        #end if
+    #end if
+    #if $method.ident.ident == 'true'
+    ident.1 = '$method.ident.ident_1',
+        #if $method.ident.ident_2 != ''
+        ident.2 = c(unlist(strsplit(gsub(" ", "", '$method.ident.ident_2'), ","))),
+        #end if
+    #end if
+    #if $method.features
+    features = c(unlist(strsplit(features_list, ","))),
+    #end if
+    logfc.threshold = $method.logfc_threshold,
+    test.use = '$method.test_use.test_use',
+    #if $method.test_use.test_use == 'negbinom'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+        min.cells.feature = $method.test_use.min_cells_feature,
+    #else if $method.test_use.test_use == 'poisson'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+        min.cells.feature = $method.test_use.min_cells_feature,
+    #else if $method.test_use.test_use =='LR'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+    #else if $method.test_use.test_use == 'MAST'
+        #if $method.test_use.latent_vars != ''
+        latent.vars = c(unlist(strsplit(gsub(" ", "", '$method.test_use.latent_vars'), ","))),
+        #end if
+    #end if
+    #if $method.adv.assay != ''
+    assay = '$method.adv.assay',
+    #end if
+    min.pct = $method.adv.min_pct,
+    #if $method.adv.min_diff_pct
+    min.diff.pct = $method.adv.min_diff_pct,
+    #end if
+    only.pos = $method.adv.only_pos,
+    #if $method.adv.max_cells_per_ident
+    max.cells.per.ident = $method.adv.max_cells_per_ident,
+    #end if
+    #if $method.adv.random_seed
+    random.seed = $method.adv.random_seed,
+    #end if
+    min.cells.group = $method.adv.min_cells_group,
+    #if $method.adv.fc_name != ''
+    fc.name = '$method.adv.fc_name',
+    #end if
+    densify = $method.adv.densify
+)
+
+@CMD_write_markers_tab@
+
+#else if $method.method == 'FindConservedMarkers'
+seurat_obj<-FindConservedMarkers(
+    seurat_obj,
+    ident.1 = $method.ident_1,
+    #if $method.ident_2 != ''
+    ident.2 = $method.ident_2,
+    #end if
+    grouping.var = '$method.grouping_var',
+    #if $method.assay != ''
+    assay = '$method.assay',
+    #end if
+    slot = '$method.slot',
+    min.cells.group = $method.min_cells_group
+)
+
+@CMD_write_markers_tab@
+
+#end if
+
+@CMD_rds_write_outputs@
+
+]]></configfile>
+    </configfiles>
+    <inputs>
+        <expand macro="input_rds"/>
+        <conditional name="method">
+            <param name="method" type="select" label="Method used">
+                <option value="FindNeighbors">Compute nearest neighbors with 'FindNeighbors'</option>
+                <option value="FindMultiModalNeighbors">Compute nearest neighbors for multimodal data with 'FindMultiModalNeighbors'</option>
+                <option value="FindClusters">Identify cell clusters with 'FindClusters'</option>
+                <option value="FindAllMarkers">Identify marker genes with 'FindAllMarkers'</option>
+                <option value="FindMarkers">Identify marker genes for specific groups with 'FindMarkers'</option>
+                <option value="FindConservedMarkers">Find markers conserved between groups with 'FindConservedMarkers'</option>
+            </param>
+            <when value="FindNeighbors">
+                <expand macro="select_reduction_pca"/>
+                <expand macro="set_dims"/>
+                <param name="k_param" type="integer" value="20" label="Set k for k-nearest neighbors" help="(k.param)"/>
+                <conditional name="nn_method">
+                    <param name="nn_method" type="select" label="Method for finding nearest neighbors" help="(nn.method)">
+                        <option value="rann">rann</option>
+                        <option value="annoy" selected="true">annoy</option>
+                    </param>
+                    <when value="rann">
+                        <param name="nn_eps" type="float" value="0.0" label="Set error bound for nearest neighbor search" help="(nn.eps)"/>
+                    </when>
+                    <when value="annoy">
+                        <param name="annoy_metric" type="select" label="Distance metric for annoy method" help="(annoy.metric)">
+                            <option value="euclidean" selected="true">euclidean</option>
+                            <option value="cosine">cosine</option>
+                            <option value="manhattan">manhattan</option>
+                            <option value="hamming">hamming</option>
+                        </param>
+                    </when>
+                </conditional>
+                <section name="adv" title="Advanced Options">
+                    <param name="n_trees" type="integer" value="50" label="Number of trees for nearest neighbor search" help="(n.trees)"/>
+                    <param name="l2_norm" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Take l2Norm of data" help="(l2.norm)"/>
+                    <conditional name="compute_snn">
+                        <param name="compute_snn" type="select" label="Compute the shared nearest neighbor (SNN) graph" help="(compute.snn)">
+                            <option value="FALSE">No</option>
+                            <option value="TRUE" selected="true">Yes</option>
+                        </param>
+                        <when value="FALSE">
+                            <conditional name="distance_matrix">
+                                <param name="distance_matrix" type="select" label="Use a distance matrix" help="(distance.matrix)">
+                                    <option value="FALSE" selected="true">No</option>
+                                    <option value="TRUE">Yes</option>
+                                </param>
+                                <when value="FALSE">
+                                    <param name="return_neighbor" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Return result as neighbor object" help="(return.neighbor)"/>
+                                </when>
+                                <when value="TRUE"></when>
+                            </conditional>
+                        </when>
+                        <when value="TRUE">
+                            <param name="prune_snn" type="float" optional="true" value="" min="0" max="1" label="Set cutoff for Jaccard index when computing overlap for SNN" help="0 no pruning, 1 prune everything (prune.SNN)"/>
+                            <param name="distance_matrix" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="false" label="Use a distance matrix" help="(distance.matrix)"/>
+                        </when>
+                    </conditional>
+                </section>
+            </when>
+            <when value="FindMultiModalNeighbors">
+                <param name="reduction_1" type="text" value="pca" label="Reduction to use for first modality">
+                    <expand macro="valid_name"/>
+                </param>
+                <param name="dims_1" type="integer" value="10" label="Number of dimensions to use from first reduction"/>
+                <param name="reduction_2" type="text" value="apca" label="Reduction to use for second modality">
+                    <expand macro="valid_name"/>
+                </param>
+                <param name="dims_2" type="integer" value="10" label="Number of dimensions to use from second reduction"/>
+                <param name="k_nn" type="integer" value="20" label="Number of multimodal neighbors to compute" help="(k.nn)"/>
+                <section name="adv" title="Advanced Options">
+                    <param name="knn_graph_name" type="text" value="wknn" label="Name for multimodal knn graph" help="(knn.graph.name)">
+                        <expand macro="valid_name"/>
+                    </param>
+                    <param name="snn_graph_name" type="text" value="wsnn" label="Name for multimodal snn graph" help="(snn.graph.name)">
+                        <expand macro="valid_name"/>
+                    </param>
+                    <param name="weighted_nn_name" type="text" value="weighted.nn" label="Name for multimodal neighbor object" help="(weighted.nn.name)">
+                        <expand macro="valid_name"/>
+                    </param>
+                    <param name="modality_weight_name" optional="true" type="text" value="" label="Name for storing modality weights in metadata" help="(modality.weight.name)">
+                        <expand macro="valid_name"/>
+                    </param>
+                    <param name="knn_range" type="integer" value="200" label="Number of approximate neighbors to compute" help="(knn.range)"/>
+                </section>
+            </when>
+            <when value="FindClusters">
+                <param name="modularity_fxn" type="select" label="Select modularity function" help="(modularity.fxn)">
+                    <option value="1" selected="true">standard</option>
+                    <option value="2">alternative</option>
+                </param>
+                <param argument="resolution" type="float" value="0.8" label="Resolution"/>
+                <conditional name="algorithm">
+                    <param argument="algorithm" type="select" label="Algorithm for modularity optimization">
+                        <option value="1" selected="true">1. Original Louvain</option>
+                        <option value="2">2. Louvain with multilevel refinement</option>
+                        <option value="3">3. SLM</option>
+                        <option value="4">4. Leiden</option>
+                    </param>
+                    <when value="4">
+                        <param name="initial_membership" type="integer" optional="true" value="" label="Set initial membership when using Python leidenalg function" help="defaults to singleton partition (initial.membership)"/>
+                        <param name="node_sizes" type="integer" optional="true" value="" label="Set node size when using Python leidenalg function" help="(node.sizes)"/>
+                        <param name="method_cluster" type="select" label="Method for leiden" help="matrix is fast for small data, enable igraph for larger data (method.cluster)">
+                            <option value="matrix" selected="true">matrix</option>
+                            <option value="igraph">igraph</option>
+                        </param>
+                    </when>
+                    <when value="1">
+                    </when>
+                    <when value="2">
+                    </when>
+                    <when value="3">
+                    </when>
+                </conditional>
+                <param name="n_start" type="integer" value="10" label="Number of random starts" help="(n.start)"/>
+                <param name="n_iter" type="integer" value="10" label="Maximal number of iterations per random start" help="(n.iter)"/>
+                <param name="random_seed" type="integer" value="0" label="Set random seed" help="(random.seed)"/>
+                <param name="group_singletons" type="boolean" truevalue="TRUE" falsevalue="FALSE" checked="true" label="Group singletons into nearest cluster" help="Set to false to create a cluster for all singletons (group.singletons)"/>
+                <param name="graph_name" type="text" optional="true" value="" label="Name of graph to use for the clustering algorithm" help="(graph.name)">
+                    <expand macro="valid_name"/>
+                </param>
+                <param name="cluster_name" type="text" optional="true" value="" label="Name for output clusters" help="(cluster.name)">
+                    <expand macro="valid_name"/>
+                </param>
+            </when>
+            <when value="FindAllMarkers">
+                <expand macro="markers_inputs"/>
+                <conditional name="set_top_markers">
+                    <param name="set_top_markers" type="select" label="Limit output to top N markers per cluster">
+                        <option value="true">Yes</option>
+                        <option value="false" selected="true">No</option>
+                    </param>
+                    <when value="true">
+                        <expand macro="set_topN"/>
+                    </when>
+                    <when value="false">
+                    </when>
+                </conditional>
+                <section name="adv" title="Advanced Options">
+                    <param argument="base" type="integer" value="2" label="Base with respect to which logarithms are computed"/>
+                    <expand macro="advanced_markers_inputs"/>
+                </section>
+            </when>
+            <when value="FindMarkers">
+                <conditional name="cells">
+                    <param name="cells" type="select" label="Compare markers for two groups of cells">
+                        <option value="true">Yes</option>
+                        <option value="false" selected="true">No</option>
+                    </param>
+                    <when value="true">
+                        <param name="cells_1" type="data" format="txt,tabular" label="List of cell names for group 1" help="text file with one cell on each line (cells.1)"/>
+                        <param name="cells_2" type="data" format="txt,tabular" label="List of cell names for group 2" help="text file with one cell on each line (cells.2)"/>
+                    </when>
+                    <when value="false">
+                    </when>
+                </conditional>
+                <conditional name="regroup">
+                    <param name="regroup" type="select" label="Change cell identities before finding markers">
+                        <option value="true">Yes</option>
+                        <option value="false" selected="true">No</option>
+                    </param>
+                    <when value="true">
+                        <param name="group_by" type="text" value="group" label="Name of identity class to regroup cells into" help="a group from the cell metadata to find markers for (group.by)"/>
+                        <param name="subset_ident" type="text" optional="true" value="" label="Identity class to subset before regrouping" help="only include cells from this cluster/identity in each new group (subset.ident)"/>
+                    </when>
+                    <when value="false">
+                    </when>
+                </conditional>
+                <conditional name="ident">
+                    <param name="ident" type="select" label="Compare markers between clusters of cells">
+                        <option value="true">Yes</option>
+                        <option value="false" selected="true">No</option>
+                    </param>
+                    <when value="true">
+                        <param name="ident_1" type="text" optional="true" value="" label="Identity class to define markers for" help="e.g. cluster number or ident group name (ident.1)"/>
+                        <param name="ident_2" type="text" optional="true" value="" label="Second identity class to compare" help="e.g. comma-separated list of cluster numbers or idents, leave blank to compare ident.1 against all other clusters. (ident.2)">
+                            <expand macro="valid_list"/>
+                        </param>
+                    </when>
+                    <when value="false">
+                    </when>
+                </conditional>
+                <expand macro="markers_inputs"/>
+                <section name="adv" title="Advanced Options">
+                    <expand macro="advanced_markers_inputs"/>
+                </section>
+            </when>
+            <when value="FindConservedMarkers">
+                <param name="ident_1" type="text" value="ident1" label="Identity class to define markers for" help="(ident.1)"/>
+                <param name="ident_2" type="text" optional="true" value="" label="Second identity class for comparison" help="leave blank to compare ident.1 to all other cells (ident.2)"/>
+                <param name="grouping_var" type="text" value="group" label="Grouping variable" help="(grouping.var)"/>
+                <expand macro="select_assay_RNA"/>
+                <expand macro="select_slot_data"/>
+                <param name="min_cells_group" type="integer" value="3" label="Minimum number of cells in one group" help="(min.cells.group)"/>
+            </when>
+        </conditional>
+        <expand macro="inputs_common_advanced"/>
+    </inputs>
+    <outputs>
+        <expand macro="seurat_outputs"/>
+        <expand macro="markers_out"/>
+    </outputs>
+    <tests>
+        <test expect_num_outputs="2">
+            <!-- test1: FindNeighbors -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/pca.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindNeighbors"/>
+                <param name="dims" value="9"/>
+                <conditional name="nn_method">
+                    <param name="nn_method" value="annoy"/>
+                    <param name="annoy_metric" value="euclidean"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindNeighbors"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/neighbors.rds" ftype="rds" compare="sim_size"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test2: FindMultiModalNeighbors -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/citeseq_dims.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindMultiModalNeighbors"/>
+                <param name="reduction_1" value="pca"/>
+                <param name="dims_1" value="8"/>
+                <param name="reduction_2" value="apca"/>
+                <param name="dims_2" value="8"/>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindMultiModalNeighbors"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/multimodalneighbors.rds" ftype="rds" compare="sim_size"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test3: FindClusters -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/neighbors.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindClusters"/>
+                <param name="resolution" value="0.8"/>
+                <conditional name="algorithm">
+                    <param name="algorithm" value="1"/>
+                </conditional>
+                <param name="n_start" value="10"/>
+                <param name="n_iter" value="10"/>
+                <param name="random_seed" value="0"/>
+                <param name="group_singletons" value="TRUE"/>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindClusters"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/clusters.rds" ftype="rds" compare="sim_size"/>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test4: FindClusters - leidenalg Installed -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/neighbors.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindClusters"/>
+                <param name="modularity_fxn" value="1"/>
+                <param name="resolution" value="0.5"/>
+                <conditional name="algorithm">
+                    <param name="algorithm" value="4"/>
+                    <param name="method_cluster" value="matrix"/>
+                </conditional>
+                <param name="n_start" value="10"/>
+                <param name="n_iter" value="10"/>
+                <param name="random_seed" value="0"/>
+                <param name="group_singletons" value="TRUE"/>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindClusters"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/clusters_leiden.rds" ftype="rds" compare="sim_size"/>
+        </test>
+        <test expect_num_outputs="3">
+            <!-- test5: FindAllMarkers -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/clusters.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindAllMarkers"/>
+                <param name="logfc_threshold" value="0.1"/>
+                <param name="slot" value="data"/>
+                <conditional name="test_use">
+                    <param name="test_use" value="wilcox"/>
+                </conditional>
+                <conditional name="set_top_markers">
+                    <param name="set_top_markers" value="true"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindAllMarkers"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/allmarkers.rds" ftype="rds"/>
+            <output name="markers_tabular" location="https://zenodo.org/records/13732784/files/allmarkers.csv" ftype="csv">
+                <assert_contents>
+                    <has_text_matching expression="avg_log2FC"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="3">
+            <!-- test6: FindMarkers - Default -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/clusters.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindMarkers"/>
+                <param name="slot" value="data"/>
+                <conditional name="cells">
+                    <param name="cells" value="false"/>
+                </conditional>
+                <conditional name="ident">
+                    <param name="ident" value="true"/>
+                    <param name="ident_1" value="0"/>
+                    <param name="ident_2" value="1"/>
+                </conditional>
+                <param name="logfc_threshold" value="0.1"/>
+                <conditional name="test_use">
+                    <param name="test_use" value="wilcox"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindMarkers"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/markers.rds" ftype="rds"/>
+            <output name="markers_tabular" location="https://zenodo.org/records/13732784/files/markers.csv" ftype="csv">
+                <assert_contents>
+                    <has_text_matching expression="avg_log2FC"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="3">
+            <!-- test7: FindMarkers - Limma Installed -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/clusters.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindMarkers"/>
+                <param name="slot" value="data"/>
+                <conditional name="cells">
+                    <param name="cells" value="false"/>
+                </conditional>
+                <conditional name="ident">
+                    <param name="ident" value="true"/>
+                    <param name="ident_1" value="0"/>
+                    <param name="ident_2" value="1"/>
+                </conditional>
+                <param name="logfc_threshold" value="0.1"/>
+                <conditional name="test_use">
+                    <param name="test_use" value="wilcox_limma"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindMarkers"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/markersLimma.rds" ftype="rds"/>
+            <output name="markers_tabular" location="https://zenodo.org/records/13732784/files/markersLimma.csv" ftype="csv">
+                <assert_contents>
+                    <has_text_matching expression="avg_log2FC"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="3">
+            <!-- test8: FindMarkers - MAST Installed -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/clusters.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindMarkers"/>
+                <param name="slot" value="data"/>
+                <conditional name="cells">
+                    <param name="cells" value="false"/>
+                </conditional>
+                <conditional name="ident">
+                    <param name="ident" value="true"/>
+                    <param name="ident_1" value="0"/>
+                    <param name="ident_2" value="1"/>
+                </conditional>
+                <param name="logfc_threshold" value="0.1"/>
+                <conditional name="test_use">
+                    <param name="test_use" value="MAST"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindMarkers"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/markersMAST.rds" ftype="rds"/>
+            <output name="markers_tabular" location="https://zenodo.org/records/13732784/files/markersMAST.csv" ftype="csv">
+                <assert_contents>
+                    <has_text_matching expression="avg_log2FC"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="3">
+            <!-- test9: FindMarkers - DESeq2 Installed -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/clusters.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindMarkers"/>
+                <param name="slot" value="counts"/>
+                <conditional name="cells">
+                    <param name="cells" value="false"/>
+                </conditional>
+                <conditional name="ident">
+                    <param name="ident" value="true"/>
+                    <param name="ident_1" value="0"/>
+                    <param name="ident_2" value="1"/>
+                </conditional>
+                <param name="logfc_threshold" value="0.1"/>
+                <conditional name="test_use">
+                    <param name="test_use" value="DESeq2"/>
+                </conditional>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindMarkers"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/markersDESeq2.rds" ftype="rds"/>
+            <output name="markers_tabular" location="https://zenodo.org/records/13732784/files/markersDESeq2.csv" ftype="csv">
+                <assert_contents>
+                    <has_text_matching expression="avg_log2FC"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="3">
+            <!-- test10: FindConservedMarkers -->
+            <param name="seurat_rds" location="https://zenodo.org/records/13732784/files/integrated_umap.rds"/>
+            <conditional name="method">
+                <param name="method" value="FindConservedMarkers"/>
+                <param name="ident_1" value="0"/>
+                <param name="ident_2" value="1"/>
+                <param name="grouping_var" value="Group"/>
+            </conditional>
+            <section name="advanced_common">
+                <param name="show_log" value="true"/>
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="FindConservedMarkers"/>
+                </assert_contents>
+            </output>
+            <output name="rds_out" location="https://zenodo.org/records/13732784/files/conserved_markers.rds" ftype="rds"/>
+            <output name="markers_tabular" location="https://zenodo.org/records/13732784/files/conserved_markers.csv" ftype="csv">
+                <assert_contents>
+                    <has_text_matching expression="Group_B_avg_log2FC"/>
+                </assert_contents>
+            </output>
+        </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.
+
+FindNeighbors
+=============
+
+Compute the k.param nearest neighbors for a given dataset.
+
+Can also optionally (via compute.SNN), construct a shared nearest neighbor graph by calculating the neighborhood overlap (Jaccard index) between every cell and its k.param nearest neighbors.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/findneighbors>`__
+
+FindMultiModalNeighbors
+=======================
+
+This function will construct a weighted nearest neighbor (WNN) graph for two modalities (e.g. RNA-seq and CITE-seq). For each cell, we identify the nearest neighbors based on a weighted combination of two modalities. 
+
+Takes as input two dimensional reductions, one computed for each modality.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/findmultimodalneighbors>`__
+
+FindClusters
+============
+
+Identify clusters of cells by a shared nearest neighbor (SNN) modularity optimization based clustering algorithm.
+
+First calculate k-nearest neighbors and construct the SNN graph. Then optimize the modularity function to determine clusters.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/findclusters>`__
+
+
+FindAllMarkers
+==============
+
+Find markers (differentially expressed genes) for each of the identity classes in a dataset
+
+Outputs a matrix containing a ranked list of putative markers, and associated statistics (p-values, ROC score, etc.)
+
+Methods:
+
+"wilcox" : Identifies differentially expressed genes between two groups of cells using a Wilcoxon Rank Sum test (default); will use a fast implementation by Presto if installed
+
+"wilcox_limma" : Identifies differentially expressed genes between two groups of cells using the limma implementation of the Wilcoxon Rank Sum test; set this option to reproduce results from Seurat v4
+
+"bimod" : Likelihood-ratio test for single cell gene expression, (McDavid et al., Bioinformatics, 2013)
+
+"roc" : Identifies 'markers' of gene expression using ROC analysis. For each gene, evaluates (using AUC) a classifier built on that gene alone, to classify between two groups of cells. An AUC value of 1 means that expression values for this gene alone can perfectly classify the two groupings (i.e. Each of the cells in cells.1 exhibit a higher level than each of the cells in cells.2). An AUC value of 0 also means there is perfect classification, but in the other direction. A value of 0.5 implies that the gene has no predictive power to classify the two groups. Returns a 'predictive power' (abs(AUC-0.5) * 2) ranked matrix of putative differentially expressed genes.
+
+"t" : Identify differentially expressed genes between two groups of cells using Student's t-test.
+
+"negbinom" : Identifies differentially expressed genes between two groups of cells using a negative binomial generalized linear model. Use only for UMI-based datasets
+
+"poisson" : Identifies differentially expressed genes between two groups of cells using a poisson generalized linear model. Use only for UMI-based datasets
+
+"LR" : Uses a logistic regression framework to determine differentially expressed genes. Constructs a logistic regression model predicting group membership based on each feature individually and compares this to a null model with a likelihood ratio test.
+
+"MAST" : Identifies differentially expressed genes between two groups of cells using a hurdle model tailored to scRNA-seq data. Utilizes the MAST package to run the DE testing.
+
+"DESeq2" : Identifies differentially expressed genes between two groups of cells based on a model using DESeq2 which uses a negative binomial distribution (Love et al, Genome Biology, 2014).This test does not support pre-filtering of genes based on average difference (or percent detection rate) between cell groups. However, genes may be pre-filtered based on their minimum detection rate (min.pct) across both cell groups.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/findallmarkers>`__
+
+FindMarkers
+===========
+
+Find markers (differentially expressed genes) for identity classes (clusters) or groups of cells
+
+Outputs a data.frame with a ranked list of putative markers as rows, and associated statistics as columns (p-values, ROC score, etc., depending on the test used (test.use)).
+
+Methods - as for FindAllMarkers
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/findmarkers>`__
+
+FindConservedMarkers
+====================
+
+Finds markers that are conserved between the groups
+
+Uses metap::minimump as meta.method.
+
+More details on the `seurat documentation
+<https://satijalab.org/seurat/reference/findconservedmarkers>`__
+
+    ]]></help>
+    <expand macro="citations"/>
+</tool>
\ No newline at end of file