diff macros.xml @ 0:8b9b8d358883 draft default tip

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/main/tools/liana commit 8dc656081d3147b402485bd25affe05a22e5194e
author iuc
date Tue, 10 Mar 2026 13:41:01 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/macros.xml	Tue Mar 10 13:41:01 2026 +0000
@@ -0,0 +1,460 @@
+<macros>
+    <token name="@TOOL_VERSION@">1.7.1</token>
+    <token name="@VERSION_SUFFIX@">0</token>
+    <token name="@PROFILE@">25.0</token>
+    <xml name="requirements">
+        <requirements>
+            <!-- Pin the version of anndata and pandas to avoid breaks in saving the h5ad macros -->
+            <requirement type="package" version="@TOOL_VERSION@">liana</requirement>
+            <requirement type="package" version="0.10.7">anndata</requirement>
+            <requirement type="package" version="1.9.6">scanpy</requirement>
+            <requirement type="package" version="2.1.4">pandas</requirement>
+        </requirements>
+    </xml>
+    <xml name="bio_tools">
+        <xrefs>
+            <xref type="bio.tools">liana</xref>
+        </xrefs>
+    </xml>
+    <xml name="creators">
+        <creator>
+            <person givenName="Khaled" familyName="Jum'ah" url="https://github.com/khaled196" />
+            <person givenName="Katarzyna" familyName="Kamieniecka" url="https://github.com/kkamieniecka" />
+            <person givenName="Pavankumar" familyName="Videm"  url="https://github.com/pavanvidem" />
+            <person givenName="Krzysztof" familyName="Poterlowicz" url="https://github.com/poterlowicz-lab" />
+            <organization name="poterlowicz-lab" url="https://github.com/poterlowicz-lab" />
+        </creator>
+    </xml>
+    <xml name="citations">
+        <citations>
+            <citation type="doi">10.1038/s41556-024-01469-w</citation>
+        </citations>
+    </xml>
+
+    <!-- param macros -->
+    <xml name="sanitize_query" token_validinitial="string.printable">
+        <sanitizer>
+            <valid initial="@VALIDINITIAL@">
+                <remove value="&apos;"/>
+            </valid>
+       </sanitizer>
+    </xml>
+    <xml name="inputs_anndata">
+        <param name="adata" type="data" format="h5ad" label="Annotated data matrix"/>
+    </xml>
+    <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="anndata_outputs">
+        <data name="anndata_out" format="h5ad" from_work_dir="anndata.h5ad" label="${tool.name} (${method.method}) on ${on_string}: Annotated data matrix">
+        </data>
+        <data name="hidden_output" format="txt" label="Log file" >
+            <filter>advanced_common['show_log']</filter>
+        </data>
+    </xml>
+
+    <!-- Liana-specific parameter macros -->
+    <xml name="param_groupby">
+        <param argument="groupby" type="text" value="" optional="false" label="Group By" help="Key to be used for grouping">
+            <expand macro="sanitize_query"/>
+            <validator type="empty_field" message="Please provide a valid groupby key (required)"/>
+        </param>
+    </xml>
+    <!-- Simple resource name parameter -->
+    <xml name="param_resource_name">
+        <param argument="resource_name" type="select" label="Ligand-receptor database" help="Built-in database of ligand-receptor pair annotations">
+            <option value="consensus" selected="true">consensus - Combined databases (recommended)</option>
+            <option value="cellchatdb">CellChat database</option>
+            <option value="cellphonedb">CellPhoneDB database</option>
+            <option value="connectomedb2020">Connectome database</option>
+            <option value="baccin2019">Baccin et al. 2019</option>
+            <option value="cellcall">CellCall</option>
+            <option value="cellinker">CellInker</option>
+            <option value="celltalkdb">CellTalkDB</option>
+            <option value="embrace">EMBRACE</option>
+            <option value="guide2pharma">Guide to Pharmacology</option>
+            <option value="hpmr">Human Protein-Protein Interactions</option>
+            <option value="icellnet">iCellNet</option>
+            <option value="italk">iTALK</option>
+            <option value="kirouac2010">Kirouac et al. 2010</option>
+            <option value="lrdb">LRDB</option>
+            <option value="mouseconsensus">mouseconsensus - Mouse data</option>
+            <option value="ramilowski2015">Ramilowski et al. 2015</option>
+        </param>
+    </xml>
+    <!-- Resource selection with hierarchy: interactions > resource > resource_name -->
+    <xml name="param_return_all_lrs">
+        <param argument="return_all_lrs" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Return all interactions" help="If enabled: include all L-R pairs from database even if they fail expression filter. If disabled: return only pairs meeting expr_prop threshold."/>
+    </xml>
+    <xml name="param_key_added">
+        <param argument="key_added" type="text" value="liana_res" label="Results key in adata.uns" help="Key in adata.uns where results will be stored. Default: 'liana_res'.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_use_raw">
+        <param argument="use_raw" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Use raw counts" help="If enabled: use adata.raw.X (raw/unprocessed counts). If disabled: use adata.X (processed/normalized expression). Default: enabled."/>
+    </xml>
+    <xml name="param_layer">
+        <param argument="layer" type="text" value="" optional="true" label="Layer in adata" help="Specific layer in adata.layers to use (e.g., 'log1p', 'scaled', 'raw'). If empty: uses adata.X.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_de_method">
+        <param argument="de_method" type="select" label="Differential expression test" help="Statistical method for rank_genes_groups (1-vs-Rest). t-test: parametric; wilcoxon: non-parametric, robust; logreg: logistic regression. Default: t-test.">
+            <option value="t-test" selected="true">t-test (default)</option>
+            <option value="t-test_overestim_var">t-test with variance correction</option>
+            <option value="wilcoxon">Wilcoxon rank-sum (non-parametric)</option>
+            <option value="logreg">Logistic regression</option>
+        </param>
+    </xml>
+    <xml name="param_n_perms">
+        <param argument="n_perms" type="integer" value="1000" min="0" optional="true" label="Permutation test iterations" help="Number of random permutations for statistical significance (CellPhoneDB, etc.). Default: 1000. Set to 0 to skip permutation testing."/>
+    </xml>
+    <xml name="param_seed">
+        <param argument="seed" type="integer" value="1337" label="Random seed for reproducibility" help=""/>
+    </xml>
+    <xml name="param_base">
+        <param argument="base" type="float" value="2.718281828459045" optional="true" label="Log transformation base" help="Base for reversing log-transformation of expression values. Default: e (2.718). Use 2 for log2 or 10 for log10 data."/>
+    </xml>
+    <xml name="param_supp_columns">
+        <param argument="supp_columns" type="text" value="" optional="true" label="Additional columns to be added" help="From any of the methods implemented in liana , or any of the columns returned by scanpy, each starting with ligand_* or receptor_*. For example, ['ligand_pvals', 'receptor_pvals']"/>
+    </xml>
+
+    <!-- Grouped parameter macros for cleaner code -->
+    <xml name="params_common_basic">
+        <expand macro="param_groupby"/>
+        <expand macro="param_resource_selection"/>
+        <param argument="expr_prop" type="float" value="0.1" min="0" max="1" label="Minimum expression proportion" help="Minimum expression proportion for the ligands and receptors (+ their subunits) in the corresponding cell identities. Set to 0 to return unfiltered results"/>
+        <param argument="min_cells" type="integer" value="5" min="1" label="Minimum cells" help="Minimum number of cells per cell identity to be considered for downstream analysis. Default: 5."/>
+    </xml>
+    <xml name="params_common_output">
+        <expand macro="param_return_all_lrs"/>
+        <expand macro="param_key_added"/>
+        <expand macro="param_layer"/>
+    </xml>
+    <!-- Combined common params for methods without permutations -->
+    <xml name="params_lr_method_basic">
+        <expand macro="params_common_basic"/>
+        <expand macro="params_common_output"/>
+        <expand macro="param_supp_columns"/>
+        <expand macro="param_de_method"/>
+        <expand macro="param_seed"/>
+    </xml>
+    <!-- Combined common params for methods with permutations -->
+    <xml name="params_lr_method_with_perms">
+        <expand macro="params_common_basic"/>
+        <expand macro="params_common_output"/>
+        <expand macro="param_supp_columns"/>
+        <expand macro="param_de_method"/>
+        <expand macro="param_n_perms"/>
+        <expand macro="param_seed"/>
+    </xml>
+
+    <!-- Spatial-specific parameter macros -->
+    <xml name="param_spatial_key">
+        <param argument="spatial_key" type="text" value="spatial" label="Spatial coordinates key" help="The key in adata.obsm where the spatial coordinates are stored">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_nz_threshold">
+        <param argument="nz_threshold" type="float" value="0.1" min="0" max="1" label="Non-zero threshold for views" help=""/>
+    </xml>
+    <xml name="param_set_diag">
+        <param argument="set_diag" type="boolean" truevalue="True" falsevalue="False" checked="true" label=" Set the diagonal of the connectivity matrix to 1" help=""/>
+    </xml>
+    <xml name="param_kernel">
+        <param argument="kernel" type="select" label="Radial basis function kernel" value="@DEFAULT_KERNEL@" help="Used for the generation of the connectivity matrix for the paraview">
+            <option value="misty_rbf">misty_rbf - MISTy RBF (default)</option>
+            <option value="gaussian">gaussian - Gaussian kernel</option>
+            <option value="exponential">exponential - Exponential decay</option>
+            <option value="linear">linear - Inverse distance</option>
+        </param>
+    </xml>
+    <xml name="param_bandwidth">
+        <param argument="bandwidth" type="float" value="100" min="0" label="Kernel bandwidth" help=""/>
+    </xml>
+    <xml name="param_zoi">
+        <param argument="zoi" type="float" value="0" min="0" label="Kernel Zone of indifference" help=""/>
+    </xml>
+    <xml name="param_cutoff">
+        <param argument="cutoff" type="float" value="0.1" min="0" max="1" label="Connectivity matrix cutoff" help=""/>
+    </xml>
+    <xml name="param_model">
+        <param argument="model" type="select" label="MISTy prediction model" help="Statistical model for feature importance ranking">
+            <option value="RandomForestModel" selected="true">RandomForestModel (default)</option>
+            <option value="LinearModel">LinearModel</option>
+            <option value="RobustLinearModel">RobustLinearModel</option>
+        </param>
+    </xml>
+    <xml name="param_bypass_intra">
+        <param argument="bypass_intra" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Exclude intra-view from training" help=""/>
+    </xml>
+    <xml name="param_resource_selection">
+        <conditional name="resource_selection">
+            <param name="resource_type" type="select" label="Interaction source" help="Priority: interactions list > custom file > built-in database. Choose based on whether you have custom L-R pairs or want to use pre-defined resources.">
+                <option value="resource_name" selected="true">Use built-in database</option>
+                <option value="resource">Upload custom resource file</option>
+                <option value="interactions">Enter specific interaction pairs</option>
+            </param>
+            <when value="resource_name">
+                <conditional name="resource_api_cached">
+                    <param name="resource_source_selector" type="select" label="Resource source" help="Use cached resources from this Galaxy server (installed via Data Manager) for fast offline access, or download from LIANA API.">
+                        <option value="builtin">Download from LIANA API</option>
+                        <option value="cached" selected="true">Cached on server (from Data Manager)</option>
+                    </param>
+                    <when value="cached">
+                        <param name="resource_cached" type="select" label="Ligand-receptor database (cached)" help="Select from resources installed by the LIANA Resources Data Manager.">
+                            <options from_data_table="liana_resources">
+                                <validator type="no_options" message="No cached LIANA resources available. Install them via Admin → Data Managers → Download LIANA Resources."/>
+                            </options>
+                        </param>
+                    </when>
+                    <when value="builtin">
+                        <expand macro="param_resource_name"/>
+                    </when>
+                </conditional>
+            </when>
+            <when value="resource">
+                <param argument="resource" type="data" format="tabular" label="Custom resource file (TSV)" help="Tab-separated file with at least two columns named 'ligand' and 'receptor'. Each row represents one ligand-receptor interaction. This resource will override the built-in database selection."/>
+            </when>
+            <when value="interactions">
+                <param argument="interactions" type="text" area="true" label="Ligand-receptor pairs (one per line)" help="Enter specific interactions to analyze in format: ligand,receptor (one pair per line, e.g., 'TGFB1,TGFBR1' or 'IL1A,IL1R1'). Use the same gene symbols as in your expression matrix. This list will override any built-in or custom resource file.">
+                    <expand macro="sanitize_query"/>
+                </param>
+            </when>
+        </conditional>
+    </xml>
+    <!-- Multi-sample parameter macros -->
+    <xml name="param_sample_key">
+        <param argument="sample_key" type="text" value="@VALUE@" label="Sample key" help="Key in adata.obs for grouping by sample or condition context. Default: 'sample'.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_score_key">
+        <param argument="score_key" type="text" value="" optional="true" label="Score key" help="Column name of the score in liana_res. If empty, inferred from method.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_source_key">
+        <param argument="source_key" type="text" value="source" label="Source key" help="Column name of sender/source cell types in LIANA results. Default: 'source'.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_target_key">
+        <param argument="target_key" type="text" value="target" label="Target key" help="Column name of receiver/target cell types in LIANA results. Default: 'target'.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_ligand_key">
+        <param argument="ligand_key" type="text" value="ligand_complex" label="Ligand key" help="Column name of ligand in LIANA results. Default: 'ligand_complex'.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_receptor_key">
+        <param argument="receptor_key" type="text" value="receptor_complex" label="Receptor key" help="Column name of receptor in LIANA results. Default: 'receptor_complex'.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="params_multi_keys">
+        <expand macro="param_score_key"/>
+        <expand macro="param_uns_key"/>
+        <expand macro="param_source_key"/>
+        <expand macro="param_target_key"/>
+        <expand macro="param_ligand_key"/>
+        <expand macro="param_receptor_key"/>
+    </xml>
+
+    <!-- Plotting-specific parameter macros -->
+    <xml name="param_uns_key">
+        <param argument="uns_key" type="text" value="liana_res" label="Results key in adata.uns" help="Must match key_added from inference method">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_plot_colour">
+        <param argument="colour" type="text" value="" optional="true" label="Color by column" help="Column name in liana_res DataFrame to map to dot color. E.g., 'magnitude_rank', 'specificity_rank', 'lr_means', or pvalue columns.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_plot_size">
+        <param argument="size" type="text" value="" optional="true" label="Size by column" help="Column name in liana_res DataFrame to map to dot size. Larger values = larger dots.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_misty_key">
+        <param argument="key" type="text" value="" optional="true" label="Function to use to sort the dataframe" help="">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_source_labels">
+        <param argument="source_labels" type="text" value="" optional="true" label="Source (sender) cell types" help="Comma-separated list of source cell type labels. Empty = show all. Useful for focusing on specific signaling populations.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_target_labels">
+        <param argument="target_labels" type="text" value="" optional="true" label="Target (receiver) cell types" help="Comma-separated list of target cell type labels. Empty = show all. Useful for focusing on specific receiving populations.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_ligand_complex">
+        <param argument="ligand_complex" type="text" value="" optional="true" label="Ligand genes" help="Comma-separated ligand gene symbols to include. Empty = all genes. Example: IL6,TNF,TGFB1.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_receptor_complex">
+        <param argument="receptor_complex" type="text" value="" optional="true" label="Receptor genes" help="Comma-separated receptor gene symbols to include. Empty = all genes. Example: EGFR,FGFR1,PDGFRA.">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_top_n">
+        <param argument="top_n" type="integer" value="" optional="true" min="1" label="Top N interactions" help="Number of top-ranked interactions to display."/>
+    </xml>
+    <xml name="param_orderby">
+        <param argument="orderby" type="text" value="" optional="true" label="Sort column" help="Column in LIANA results to sort by (used with top_n).">
+            <expand macro="sanitize_query"/>
+        </param>
+    </xml>
+    <xml name="param_orderby_ascending">
+        <param argument="orderby_ascending" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Sort ascending" help="Sort by increasing (smallest to largest) values."/>
+    </xml>
+    <xml name="param_orderby_absolute">
+        <param argument="orderby_absolute" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Sort by absolute value" help="Sort by absolute value magnitude (ignoring sign)."/>
+    </xml>
+    <xml name="param_inverse_colour">
+        <param argument="inverse_colour" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Apply -log10 transformation to color" help="If enabled: apply -log10 to color column (e.g., converts p-values to -log10(p)). Useful for p-value visualization."/>
+    </xml>
+    <xml name="param_inverse_size">
+        <param argument="inverse_size" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Apply -log10 transformation to size" help="If enabled: apply -log10 to size column (useful for p-values where smaller p = larger dots)."/>
+    </xml>
+    <xml name="param_cmap">
+        <param argument="cmap" type="select" label="Color scheme (matplotlib colormap)" help="Colormap for color column visualization. viridis/plasma: perceptually uniform; RdBu: diverging; sequential: Reds, Blues, etc. Default: viridis.">
+            <option value="viridis" selected="true">viridis - Perceptually uniform</option>
+            <option value="plasma">plasma</option>
+            <option value="inferno">inferno</option>
+            <option value="magma">magma</option>
+            <option value="cividis">cividis</option>
+            <option value="Greys">Greys</option>
+            <option value="Blues">Blues</option>
+            <option value="Greens">Greens</option>
+            <option value="Oranges">Oranges</option>
+            <option value="Reds">Reds</option>
+            <option value="YlOrBr">YlOrBr</option>
+            <option value="YlOrRd">YlOrRd</option>
+            <option value="OrRd">OrRd</option>
+            <option value="PuRd">PuRd</option>
+            <option value="RdPu">RdPu</option>
+            <option value="BuPu">BuPu</option>
+            <option value="GnBu">GnBu</option>
+            <option value="PuBu">PuBu</option>
+            <option value="YlGnBu">YlGnBu</option>
+            <option value="PuBuGn">PuBuGn</option>
+            <option value="BuGn">BuGn</option>
+            <option value="YlGn">YlGn</option>
+            <option value="PiYG">PiYG</option>
+            <option value="PRGn">PRGn</option>
+            <option value="BrBG">BrBG</option>
+            <option value="PuOr">PuOr</option>
+            <option value="RdGy">RdGy</option>
+            <option value="RdBu">RdBu</option>
+            <option value="RdBu_r">RdBu_r</option>
+            <option value="RdYlBu">RdYlBu</option>
+            <option value="RdYlGn">RdYlGn</option>
+            <option value="Spectral">Spectral</option>
+            <option value="coolwarm">coolwarm</option>
+            <option value="bwr">bwr</option>
+            <option value="seismic">seismic</option>
+        </param>
+    </xml>
+    <xml name="param_size_range">
+        <param name="size_range_min" type="integer" value="2" min="1" label="Minimum dot size (pixels)" help="Smallest dot size for minimum values. Default: 2 pixels."/>
+        <param name="size_range_max" type="integer" value="9" min="1" label="Maximum dot size (pixels)" help="Largest dot size for maximum values. Default: 9 pixels. Adjust range to make size differences more/less prominent."/>
+    </xml>
+    <xml name="param_figure_size" token_width="8" token_height="6">
+        <param name="figure_size_width" type="float" value="@WIDTH@" min="1" label="Figure width (inches)" help="Output plot width. Default: 8 inches."/>
+        <param name="figure_size_height" type="float" value="@HEIGHT@" min="1" label="Figure height (inches)" help="Output plot height. Default: 6 inches."/>
+    </xml>
+
+    <!-- Plotting command tokens -->
+    <token name="@CMD_PLOT_SOURCE_TARGET_LABELS@"><![CDATA[
+    #if str($method.source_labels) != '':
+    source_labels=[x.strip() for x in '$method.source_labels'.split(',')],
+    #end if
+    #if str($method.target_labels) != '':
+    target_labels=[x.strip() for x in '$method.target_labels'.split(',')],
+    #end if
+    ]]>
+    </token>
+    <token name="@CMD_PLOT_LIGAND_RECEPTOR_COMPLEX@"><![CDATA[
+    #if str($method.ligand_complex) != '':
+    ligand_complex=[x.strip() for x in '$method.ligand_complex'.split(',')],
+    #end if
+    #if str($method.receptor_complex) != '':
+    receptor_complex=[x.strip() for x in '$method.receptor_complex'.split(',')],
+    #end if
+    ]]>
+    </token>
+    <token name="@CMD_PLOT_TOP_N_ORDERBY@"><![CDATA[
+    #if str($method.top_n) != '':
+    top_n=$method.top_n,
+    #end if
+    #if str($method.orderby) != '':
+    orderby='$method.orderby',
+    #end if
+    orderby_ascending=$method.orderby_ascending,
+    orderby_absolute=$method.orderby_absolute,
+    ]]>
+    </token>
+
+    <!-- command macros -->
+    <xml name="version_command">
+        <version_command><![CDATA[python -c "import liana as li;print('liana version: %s' % li.__version__)"]]></version_command>
+    </xml>
+    <token name="@CMD_PRETTIFY_STDOUT@"><![CDATA[
+| sed -r '1 s|AnnData 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="@CMD_READ_INPUTS@"><![CDATA[
+adata = sc.read_h5ad('anndata.h5ad')
+    ]]>
+    </token>
+    <!-- Resource param block for L-R methods: interactions | resource (file) | resource (cached from DM) | resource_name (API) -->
+    <token name="@CMD_RESOURCE_FOR_METHODS@"><![CDATA[
+#if str($method.resource_selection.resource_type) == 'interactions':
+    interactions=[tuple(x.strip().split(',')) for x in '''$method.resource_selection.interactions'''.strip().split('\n') if x.strip()],
+#else if str($method.resource_selection.resource_type) == 'resource':
+    resource=pd.read_csv('$method.resource_selection.resource', sep='\t'),
+#else:
+#if str($method.resource_selection.resource_api_cached.resource_source_selector) == 'cached':
+    resource=pd.read_csv(os.path.join('$method.resource_selection.resource_api_cached.resource_cached.fields.path', '$method.resource_selection.resource_api_cached.resource_cached.fields.value' + '.tsv'), sep='\t'),
+#else:
+    resource_name='$method.resource_selection.resource_api_cached.resource_name',
+#end if
+#end if
+    ]]>
+    </token>
+    <!-- ln -s doesn't work here because the output is overwritten to the same file -->
+    <token name="@CMD@"><![CDATA[
+cp '$adata' 'anndata.h5ad' &&
+cat '$script_file' > '$hidden_output' &&
+python '$script_file' >> '$hidden_output' &&
+ls . >> '$hidden_output' &&
+touch 'anndata_info.txt' &&
+cat 'anndata_info.txt' @CMD_PRETTIFY_STDOUT@
+    ]]>
+    </token>
+    <token name="@CMD_IMPORTS@"><![CDATA[
+import liana as li
+import scanpy as sc
+import pandas as pd
+import os
+
+    ]]>
+    </token>
+    <token name="@CMD_ANNDATA_WRITE_OUTPUTS@"><![CDATA[
+adata.write_h5ad('anndata.h5ad', compression='gzip')
+with open('anndata_info.txt','w', encoding='utf-8') as ainfo:
+    print(adata, file=ainfo)
+    ]]>
+    </token>
+</macros>