changeset 0:b82f44c4e8af draft

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/muon/ commit bcf2ec32c3d13b29da55e0e638da7ddd7162c436
author iuc
date Wed, 05 Feb 2025 10:53:32 +0000
parents
children a8f0f1cf5152
files cluster_analyze_embed_muon.xml macros.xml
diffstat 2 files changed, 729 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cluster_analyze_embed_muon.xml	Wed Feb 05 10:53:32 2025 +0000
@@ -0,0 +1,465 @@
+<tool id="cluster_analyze_embed_muon" name="muon Cluster, analyze, and embed multimodal data" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="@PROFILE@">
+    <macros>
+        <import>macros.xml</import>
+    </macros>
+    <expand macro="bio_tools"/>
+    <expand macro="requirements"/>
+    <expand macro="version_command"/>
+    <command detect_errors="exit_code"><![CDATA[
+@COPY_MUDATA@
+@CMD@
+]]></command>
+    <configfiles>
+        <configfile name="script_file"><![CDATA[
+@CMD_imports@
+@CMD_read_inputs@
+
+#if $method.method == 'tl.louvain'
+mu.tl.louvain(
+    mdata,
+    @CMD_params_clustering@
+)
+
+#else if $method.method == 'tl.leiden'
+mu.tl.leiden(
+    mdata,
+    @CMD_params_clustering@
+)
+
+#else if $method.method == 'tl.mofa'
+mu.tl.mofa(
+    mdata,
+    #if $method.groups_label
+    groups_label='$method.groups_label',
+    #end if
+    use_raw=$method.use_raw,
+    #if $method.use_layer
+    use_layer='$method.use_layer',
+    #end if
+    #if $method.use_var
+    use_var='$method.use_var',
+    #end if
+    #if str($method.use_obs) != 'None'
+    use_obs='$method.use_obs',
+    #end if
+    n_factors=$method.n_factors,
+    scale_views=$method.scale_views,
+    scale_groups=$method.scale_groups,
+    center_groups=$method.center_groups,
+    ard_weights=$method.ard_weights,
+    ard_factors=$method.ard_factors,
+    spikeslab_weights=$method.spikeslab_weights,
+    spikeslab_factors=$method.spikeslab_factors,
+    n_iterations=$method.n_iterations,
+    convergence_mode='$method.convergence_mode',
+    use_float32=$method.use_float32,
+    #if $method.svi.svi_mode == 'yes'
+    svi_batch_size=$method.svi.svi_batch_size,
+    svi_learning_rate=$method.svi.svi_learning_rate,
+    svi_forgetting_rate=$method.svi.svi_forgetting_rate,
+    svi_start_stochastic=$method.svi.svi_start_stochastic,
+    #end if
+    #if $method.smooth_covariate
+    smooth_covariate='$method.smooth_covariate',
+    #end if
+    smooth_warping=$method.smooth_warping,
+    seed=$method.seed,
+    copy=False
+)
+
+#else if $method.method == 'tl.umap'
+mu.tl.umap(
+    mdata,
+    min_dist=$method.min_dist,
+    spread=$method.spread,
+    n_components=$method.n_components,
+    #if str($method.maxiter)
+    maxiter=$method.maxiter,
+    #end if
+    alpha=$method.alpha,
+    gamma=$method.gamma,
+    negative_sample_rate=$method.negative_sample_rate,
+    init_pos='$method.init_pos',
+    random_state=$method.random_state,
+    #if $method.neighbors_key
+    neighbors_key='$method.neighbors_key',
+    #end if
+    copy=False
+)
+#end if
+
+@CMD_mudata_write_outputs@
+]]></configfile>
+    </configfiles>
+    <inputs>
+        <expand macro="inputs_mudata"/>
+        <conditional name="method">
+            <param name="method" type="select" label="Method used for processing">
+                <option value="tl.leiden">Cluster: Cluster cells using the Leiden algorithm, using 'muon.tl.leiden'</option>
+                <option value="tl.louvain">Cluster: Cluster cells using the Louvain algorithm, using 'muon.tl.louvain'</option>
+                <option value="tl.mofa">Analyze: Run Multi Omics Factor Analysis, using 'muon.tl.mofa'</option>
+                <option value="tl.umap">Embed: Embed the multimodal neighborhood graph using UMAP, using 'muon.tl.umap'</option>
+            </param>
+            <when value="tl.leiden">
+                <expand macro="param_resolution"/>
+                <expand macro="param_weight"/>
+                <expand macro="param_random_state" seed="0"/>
+                <expand macro="param_key_added" key_added="leiden"/>
+                <expand macro="param_neighbors_key"/>
+                <expand macro="param_directed"/>
+            </when>
+            <when value="tl.louvain">
+                <expand macro="param_resolution"/>
+                <expand macro="param_weight"/>
+                <expand macro="param_random_state" seed="0"/>
+                <expand macro="param_key_added" key_added="louvain"/>
+                <expand macro="param_neighbors_key"/>
+                <expand macro="param_directed"/>
+            </when>
+            <when value="tl.mofa">
+                <param argument="groups_label" type="text" optional="true" label="a column name in adata.obs for grouping the samples">
+                    <expand macro="sanitize_query" />
+                </param>
+                <expand macro="param_use_raw" label="Use raw slot of AnnData as input values" checked="false"/>
+                <param argument="use_layer" type="text" optional="true" label="Use a specific layer of AnnData as input values"
+                    help="supersedes use_raw option">
+                    <expand macro="sanitize_query" />
+                </param>
+                <param argument="use_var" type="text" optional="true" label=".var column with a boolean value to select genes"
+                    help="e.g. “highly_variable”">
+                    <expand macro="sanitize_query" />
+                </param>
+                <param argument="use_obs" type="select" optional="true" label="strategy to deal with samples (cells) not being the same across modalities"
+                    help="Throws error if there are cells that are not same across modalities">
+                    <option value="union">union</option>
+                    <option value="intersection">intersection</option>
+                </param>
+                <param name="n_factors" type="integer" value="10" label="Number of factors to train the model with"/>
+                <param argument="scale_views" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Scale views to unit variance"/>
+                <param argument="scale_groups" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Scale groups to unit variance"/>
+                <param argument="center_groups" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Center groups to zero mean"/>
+                <param argument="ard_weights" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Use view-wise sparsity"/>
+                <param argument="ard_factors" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Use group-wise sparsity"/>
+                <param argument="spikeslab_weights" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Use feature-wise sparsity (e.g. gene-wise)"/>
+                <param argument="spikeslab_factors" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Use sample-wise sparsity (e.g. cell-wise)"/>
+                <param name="n_iterations" type="integer" value="1000" label="Upper limit on the number of iterations"/>
+                <param argument="convergence_mode" type="select" label="Convergence mode">
+                    <option value="fast" selected="true">fast</option>
+                    <option value="medium">medium</option>
+                    <option value="slow">slow</option>
+                </param>
+                <param argument="use_float32" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Use reduced precision"/>
+                <conditional name="svi">
+                    <param name="svi_mode" type="select" label="Use Stochastic Variational Inference (SVI)?">
+                        <option value="yes">Yes</option>
+                        <option value="no" selected="true">No</option>
+                    </param>
+                    <when value="yes">
+                        <param argument="svi_batch_size" type="float" value="0.5" min="0" max="1" label="Batch size as a fraction"/>
+                        <param argument="svi_learning_rate" type="float" value="1.0" min="0" max="1" label="Learning rate"/>
+                        <param argument="svi_forgetting_rate" type="float" value="0.5" min="0" max="1" label="Forgetting rate"/>
+                        <param argument="svi_start_stochastic" type="integer" value="1" label="First iteration to start SVI"/>
+                    </when>
+                    <when value="no"/>
+                </conditional>
+                <param argument="smooth_covariate" type="text" optional="true" label="Use a covariate (column in .obs) to learn smooth factors (MEFISTO)">
+                    <expand macro="sanitize_query" />
+                </param>
+                <param argument="smooth_warping" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Learn the alignment of covariates (e.g. time points) from different groups?"/>
+                <param argument="seed" type="integer" value="1" label="Random seed"/>
+            </when>
+            <when value="tl.umap">
+                <param argument="min_dist" type="float" min="0" value="0.5" label="The effective minimum distance between embedded points"
+                    help="Smaller values will result in a more clustered/clumped embedding where nearby points on the manifold are drawn closer together, while larger values will result on a more even dispersal of points."/>
+                <param argument="spread" type="float" value="1.0" label="The effective scale of embedded points"
+                    help="Determines how clustered/clumped the embedded points are"/>
+                <param argument="n_components" type="integer" value="2" label="The number of dimensions of the embedding"/>
+                <param argument="maxiter" type="integer" optional="true" label="The number of iterations (epochs) of the optimization"
+                    help="Called `n_epochs` in the original UMAP"/>
+                <param argument="alpha" type="float" value="1.0" label="The initial learning rate for the embedding optimization"/>
+                <param argument="gamma" type="float" value="1.0" label="Weighting applied to negative samples in low dimensional embedding optimization"
+                    help="Values higher than one will result in greater weight being given to negative samples"/>
+                <param argument="negative_sample_rate" type="integer" value="5" label="Negative sample rate"
+                    help="The number of negative edge/1-simplex samples to use per positive edge/1-simplex sample in optimizing the low dimensional embedding"/>
+                <param argument="init_pos" type="select" label="How to initialize the low dimensional embedding"
+                    help="Called `init` in the original UMAP">
+                    <option value="spectral">Use a spectral embedding of the graph</option>
+                    <option value="random">Assign initial embedding positions at random</option>
+                </param>
+                <expand macro="param_random_state" seed="42"/>
+                <expand macro="param_neighbors_key"/>
+            </when>
+        </conditional>
+        <expand macro="inputs_common_advanced" />
+    </inputs>
+    <outputs>
+        <expand macro="muon_outputs"/>
+    </outputs>
+    <tests>
+        <test expect_num_outputs="2">
+            <!-- test2: tl.leiden -->
+            <param name="mdata" location="https://zenodo.org/records/12570984/files/pbmc3k_chr21_processed.h5mu"/>
+            <param name="method" value="tl.leiden"/>
+            <conditional name="res">
+                <param name="type" value="separate"/>
+                <repeat name="modalities">
+                    <param name="mod_name" value="rna"/>
+                    <param name="resolution" value="2.0"/>
+                </repeat>
+                <repeat name="modalities">
+                    <param name="mod_name" value="atac"/>
+                    <param name="resolution" value="1.5"/>
+                </repeat>
+            </conditional>
+            <conditional name="weights">
+                <param name="type" value="separate"/>
+                <repeat name="modalities">
+                    <param name="mod_name" value="rna"/>
+                    <param name="mod_weights" value="3"/>
+                </repeat>
+                <repeat name="modalities">
+                    <param name="mod_name" value="atac"/>
+                    <param name="mod_weights" value="1"/>
+                </repeat>
+            </conditional>
+            <param name="random_state" value="0"/>
+            <param name="key_added" value="leiden"/>
+            <param name="neighbors_key" value="neighbors"/>
+            <param name="directed" value="True"/>
+            <section name="advanced_common">
+                <param name="show_log" value="true" />
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="mu.tl.leiden"/>
+                    <has_text_matching expression="'rna': 2.0"/>
+                    <has_text_matching expression="'atac': 1.5"/>
+                    <has_text_matching expression="'rna': 3"/>
+                    <has_text_matching expression="'atac': 1"/>
+                    <has_text_matching expression="random_state=0"/>
+                    <has_text_matching expression="key_added='leiden'"/>
+                    <has_text_matching expression="neighbors_key='neighbors'"/>
+                    <has_text_matching expression="directed=True"/>
+                </assert_contents>
+            </output>
+            <assert_stdout>
+                <has_text_matching expression="179 × 490"/>
+                <has_text_matching expression="179 x 178"/>
+                <has_text_matching expression="179 x 312"/>
+            </assert_stdout>
+            <output name="mudata_out" ftype="h5ad">
+                <assert_contents>
+                    <has_h5_keys keys="mod/rna"/>
+                    <has_h5_keys keys="mod/atac"/>
+                    <has_h5_keys keys="obs/leiden"/>
+                    <has_h5_keys keys="uns/leiden"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test3: tl.louvain -->
+            <param name="mdata" location="https://zenodo.org/records/12570984/files/pbmc3k_chr21_processed.h5mu"/>
+            <param name="method" value="tl.louvain"/>
+            <conditional name="res">
+                <param name="type" value="separate"/>
+                <repeat name="modalities">
+                    <param name="mod_name" value="rna"/>
+                    <param name="resolution" value="2.0"/>
+                </repeat>
+                <repeat name="modalities">
+                    <param name="mod_name" value="atac"/>
+                    <param name="resolution" value="1.5"/>
+                </repeat>
+            </conditional>
+            <conditional name="weights">
+                <param name="type" value="separate"/>
+                <repeat name="modalities">
+                    <param name="mod_name" value="rna"/>
+                    <param name="mod_weights" value="3"/>
+                </repeat>
+                <repeat name="modalities">
+                    <param name="mod_name" value="atac"/>
+                    <param name="mod_weights" value="1"/>
+                </repeat>
+            </conditional>
+            <param name="random_state" value="0"/>
+            <param name="key_added" value="louvain"/>
+            <param name="neighbors_key" value="neighbors"/>
+            <param name="directed" value="True"/>
+            <section name="advanced_common">
+                <param name="show_log" value="true" />
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="mu.tl.louvain"/>
+                    <has_text_matching expression="'rna': 2.0"/>
+                    <has_text_matching expression="'atac': 1.5"/>
+                    <has_text_matching expression="'rna': 3"/>
+                    <has_text_matching expression="'atac': 1"/>
+                    <has_text_matching expression="random_state=0"/>
+                    <has_text_matching expression="key_added='louvain'"/>
+                    <has_text_matching expression="neighbors_key='neighbors'"/>
+                    <has_text_matching expression="directed=True"/>
+                </assert_contents>
+            </output>
+            <assert_stdout>
+                <has_text_matching expression="179 × 490"/>
+                <has_text_matching expression="179 x 178"/>
+                <has_text_matching expression="179 x 312"/>
+            </assert_stdout>
+            <output name="mudata_out" ftype="h5ad">
+                <assert_contents>
+                    <has_h5_keys keys="mod/rna"/>
+                    <has_h5_keys keys="mod/atac"/>
+                    <has_h5_keys keys="obs/louvain"/>
+                    <has_h5_keys keys="uns/louvain"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test4: tl.mofa -->
+            <param name="mdata" location="https://zenodo.org/records/12570984/files/pbmc3k_chr21_processed.h5mu"/>
+            <param name="method" value="tl.mofa"/>
+            <param name="groups_label" value=""/>
+            <param name="use_raw" value="False"/>
+            <param name="use_var" value="highly_variable"/>
+            <param name="use_obs" value="union"/>
+            <param name="n_factors" value="10"/>
+            <param name="n_iterations" value="10"/>
+            <param name="convergence_mode" value="fast"/>
+            <conditional name="svi">
+                <param name="svi_mode" value="yes"/>
+                <param name="svi_batch_size" value="0.5"/>
+                <param name="svi_learning_rate" value="1.0"/>
+                <param name="svi_forgetting_rate" value="0.5"/>
+                <param name="svi_start_stochastic" value="1"/>
+            </conditional>
+            <param name="seed" value="1"/>
+            <section name="advanced_common">
+                <param name="show_log" value="true" />
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="mu.tl.mofa"/>
+                    <has_text_matching expression="use_raw=False"/>
+                    <has_text_matching expression="use_var='highly_variable'"/>
+                    <has_text_matching expression="use_obs='union'"/>
+                    <has_text_matching expression="n_factors=10"/>
+                    <has_text_matching expression="n_iterations=10"/>
+                    <has_text_matching expression="convergence_mode='fast'"/>
+                    <has_text_matching expression="svi_batch_size=0.5"/>
+                    <has_text_matching expression="svi_learning_rate=1.0"/>
+                    <has_text_matching expression="svi_forgetting_rate=0.5"/>
+                    <has_text_matching expression="svi_start_stochastic=1"/>
+                    <has_text_matching expression="seed=1"/>
+                </assert_contents>
+            </output>
+            <assert_stdout>
+                <has_text_matching expression="179 × 490"/>
+                <has_text_matching expression="179 x 178"/>
+                <has_text_matching expression="179 x 312"/>
+            </assert_stdout>
+            <output name="mudata_out" ftype="h5ad">
+                <assert_contents>
+                    <has_h5_keys keys="mod/rna"/>
+                    <has_h5_keys keys="mod/atac"/>
+                    <has_h5_keys keys="uns/mofa"/>
+                    <has_h5_keys keys="obsm/X_mofa"/>
+                    <has_h5_keys keys="varm/LFs"/>
+                </assert_contents>
+            </output>
+        </test>
+        <test expect_num_outputs="2">
+            <!-- test5: tl.umap -->
+            <param name="mdata" location="https://zenodo.org/records/12570984/files/pp.neighbors.h5mu"/>
+            <param name="method" value="tl.umap"/>
+            <param name="min_dist" value="0.5"/>
+            <param name="spread" value="1.0"/>
+            <param name="n_components" value="2"/>
+            <param name="maxiter" value="10"/>
+            <param name="alpha" value="1.0"/>
+            <param name="gamma" value="1.0"/>
+            <param name="negative_sample_rate" value="5"/>
+            <param name="init_pos" value="spectral"/>
+            <param name="random_state" value="42"/>
+            <section name="advanced_common">
+                <param name="show_log" value="true" />
+            </section>
+            <output name="hidden_output">
+                <assert_contents>
+                    <has_text_matching expression="mu.tl.umap"/>
+                    <has_text_matching expression="min_dist=0.5"/>
+                    <has_text_matching expression="spread=1.0"/>
+                    <has_text_matching expression="n_components=2"/>
+                    <has_text_matching expression="maxiter=10"/>
+                    <has_text_matching expression="alpha=1.0"/>
+                    <has_text_matching expression="gamma=1.0"/>
+                    <has_text_matching expression="negative_sample_rate=5"/>
+                    <has_text_matching expression="init_pos='spectral'"/>
+                    <has_text_matching expression="random_state=42"/>
+                </assert_contents>
+            </output>
+            <assert_stdout>
+                <has_text_matching expression="2711 × 1781"/>
+                <has_text_matching expression="2711 x 555"/>
+                <has_text_matching expression="2711 x 1226"/>
+            </assert_stdout>
+            <output name="mudata_out" ftype="h5ad">
+                <assert_contents>
+                    <has_h5_keys keys="mod/rna"/>
+                    <has_h5_keys keys="mod/atac"/>
+                    <has_h5_keys keys="uns/umap"/>
+                    <has_h5_keys keys="obsm/X_umap"/>
+                    <has_h5_keys keys="obsp/connectivities"/>
+                    <has_h5_keys keys="obsp/distances"/>
+                </assert_contents>
+            </output>
+        </test>
+    </tests>
+    <help><![CDATA[
+Cluster: Cluster cells using the Leiden algorithm (`muon.tl.leiden`)
+====================================================================
+
+        Cluster cells using the Leiden algorithm. This runs only the multiplex Leiden algorithm on the MuData object
+        using connectivities of individual modalities.
+
+        More details on the `muon documentation
+        <https://muon.readthedocs.io/en/latest/api/generated/muon.tl.leiden.html#muon.tl.leiden>`__
+
+Cluster: Cluster cells using the Louvain algorithm ('muon.tl.louvain')
+======================================================================
+
+        Cluster cells using the Louvain algorithm. This runs only the multiplex Louvain algorithm on the MuData object
+        using connectivities of individual modalities
+
+        More details on the `muon documentation
+        <https://muon.readthedocs.io/en/latest/api/generated/muon.tl.louvain.html#muon.tl.louvain>`__
+
+Analyze: Run Multi Omics Factor Analysis ('muon.tl.mofa')
+=========================================================
+
+        Run Multi-Omics Factor Analysis
+
+        More details on the `muon documentation
+        <https://muon.readthedocs.io/en/latest/api/generated/muon.tl.mofa.html#muon.tl.mofa>`__
+
+Analyze: Similarity Network Fusion ('muon.tl.snf')
+==================================================
+
+        Similarity network fusion (SNF). See Wang et al., 2014 (DOI: 10.1038/nmeth.2810).
+
+        More details on the `muon documentation
+        <https://muon.readthedocs.io/en/latest/api/generated/muon.tl.snf.html#muon.tl.snf>`__
+
+Embed: Embed the multimodal neighborhood graph using UMAP ('muon.tl.umap')
+==========================================================================
+
+        Embed the multimodal neighborhood graph using UMAP (McInnes et al, 2018). UMAP (Uniform Manifold Approximation
+        and Projection) is a manifold learning technique suitable for visualizing high-dimensional data.
+
+        More details on the `muon documentation
+        <https://muon.readthedocs.io/en/latest/api/generated/muon.tl.umap.html#muon.tl.umap>`__
+
+    ]]></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 Feb 05 10:53:32 2025 +0000
@@ -0,0 +1,264 @@
+<macros>
+    <token name="@TOOL_VERSION@">0.1.6</token>
+    <token name="@VERSION_SUFFIX@">0</token>
+    <token name="@PROFILE@">23.0</token>
+    <xml name="requirements">
+        <requirements>
+            <requirement type="package" version="@TOOL_VERSION@">muon</requirement>
+            <requirement type="package" version="0.10.2">leidenalg</requirement>
+            <requirement type="package" version="0.8.2">louvain</requirement>
+            <requirement type="package" version="0.7.2">mofapy2</requirement>
+        </requirements>
+    </xml>
+    <xml name="bio_tools">
+        <xrefs>
+            <xref type="bio.tools">muon</xref>
+        </xrefs>
+    </xml>
+    <xml name="creators">
+        <creator>
+            <organization name="European Galaxy Team" url="https://galaxyproject.org/eu/" />
+        </creator>
+    </xml>
+    <xml name="citations">
+        <citations>
+            <citation type="doi">10.1186/s13059-021-02577-8</citation>
+        </citations>
+    </xml>
+    <xml name="sanitize_query">
+        <sanitizer>
+            <valid initial="string.printable">
+                <remove value="&apos;" />
+            </valid>
+       </sanitizer>
+    </xml>
+    <xml name="sanitize_string">
+        <sanitizer>
+            <valid initial="string.letters,string.digits"><add value="_" /></valid>
+        </sanitizer>
+    </xml>
+    <xml name="version_command">
+        <version_command><![CDATA[python -c "import muon as mu;print('Muon version: %s' % mu.__version__)"]]></version_command>
+    </xml>
+
+    <token name="@CMD_imports@"><![CDATA[
+import mudata as md
+import muon as mu
+import scanpy as sc
+import os
+            ]]>
+    </token>
+    <xml name="inputs_mudata">
+        <param name="mdata" type="data" format="h5ad" label="MuData input file"/>
+    </xml>
+    <token name="@CMD_read_inputs@"><![CDATA[
+mdata = md.read('mudata.h5mu')
+        ]]>
+    </token>
+    <token name="@CMD_prettify_stdout@"><![CDATA[ | sed -r '1 s|MuData object with (.+) = (.*)\s*|\1: \2|g' | sed "s|'||g"  | sed -r 's|^\s*(.*):\s(.*)|[\1]\n-    \2|g' | sed 's|, |\n-    |g'
+    ]]></token>
+    <token name="@COPY_MUDATA@"><![CDATA[
+cp '$mdata' 'mudata.h5mu' &&
+    ]]>
+    </token>
+
+    <token name="@CMD@"><![CDATA[
+cat '$script_file' > '$hidden_output' &&
+python '$script_file' >> '$hidden_output' &&
+touch 'mudata_info.txt' &&
+cat 'mudata_info.txt' @CMD_prettify_stdout@
+    ]]>
+    </token>
+
+    <token name="@CMD_params_clustering@"><![CDATA[
+    #if $method.res.type == 'same'
+        #if str($method.res.resolution)
+    resolution=$method.res.resolution,
+        #end if
+    #else if $method.res.type == 'separate'
+    resolution={
+        #for $modality in $method.res.modalities
+        '$modality.mod_name': $modality.resolution,
+        #end for
+    },
+    #end if
+    #if $method.weights.type == 'same'
+        #if str($method.weights.mod_weights)
+    mod_weights=$method.weights.mod_weights,
+        #end if
+    #else if $method.weights.type == 'separate'
+    mod_weights={
+        #for $modality in $method.weights.modalities
+        '$modality.mod_name': $modality.mod_weights,
+        #end for
+    },
+    #end if
+    random_state=$method.random_state,
+    key_added='$method.key_added',
+    #if $method.neighbors_key
+    neighbors_key='$method.neighbors_key',
+    #end if
+    directed=$method.directed
+    ]]></token>
+
+    <token name="@CMD_neighbor_keys@"><![CDATA[
+    #if $method.n_keys.type == 'same'
+    neighbor_keys='$method.n_keys.neighbor_keys',
+    #else if $method.n_keys.type == 'separate'
+    neighbor_keys={
+        #for $modality in $method.n_keys.modalities
+        '$modality.mod_name': '$modality.neighbor_keys',
+        #end for
+    },
+    #end if
+    ]]></token>
+    <token name="@CMD_params_embedding@"><![CDATA[
+    #if $method.color
+    #set $color = ([x.strip() for x in str($method.color).split(',')])
+    color=$color,
+    #end if
+    use_raw=$method.use_raw,
+    #if $method.layer
+    layer='$method.layer',
+    #end if
+    ]]></token>
+
+    <xml name="inputs_common_advanced">
+        <section name="advanced_common" title="Advanced Options" 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="muon_outputs">
+        <data name="mudata_out" format="h5ad" from_work_dir="mudata.h5mu" label="${tool.name} (${method.method}) on ${on_string}: MuData"/>
+        <expand macro="outputs_common_advanced"/>
+    </xml>
+    <token name="@CMD_mudata_write_outputs@"><![CDATA[
+mdata.write('mudata.h5mu')
+with open('mudata_info.txt','w', encoding='utf-8') as ainfo:
+    print(mdata, file=ainfo)
+        ]]>
+    </token>
+
+    <xml name="param_neighbor_keys">
+        <conditional name="n_keys">
+            <param name="type" type="select" label="Same or separate neighborhood information for each modality?">
+                <option value="same">Same neighborhood key for all modalities</option>
+                <option value="separate">Separate neighborhood keys per modality</option>
+            </param>
+            <when value="same">
+                <param argument="neighbor_keys" type="text" value="neighbors" label="Keys in .uns where per-modality neighborhood information is stored"/>
+            </when>
+            <when value="separate">
+                <repeat name="modalities" title="Modalities" min="2" default="2">
+                    <param name="mod_name" type="text" label="Modality name" optional="true">
+                        <expand macro="sanitize_string" />
+                    </param>
+                    <param argument="neighbor_keys" type="text" value="neighbors" label="Keys in .uns where neighborhood information is stored"/>
+                </repeat>
+            </when>
+        </conditional>
+    </xml>
+    <xml name="param_resolution">
+        <conditional name="res">
+            <param name="type" type="select" label="Same or separate resolutions for each modality?">
+                <option value="same">Same resolution for all modalities</option>
+                <option value="separate">Separate resolutions per modality</option>
+            </param>
+            <when value="same">
+                <param argument="resolution" type="float" optional="true" label="Coarseness of the clustering" help="Higher values -> more clusters"/>
+            </when>
+            <when value="separate">
+                <repeat name="modalities" title="Modalities" min="2" default="2">
+                    <param name="mod_name" type="text" label="Modality name" optional="true">
+                        <expand macro="sanitize_string" />
+                    </param>
+                    <param name="resolution" type="float" label="Resolution for the above modality" help="Higher values -> more clusters"/>
+                </repeat>
+            </when>
+        </conditional>
+    </xml>
+    <xml name="param_weight">
+        <conditional name="weights">
+            <param name="type" type="select" label="Same or separate weights for each modality?">
+                <option value="same">Same weight for all modalities</option>
+                <option value="separate">Separate weight per modality</option>
+            </param>
+            <when value="same">
+                <param argument="mod_weights" type="float" optional="true" label="Weight each modality controlling its contribution" help="Higher values -> more important"/>
+            </when>
+            <when value="separate">
+                <repeat name="modalities" title="Modalities" min="2" default="2">
+                    <param name="mod_name" type="text" label="Modality name" optional="true">
+                        <expand macro="sanitize_string" />
+                    </param>
+                    <param name="mod_weights" type="float" label="Weight for the above modality" help="Higher values -> more important"/>
+                </repeat>
+            </when>
+        </conditional>
+    </xml>
+    <xml name="param_random_state" tokens="seed">
+        <param argument="random_state" type="integer" value="@SEED@" optional="true" label="Random seed for the optimization"/>
+    </xml>
+    <xml name="param_key_added" tokens="key_added">
+        <param argument="key_added" type="text" value="@KEY_ADDED@" label="mdata.obs key where cluster labels to be added">
+            <expand macro="sanitize_string" />
+        </param>
+    </xml>
+    <xml name="param_neighbors_key">
+        <param argument="neighbors_key" type="text" optional="true" label="Use neighbors connectivities as adjacency"
+        help="If not specified, look for .obsp['connectivities'] in each modality.
+        If specified, look for .obsp[.uns[neighbors_key]['connectivities_key']] in each modality for connectivities.">
+            <expand macro="sanitize_string" />
+        </param>
+    </xml>
+    <xml name="param_directed">
+        <param argument="directed" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Treat the graph as directed"/>
+    </xml>
+    <xml name="param_key_added_common">
+        <param argument="key_added" type="text" optional="true" label="Key to be added to store neighbors, distances and connectivities data"
+            help="If not specified, the multimodal neighbors data is stored in .uns['neighbors'], distances and connectivities are stored in .obsp['distances'] and .obsp['connectivities'], respectively.
+            If specified, the neighbors data is added to .uns[key_added], distances are stored in .obsp[key_added + '_distances'] and connectivities in .obsp[key_added + '_connectivities'].">
+            <expand macro="sanitize_string" />
+        </param>
+    </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="param_use_raw" tokens="label,checked">
+        <param argument="use_raw" type="boolean" truevalue="True" falsevalue="False" checked="@CHECKED@" label="@LABEL@" />
+    </xml>
+    <xml name="param_keys">
+        <conditional name="key_variables">
+            <param name="type" type="select" label="Keys to plot">
+                <option value="var_names">All variables in '.var_names'</option>
+                <option value="obs">All fields in '.obs'</option>
+                <option value="custom">Subset of variables in 'adata.var_names' or fields of '.obs'</option>
+            </param>
+            <when value="var_names"/>
+            <when value="obs"/>
+            <when value="custom">
+                <param argument="keys" type="text" value="" label="Keys to plot" help="One or a list of comma-separated index or key from '.var_names' or fields of '.obs'">
+                    <expand macro="sanitize_query" />
+                </param>
+            </when>
+        </conditional>
+    </xml>
+    <xml name="param_color">
+        <param argument="color" type="text" optional="true" label="Keys for variables or annotations of observations (.obs columns)" help="Can be from any modality.">
+            <expand macro="sanitize_query" />
+        </param>
+    </xml>
+    <xml name="params_embedding">
+        <expand macro="param_color"/>
+        <expand macro="param_use_raw" label="Use raw slot of AnnData as input values" checked="true"/>
+        <param argument="layer" type="text" optional="true" label="Name of the layer in the modality where a feature (from color) is derived from"
+            help="If a valid layer is provided, this takes precedence over use_raw=True">
+            <expand macro="sanitize_query" />
+        </param>
+    </xml>
+</macros>