Build branch openpipeline_spatial/niche-compass with version niche-compass to openpipeline_spatial on branch niche-compass (87e6260)
Build pipeline: openpipelines-bio.openpipeline-spatial.niche-compass-8zcq9
Source commit: 87e62605aa
Source message: add cmake to test container
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,10 +1,24 @@
|
||||
# openpipeline_spatial x.x.x
|
||||
# openpipeline_spatial 0.4.0
|
||||
|
||||
## NEW FUNCTIONALITY
|
||||
|
||||
* `feature_annotation/spatial_autocorr`: Added a spatial autocorrelation component (PR #45).
|
||||
|
||||
* `feature_annotation/xenium_spatial_statistics`: Added a component to calculate spatial statistics on Xenium-ingested data (PR #46).
|
||||
|
||||
* `neighbors/join_graphs`: Combine spatial and expression neighborhood graphs into a single graph (PR #47).
|
||||
|
||||
# openpipeline_spatial 0.3.0
|
||||
|
||||
## NEW FUNCTIONALITY
|
||||
|
||||
* `convert/from_h5mu_to_spatialdata`: Added a converter component to convert from H5MU to SpatialData (PR #40)
|
||||
|
||||
## MINOR CHANGES
|
||||
|
||||
* Bump squidpy to 1.8.1 and spatialdata to 0.7.2 (PR #41).
|
||||
|
||||
* Update openpipeline dependencies to v4.0.2 (PR #42).
|
||||
* Update openpipeline dependencies to v4.0.3 (PR #42, PR #44).
|
||||
|
||||
# openpipeline_spatial 0.2.0
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ repositories:
|
||||
- name: openpipeline
|
||||
repo: openpipeline
|
||||
type: vsh
|
||||
tag: v4.0.2
|
||||
tag: v4.0.3
|
||||
info:
|
||||
test_resources:
|
||||
- type: s3
|
||||
|
||||
5
resources_test_scripts/visium_tiny.sh
Normal file → Executable file
5
resources_test_scripts/visium_tiny.sh
Normal file → Executable file
@@ -7,6 +7,7 @@ REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
|
||||
# Define absolute directory path
|
||||
DIR="$REPO_ROOT/resources_test/visium"
|
||||
ID="Visium_FFPE_Human_Ovarian_Cancer_tiny"
|
||||
|
||||
# from https://www.10xgenomics.com/resources/datasets/human-ovarian-cancer-1-standard
|
||||
mkdir -p "$DIR"
|
||||
@@ -46,6 +47,10 @@ echo "> Running spaceranger complete"
|
||||
rm -rf "$DIR/Visium_FFPE_Human_Ovarian_Cancer_fastqs"
|
||||
rm -f "$DIR/Visium_FFPE_Human_Ovarian_Cancer_image.jpg"
|
||||
|
||||
viash run "$REPO_ROOT/src/convert/from_spaceranger_to_h5mu/config.vsh.yaml" -- \
|
||||
--input "$DIR/Visium_FFPE_Human_Ovarian_Cancer_tiny_spaceranger" \
|
||||
--output "$DIR/$ID.h5mu"
|
||||
|
||||
aws s3 sync \
|
||||
--profile di \
|
||||
--exclude "*.yaml" \
|
||||
|
||||
@@ -19,14 +19,16 @@ function clean_up {
|
||||
trap clean_up EXIT
|
||||
|
||||
if [ ! -d "$OUT" ]; then
|
||||
tiny_dataset="https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_Prime_Mouse_Ileum_tiny_outs.zip"
|
||||
wget "$tiny_dataset" -O "$TMPDIR/xenium_tiny.zip"
|
||||
tiny_dataset="https://raw.githubusercontent.com/nf-core/test-datasets/spatialxe/Xenium_Prime_Mouse_Ileum_tiny_outs.tar.gz"
|
||||
wget "$tiny_dataset" -O "$TMPDIR/xenium_tiny.tar.gz"
|
||||
|
||||
unzip -q "$TMPDIR/xenium_tiny.zip" -d "$TMPDIR/xenium_tiny"
|
||||
mkdir -p "$TMPDIR/xenium_tiny"
|
||||
tar -xzf "$TMPDIR/xenium_tiny.tar.gz" -C "$TMPDIR/xenium_tiny"
|
||||
mkdir -p "$OUT"
|
||||
mv "$TMPDIR/xenium_tiny/Xenium_Prime_Mouse_Ileum_tiny_outs/"* "$OUT/"
|
||||
fi
|
||||
|
||||
rm -rf "$DIR/$ID.zarr"
|
||||
viash run "$REPO_ROOT/src/convert/from_xenium_to_spatialdata/config.vsh.yaml" -- \
|
||||
--input "$OUT" \
|
||||
--output "$DIR/$ID.zarr"
|
||||
@@ -35,11 +37,73 @@ viash run "$REPO_ROOT/src/convert/from_spatialdata_to_h5mu/config.vsh.yaml" -- \
|
||||
--input "$DIR/$ID.zarr" \
|
||||
--output "$DIR/$ID.h5mu"
|
||||
|
||||
|
||||
viash run src/neighbors/spatial_neighborhood_graph/config.vsh.yaml -- \
|
||||
--input "$DIR/$ID.h5mu" \
|
||||
--output "$DIR/$ID.h5mu"
|
||||
|
||||
cat > /tmp/qc.yaml <<EOF
|
||||
param_list:
|
||||
- id: xenium_tiny
|
||||
input: "$DIR/$ID.h5mu"
|
||||
var_name_mitochondrial_genes: mitochondrial
|
||||
var_name_ribosomal_genes: ribosomal
|
||||
output: '\$id.qc.h5mu'
|
||||
output_compression: gzip
|
||||
publish_dir: "$DIR"
|
||||
EOF
|
||||
|
||||
nextflow run openpipelines-bio/openpipeline \
|
||||
-latest \
|
||||
-r 2.1.0 \
|
||||
-main-script target/nextflow/workflows/qc/qc/main.nf \
|
||||
-profile docker \
|
||||
-params-file /tmp/qc.yaml \
|
||||
-resume \
|
||||
-config src/workflows/utils/labels_ci.config
|
||||
|
||||
viash run "$REPO_ROOT/src/neighbors/spatial_neighborhood_graph/config.vsh.yaml" -- \
|
||||
--input "$DIR/$ID.qc.h5mu" \
|
||||
--output "$DIR/${ID}.qc.neighbors.h5mu"
|
||||
|
||||
cat > /tmp/pca.yaml <<EOF
|
||||
param_list:
|
||||
- id: xenium_tiny
|
||||
input: "$DIR/${ID}.qc.neighbors.h5mu"
|
||||
output: '\$id.qc.neighbors.pca.h5mu'
|
||||
output_compression: gzip
|
||||
publish_dir: "$TMPDIR"
|
||||
EOF
|
||||
|
||||
nextflow run openpipelines-bio/openpipeline \
|
||||
-latest \
|
||||
-r v4.0.3 \
|
||||
-main-script target/nextflow/dimred/pca/main.nf \
|
||||
-profile docker \
|
||||
-params-file /tmp/pca.yaml \
|
||||
-config src/workflows/utils/labels_ci.config \
|
||||
-resume
|
||||
|
||||
cat > /tmp/find_neighbors.yaml <<EOF
|
||||
param_list:
|
||||
- id: xenium_tiny
|
||||
input: "$TMPDIR/xenium_tiny.qc.neighbors.pca.h5mu"
|
||||
output: '\$id.qc.all_neighbors.pca.h5mu'
|
||||
output_compression: gzip
|
||||
publish_dir: "$TMPDIR"
|
||||
EOF
|
||||
|
||||
nextflow run openpipelines-bio/openpipeline \
|
||||
-latest \
|
||||
-r v4.0.3 \
|
||||
-main-script target/nextflow/neighbors/find_neighbors/main.nf \
|
||||
-profile docker \
|
||||
-params-file /tmp/find_neighbors.yaml \
|
||||
-config src/workflows/utils/labels_ci.config \
|
||||
-resume
|
||||
|
||||
# Move the final output to the destination directory
|
||||
mv "$TMPDIR/xenium_tiny.qc.all_neighbors.pca.h5mu" "$DIR/xenium_tiny.qc.all_neighbors.pca.h5mu"
|
||||
|
||||
# Sync to S3
|
||||
aws s3 sync \
|
||||
--profile di \
|
||||
|
||||
12
src/authors/luke_zappia.yaml
Normal file
12
src/authors/luke_zappia.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Luke Zappia
|
||||
info:
|
||||
role: Contributor
|
||||
links:
|
||||
email: luke@data-intuitive.com
|
||||
github: lazappi
|
||||
orcid: 0000-0001-7744-8565
|
||||
linkedin: lazappi
|
||||
organizations:
|
||||
- name: Data Intuitive
|
||||
href: https://www.data-intuitive.com
|
||||
role: Data Science Engineer
|
||||
@@ -1,3 +1,6 @@
|
||||
packages:
|
||||
- spatialdata~=0.7.2
|
||||
- ome-zarr~=0.12.2
|
||||
- pyarrow~=18.0.0
|
||||
script: |
|
||||
exec("try:\n import zarr; from importlib.metadata import version\nexcept ModuleNotFoundError:\n exit(0)\nelse: assert int(version(\"zarr\").partition(\".\")[0]) > 2")
|
||||
|
||||
64
src/convert/from_h5mu_to_spatialdata/config.vsh.yaml
Normal file
64
src/convert/from_h5mu_to_spatialdata/config.vsh.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
name: "from_h5mu_to_spatialdata"
|
||||
namespace: "convert"
|
||||
scope: "public"
|
||||
description: |
|
||||
Reads in an H5MU file and saves it as a SpatialData Zarr store. The selected
|
||||
modality in the MuData is stored as the main table in the SpatialData object.
|
||||
If a matching existing SpatialData is provided, it will be used to fill the
|
||||
remaining SpatialData slots.
|
||||
|
||||
authors:
|
||||
- __merge__: /src/authors/dorien_roosen.yaml
|
||||
roles: [ maintainer ]
|
||||
- __merge__: /src/authors/luke_zappia.yaml
|
||||
roles: [ author ]
|
||||
arguments:
|
||||
- name: "--input"
|
||||
alternatives: ["-i"]
|
||||
type: file
|
||||
description: Input H5MU file.
|
||||
example: input.h5mu
|
||||
direction: input
|
||||
required: true
|
||||
- name: "--input_spatialdata"
|
||||
type: file
|
||||
description: An optional existing SpatialData Zarr store to fill remaining slots from.
|
||||
example: existing.zarr
|
||||
direction: input
|
||||
required: false
|
||||
- name: "--modality"
|
||||
type: string
|
||||
default: rna
|
||||
description: The modality in the MuData to be used as the main table in the SpatialData object.
|
||||
- name: "--output"
|
||||
alternatives: ["-o"]
|
||||
type: file
|
||||
description: The path to the output SpatialData Zarr store.
|
||||
example: "output.zarr"
|
||||
direction: output
|
||||
required: true
|
||||
|
||||
resources:
|
||||
- type: python_script
|
||||
path: script.py
|
||||
- path: /src/utils/setup_logger.py
|
||||
test_resources:
|
||||
- type: python_script
|
||||
path: test.py
|
||||
- path: /resources_test/xenium/xenium_tiny.h5mu
|
||||
- path: /resources_test/xenium/xenium_tiny.zarr
|
||||
engines:
|
||||
- type: docker
|
||||
image: python:3.12-slim
|
||||
setup:
|
||||
- type: apt
|
||||
packages:
|
||||
- procps
|
||||
- type: python
|
||||
__merge__: [/src/base/requirements/anndata_mudata.yaml, /src/base/requirements/spatialdata.yaml]
|
||||
__merge__: [ /src/base/requirements/python_test_setup.yaml, .]
|
||||
runners:
|
||||
- type: executable
|
||||
- type: nextflow
|
||||
directives:
|
||||
label: [lowmem, singlecpu]
|
||||
60
src/convert/from_h5mu_to_spatialdata/script.py
Normal file
60
src/convert/from_h5mu_to_spatialdata/script.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import mudata as mu
|
||||
import spatialdata as sd
|
||||
|
||||
## VIASH START
|
||||
par = {
|
||||
"input": "./resources_test/xenium/xenium_tiny.h5mu",
|
||||
"input_spatialdata": "./resources_test/xenium/xenium_tiny.zarr",
|
||||
"output": "./resources_test/xenium/xenium_tiny_from_h5mu.zarr",
|
||||
"modality": "rna",
|
||||
}
|
||||
meta = {"resources_dir": "src/utils"}
|
||||
## VIASH END
|
||||
|
||||
sys.path.append(meta["resources_dir"])
|
||||
from setup_logger import setup_logger
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
logger.info("Starting conversion from H5MU to SpatialData...")
|
||||
|
||||
logger.info(f"Reading input H5MU file from {par['input']}...")
|
||||
mdata = mu.read_h5mu(par["input"])
|
||||
|
||||
logger.info("Extracting modality from MuData object...")
|
||||
mod = mdata.mod[par["modality"]]
|
||||
|
||||
if par.get("input_spatialdata", None) is not None:
|
||||
logger.info(f"Reading existing SpatialData from {par['input_spatialdata']}...")
|
||||
|
||||
# Disable logger messages from spatialdata when reading
|
||||
logger.setLevel(logging.WARNING)
|
||||
sdata_existing = sd.read_zarr(par["input_spatialdata"])
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
logger.info("Checking modality matches existing SpatialData table...")
|
||||
if not mod.n_obs == sdata_existing["table"].n_obs:
|
||||
raise ValueError(
|
||||
"The number of observations in the selected modality does not match the existing SpatialData table."
|
||||
)
|
||||
if not mod.obs_names.equals(sdata_existing["table"].obs_names):
|
||||
raise ValueError(
|
||||
"The observation names in the selected modality do not match the existing SpatialData table."
|
||||
)
|
||||
|
||||
logger.info("Creating SpatialData object...")
|
||||
if par.get("input_spatialdata", None) is not None:
|
||||
logger.info("Using existing SpatialData...")
|
||||
sdata = sdata_existing
|
||||
sdata["table"] = mod
|
||||
else:
|
||||
logger.info("Creating new SpatialData...")
|
||||
sdata = sd.SpatialData(tables={"table": mod})
|
||||
|
||||
logger.info(f"Writing output SpatialData Zarr store to {par['output']}...")
|
||||
sdata.write(par["output"], overwrite=True)
|
||||
|
||||
logger.info("Done!")
|
||||
143
src/convert/from_h5mu_to_spatialdata/test.py
Normal file
143
src/convert/from_h5mu_to_spatialdata/test.py
Normal file
@@ -0,0 +1,143 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import mudata as mu
|
||||
import pytest
|
||||
import spatialdata as sd
|
||||
|
||||
|
||||
def test_simple_execution(run_component, tmp_path):
|
||||
input = meta["resources_dir"] + "/xenium_tiny.h5mu"
|
||||
input_spatialdata = meta["resources_dir"] + "/xenium_tiny.zarr"
|
||||
output = tmp_path / "output.zarr"
|
||||
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input,
|
||||
"--input_spatialdata",
|
||||
input_spatialdata,
|
||||
"--output",
|
||||
output,
|
||||
]
|
||||
)
|
||||
assert os.path.exists(output), "output zarr was not created"
|
||||
|
||||
mdata = mu.read_h5mu(input)
|
||||
mod = mdata.mod["rna"]
|
||||
|
||||
sdata = sd.read_zarr(output)
|
||||
table = sdata["table"]
|
||||
|
||||
# Check that the main table in the SpatialData object matches the selected modality in the MuData object
|
||||
assert table.n_obs == mod.n_obs, (
|
||||
"The number of observations in the SpatialData table does not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.obs_names.equals(mod.obs_names), (
|
||||
"The observation names in the SpatialData table do not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.n_vars == mod.n_vars, (
|
||||
"The number of variables in the SpatialData table does not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.var_names.equals(mod.var_names), (
|
||||
"The variable names in the SpatialData table do not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.obs.keys().equals(mod.obs.keys()), (
|
||||
"The observation metadata columns in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert table.var.keys().equals(mod.var.keys()), (
|
||||
"The variable metadata columns in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert set(table.uns.keys()) == set(mod.uns.keys()), (
|
||||
"The unstructured metadata keys in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert set(table.obsm.keys()) == set(mod.obsm.keys()), (
|
||||
"The obsm keys in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert set(table.varm.keys()) == set(mod.varm.keys()), (
|
||||
"The varm keys in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
|
||||
sdata_existing = sd.read_zarr(input_spatialdata)
|
||||
|
||||
# Check that remaining slots in the SpatialData object are filled from the existing SpatialData when provided
|
||||
assert sdata.images.keys() == sdata_existing.images.keys(), (
|
||||
"The image keys in the output SpatialData do not match those in the existing SpatialData."
|
||||
)
|
||||
assert sdata.labels.keys() == sdata_existing.labels.keys(), (
|
||||
"The label keys in the output SpatialData do not match those in the existing SpatialData."
|
||||
)
|
||||
assert sdata.shapes.keys() == sdata_existing.shapes.keys(), (
|
||||
"The shape keys in the output SpatialData do not match those in the existing SpatialData."
|
||||
)
|
||||
assert sdata.points.keys() == sdata_existing.points.keys(), (
|
||||
"The point keys in the output SpatialData do not match those in the existing SpatialData."
|
||||
)
|
||||
|
||||
|
||||
def test_execution_without_input_spatialdata(run_component, tmp_path):
|
||||
input = meta["resources_dir"] + "/xenium_tiny.h5mu"
|
||||
output = tmp_path / "output_no_spatialdata.zarr"
|
||||
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input,
|
||||
"--output",
|
||||
output,
|
||||
]
|
||||
)
|
||||
assert os.path.exists(output), "output zarr was not created"
|
||||
|
||||
mdata = mu.read_h5mu(input)
|
||||
mod = mdata.mod["rna"]
|
||||
|
||||
sdata = sd.read_zarr(output)
|
||||
table = sdata["table"]
|
||||
|
||||
# Check that the main table in the SpatialData object matches the selected modality in the MuData object
|
||||
assert table.n_obs == mod.n_obs, (
|
||||
"The number of observations in the SpatialData table does not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.obs_names.equals(mod.obs_names), (
|
||||
"The observation names in the SpatialData table do not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.n_vars == mod.n_vars, (
|
||||
"The number of variables in the SpatialData table does not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.var_names.equals(mod.var_names), (
|
||||
"The variable names in the SpatialData table do not match the selected modality in the MuData object."
|
||||
)
|
||||
assert table.obs.keys().equals(mod.obs.keys()), (
|
||||
"The observation metadata columns in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert table.var.keys().equals(mod.var.keys()), (
|
||||
"The variable metadata columns in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert set(table.uns.keys()) == set(mod.uns.keys()), (
|
||||
"The unstructured metadata keys in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert set(table.obsm.keys()) == set(mod.obsm.keys()), (
|
||||
"The obsm keys in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
assert set(table.varm.keys()) == set(mod.varm.keys()), (
|
||||
"The varm keys in the SpatialData table do not match those in the selected modality of the MuData object."
|
||||
)
|
||||
|
||||
# When no existing SpatialData is provided, remaining slots should be empty
|
||||
assert len(sdata.images) == 0, (
|
||||
"Expected no images when input_spatialdata is not provided."
|
||||
)
|
||||
assert len(sdata.labels) == 0, (
|
||||
"Expected no labels when input_spatialdata is not provided."
|
||||
)
|
||||
assert len(sdata.shapes) == 0, (
|
||||
"Expected no shapes when input_spatialdata is not provided."
|
||||
)
|
||||
assert len(sdata.points) == 0, (
|
||||
"Expected no points when input_spatialdata is not provided."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main([__file__]))
|
||||
@@ -64,6 +64,7 @@ engines:
|
||||
- python3-pip
|
||||
- python3-dev
|
||||
- python-is-python3
|
||||
- cmake
|
||||
- type: r
|
||||
cran: [ reticulate, testthat ]
|
||||
- type: python
|
||||
|
||||
@@ -68,8 +68,6 @@ engines:
|
||||
env: ["LIBARROW_MINIMAL=false"]
|
||||
- type: r
|
||||
script: 'install.packages("arrow", type = "source")'
|
||||
- type: r
|
||||
script: 'Sys.setenv(LIBARROW_MINIMAL = "false"); install.packages("arrow", type = "source")'
|
||||
- type: r
|
||||
bioc: [ SpatialExperimentIO ]
|
||||
test_setup:
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
name: split_h5mu
|
||||
namespace: "dataflow"
|
||||
scope: "public"
|
||||
description: |
|
||||
Split the samples of a single modality from a .h5mu (multimodal) sample into seperate .h5mu files based on the values of an .obs column of this modality.
|
||||
authors:
|
||||
- __merge__: /src/authors/dorien_roosen.yaml
|
||||
roles: [ author, maintainer ]
|
||||
argument_groups:
|
||||
- name: Input & specifications
|
||||
arguments:
|
||||
- name: "--input"
|
||||
type: file
|
||||
description: Path to a single .h5mu file.
|
||||
required: true
|
||||
- name: "--modality"
|
||||
description: |
|
||||
Which modality from the input MuData file to process.
|
||||
type: string
|
||||
default: "rna"
|
||||
required: false
|
||||
- name: "--obs_feature"
|
||||
type: string
|
||||
required: true
|
||||
description: The .obs column to split the mudata on.
|
||||
example: "celltype"
|
||||
- name: "--drop_obs_nan"
|
||||
type: boolean_true
|
||||
description: Whether to drop all .obs columns that contain only nan values after splitting.
|
||||
- name: "--ensure_unique_filenames"
|
||||
type: boolean_true
|
||||
description: Append number suffixes to ensure unique filenames after sanitizing obs feature values.
|
||||
|
||||
- name: Outputs
|
||||
arguments:
|
||||
- name: "--output"
|
||||
type: file
|
||||
required: true
|
||||
direction: output
|
||||
example: "/path/to/output"
|
||||
description: Output directory containing multiple h5mu files.
|
||||
- name: "--output_files"
|
||||
type: file
|
||||
required: true
|
||||
direction: output
|
||||
example: sample_files.csv
|
||||
description: A csv containing the base filename and obs feature by which it was split.
|
||||
__merge__: [., /src/base/h5_compression_argument.yaml]
|
||||
|
||||
|
||||
resources:
|
||||
- type: python_script
|
||||
path: script.py
|
||||
- path: /src/utils/setup_logger.py
|
||||
test_resources:
|
||||
- type: python_script
|
||||
path: test.py
|
||||
|
||||
engines:
|
||||
- type: docker
|
||||
image: python:3.12-slim
|
||||
setup:
|
||||
- type: apt
|
||||
packages:
|
||||
- procps
|
||||
- type: python
|
||||
__merge__: /src/base/requirements/anndata_mudata.yaml
|
||||
__merge__: [ /src/base/requirements/python_test_setup.yaml, .]
|
||||
runners:
|
||||
- type: executable
|
||||
- type: nextflow
|
||||
directives:
|
||||
label: [ lowcpu, highmem, highdisk]
|
||||
@@ -1,119 +0,0 @@
|
||||
import sys
|
||||
import mudata as mu
|
||||
import pandas as pd
|
||||
import re
|
||||
import gc
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
|
||||
### VIASH START
|
||||
par = {
|
||||
"input": "cart_atomx_process_samples.h5mu",
|
||||
"modality": "rna",
|
||||
"obs_feature": "sample_id",
|
||||
"output": "reference_download/sample_split",
|
||||
"drop_obs_nan": "true",
|
||||
"output_compression": None,
|
||||
"output_files": "reference_download/sample_files.csv",
|
||||
"ensure_unique_filenames": True,
|
||||
}
|
||||
meta = {
|
||||
"resources_dir": "src/utils",
|
||||
}
|
||||
# import anndata as ad
|
||||
|
||||
# df = pd.DataFrame(
|
||||
# [[1, 2, 3], [4, 5, 6]], index=["obs1", "obs2"], columns=["var1", "var2", "var3"]
|
||||
# )
|
||||
# var3 = pd.DataFrame(["d", "e", "g"], index=df.columns, columns=["Feat"])
|
||||
# obs3 = pd.DataFrame(["C C", "C_C"], index=df.index, columns=["Obs"])
|
||||
# ad3 = ad.AnnData(df, obs=obs3, var=var3)
|
||||
# mdata = mu.MuData({"rna": ad3})
|
||||
# mdata.write_h5mu("test_san.h5mu")
|
||||
# par["input"] = "test_san.h5mu"
|
||||
# par["obs_feature"] = "Obs"
|
||||
### VIASH END
|
||||
|
||||
sys.path.append(meta["resources_dir"])
|
||||
from setup_logger import setup_logger
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
|
||||
def main():
|
||||
logger.info(f"Reading {par['input']}")
|
||||
input_file = Path(par["input"].strip())
|
||||
|
||||
mdata = mu.read_h5mu(input_file)
|
||||
adata = mdata.mod[par["modality"]]
|
||||
|
||||
logger.info(f"Reading unique features from {par['obs_feature']}")
|
||||
obs_features = adata.obs[par["obs_feature"]].unique().tolist()
|
||||
|
||||
# sanitize --obs_feature values
|
||||
obs_features_s = [re.sub(r"[-\s]", "_", str(s).strip()) for s in obs_features]
|
||||
obs_features_s = [re.sub(r"[^A-Za-z0-9_]", "", s) for s in obs_features_s]
|
||||
|
||||
# ensure that names are unique, if not raise or append number as suffix
|
||||
if not len(obs_features_s) == len(set(obs_features_s)):
|
||||
if not par["ensure_unique_filenames"]:
|
||||
raise ValueError(
|
||||
f"File names are not unique after sanitizing the --obs_feature {par['obs_feature']} values"
|
||||
)
|
||||
|
||||
logger.info("Ensuring unique names for par['obs_feature']")
|
||||
counts = defaultdict(lambda: -1)
|
||||
for i, feature in enumerate(obs_features_s):
|
||||
counts[feature] += 1
|
||||
if (curr_counts := counts[feature]) > 0:
|
||||
obs_features_s[i] += f"_{curr_counts}"
|
||||
|
||||
# generate output dir
|
||||
output_dir = Path(par["output"])
|
||||
if not output_dir.is_dir():
|
||||
output_dir.mkdir(parents=True)
|
||||
|
||||
# split modality of mdata file base on obs_feature
|
||||
logger.info(f"Splitting file based on {par['obs_feature']} values {obs_features}")
|
||||
obs_files = []
|
||||
|
||||
for obs_name, file_name in zip(obs_features, obs_features_s):
|
||||
logger.info(
|
||||
f"Filtering modality '{par['modality']}' observations by .obs['{par['obs_feature']}'] == {obs_name}"
|
||||
)
|
||||
mdata_obs = mdata.copy()
|
||||
adata_full = mdata_obs.mod[par["modality"]]
|
||||
|
||||
# split the samples
|
||||
mask = adata_full.obs[par["obs_feature"]] == obs_name
|
||||
adata_obs = adata_full[mask].copy()
|
||||
|
||||
# Dropping columns that only have nan values after splitting
|
||||
if par["drop_obs_nan"]:
|
||||
logger.info("Dropping all .obs columns with NaN values")
|
||||
adata_obs.obs = adata_obs.obs.dropna(axis=1, how="all")
|
||||
|
||||
mdata_obs.mod[par["modality"]] = adata_obs
|
||||
|
||||
mdata_obs_name = f"{input_file.stem}_{file_name}.h5mu"
|
||||
out_path = output_dir / mdata_obs_name
|
||||
|
||||
# replace mdata file with modality adata contianing split samples
|
||||
logger.info(
|
||||
f"Writing h5mu filtered for {par['obs_feature']} {obs_name} to file {out_path}"
|
||||
)
|
||||
|
||||
mdata_obs.write_h5mu(out_path, compression=par["output_compression"])
|
||||
|
||||
# avoid keeping files in memory
|
||||
obs_files.append(mdata_obs_name)
|
||||
del mdata_obs, adata_obs
|
||||
gc.collect()
|
||||
|
||||
logger.info(f"Writing output_files CSV file to {par['output_files']}")
|
||||
df = pd.DataFrame({"name": obs_features_s, "filename": obs_files})
|
||||
df.to_csv(par["output_files"], index=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,288 +0,0 @@
|
||||
import sys
|
||||
from textwrap import dedent
|
||||
import pytest
|
||||
import mudata as mu
|
||||
import anndata as ad
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_modality_1():
|
||||
df = pd.DataFrame(
|
||||
[[1, 2, 3], [4, 5, 6]], index=["obs1", "obs2"], columns=["var1", "var2", "var3"]
|
||||
)
|
||||
obs = pd.DataFrame({"Obs": ["A", "B"], "Obs_nan": [np.nan, np.nan]}, index=df.index)
|
||||
var = pd.DataFrame([["a"], ["b"], ["c"]], index=df.columns, columns=["Feat"])
|
||||
ad1 = ad.AnnData(df, obs=obs, var=var)
|
||||
return ad1
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_modality_2():
|
||||
df = pd.DataFrame(
|
||||
[[1, 2, 3], [4, 5, 6]], index=["obs1", "obs2"], columns=["var1", "var2", "var3"]
|
||||
)
|
||||
var2 = pd.DataFrame(["d", "e", "g"], index=df.columns, columns=["Feat"])
|
||||
obs2 = pd.DataFrame(["C", "D"], index=df.index, columns=["Obs"])
|
||||
ad2 = ad.AnnData(df, obs=obs2, var=var2)
|
||||
return ad2
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_modality_3():
|
||||
df = pd.DataFrame(
|
||||
[[1, 2, 3], [4, 5, 6]], index=["obs1", "obs2"], columns=["var1", "var2", "var3"]
|
||||
)
|
||||
var3 = pd.DataFrame(["d", "e", "g"], index=df.columns, columns=["Feat"])
|
||||
obs3 = pd.DataFrame(["C C", "C_C"], index=df.index, columns=["Obs"])
|
||||
ad3 = ad.AnnData(df, obs=obs3, var=var3)
|
||||
return ad3
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_h5mu(input_modality_1, input_modality_2):
|
||||
tmp_mudata = mu.MuData({"mod1": input_modality_1, "mod2": input_modality_2})
|
||||
return tmp_mudata
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_h5mu_path(write_mudata_to_file, input_h5mu):
|
||||
return write_mudata_to_file(input_h5mu)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_h5mu_non_unique_filenames(input_modality_3):
|
||||
tmp_mudata = mu.MuData({"mod3": input_modality_3})
|
||||
return tmp_mudata
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def input_h5mu_path_non_unique_filenames(
|
||||
write_mudata_to_file, input_h5mu_non_unique_filenames
|
||||
):
|
||||
return write_mudata_to_file(input_h5mu_non_unique_filenames)
|
||||
|
||||
|
||||
def test_sample_split(run_component, random_path, input_h5mu, input_h5mu_path):
|
||||
output_dir = random_path()
|
||||
output_files = random_path(extension="csv")
|
||||
args = [
|
||||
"--input",
|
||||
input_h5mu_path,
|
||||
"--output",
|
||||
str(output_dir),
|
||||
"--modality",
|
||||
"mod1",
|
||||
"--obs_feature",
|
||||
"Obs",
|
||||
"--output_files",
|
||||
str(output_files),
|
||||
]
|
||||
|
||||
run_component(args)
|
||||
assert output_files.is_file()
|
||||
assert output_dir.is_dir()
|
||||
|
||||
# check output dir and file names
|
||||
dir_content = [
|
||||
h5mu_file
|
||||
for h5mu_file in output_dir.iterdir()
|
||||
if h5mu_file.suffix == ".h5mu" and h5mu_file != input_h5mu_path
|
||||
]
|
||||
s1_file = output_dir / f"{input_h5mu_path.stem}_A.h5mu"
|
||||
s2_file = output_dir / f"{input_h5mu_path.stem}_B.h5mu"
|
||||
assert set(dir_content) == set([s1_file, s2_file])
|
||||
|
||||
# check that number of modalities, variables and observations
|
||||
s1 = mu.read_h5mu(s1_file)
|
||||
s2 = mu.read_h5mu(s2_file)
|
||||
assert s1.n_mod == 2
|
||||
assert s2.n_mod == 2
|
||||
|
||||
assert s1.n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file does not match input file"
|
||||
)
|
||||
assert s2.n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file does not match input file"
|
||||
)
|
||||
|
||||
assert s1.mod["mod1"].n_obs == 1, (
|
||||
"number of observations of split file s1 modality mod1 should equal 1"
|
||||
)
|
||||
assert s1.mod["mod2"].n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file s1 modality mod2 should equal input file"
|
||||
)
|
||||
|
||||
assert len(s1.mod["mod1"].obs.keys()) == 2, (
|
||||
"number of observation keys split file s1 modality mod1 should equal 2"
|
||||
)
|
||||
assert len(s1.mod["mod2"].obs.keys()) == 1, (
|
||||
"number of observation keys split file s1 modality mod2 should equal 1"
|
||||
)
|
||||
|
||||
assert s2.mod["mod1"].n_obs == 1, (
|
||||
"number of observations of split file s2 modality mod1 should equal 1"
|
||||
)
|
||||
assert s2.mod["mod2"].n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file s2 modality mod2 should equal input file"
|
||||
)
|
||||
|
||||
assert s1.n_vars == input_h5mu.n_vars, (
|
||||
"number of variables of split file s1 should equal input file"
|
||||
)
|
||||
assert s2.n_vars == input_h5mu.n_vars, (
|
||||
"number of variables of split file s1 should equal input file"
|
||||
)
|
||||
|
||||
assert s1.mod["mod1"].n_vars == input_h5mu.mod["mod1"].n_vars, (
|
||||
"number of variables of split file s1 modalitty mod1 should equal input file"
|
||||
)
|
||||
assert s1.mod["mod2"].n_vars == input_h5mu.mod["mod1"].n_vars, (
|
||||
"number of variables of split file s1 modalitty mod2 should equal input file"
|
||||
)
|
||||
|
||||
assert s2.mod["mod1"].n_vars == input_h5mu.mod["mod1"].n_vars, (
|
||||
"number of variables of split file s2 modalitty mod1 should equal input file"
|
||||
)
|
||||
assert s2.mod["mod2"].n_vars == input_h5mu.mod["mod1"].n_vars, (
|
||||
"number of variables of split file s2 modalitty mod2 should equal input file"
|
||||
)
|
||||
|
||||
# check correct sample splitting
|
||||
assert np.all(s1.mod["mod1"].obs["Obs"] == "A"), (
|
||||
"observation of .obs Obs in s1 should equal A"
|
||||
)
|
||||
assert np.all(s2.mod["mod1"].obs["Obs"] == "B"), (
|
||||
"observation of .obs Obs in s2 should equal B"
|
||||
)
|
||||
|
||||
# Check contents of csv file
|
||||
expected_csv_output = dedent(
|
||||
f"""\
|
||||
name,filename
|
||||
A,{s1_file.name}
|
||||
B,{s2_file.name}
|
||||
"""
|
||||
)
|
||||
with open(output_files, "r") as open_csv_file:
|
||||
result = open_csv_file.read()
|
||||
assert result == expected_csv_output
|
||||
|
||||
|
||||
def test_sample_split_dropna(run_component, random_path, input_h5mu, input_h5mu_path):
|
||||
output_dir = random_path()
|
||||
output_files = random_path(extension="csv")
|
||||
args = [
|
||||
"--input",
|
||||
input_h5mu_path,
|
||||
"--output",
|
||||
str(output_dir),
|
||||
"--modality",
|
||||
"mod1",
|
||||
"--obs_feature",
|
||||
"Obs",
|
||||
"--drop_obs_nan",
|
||||
"true",
|
||||
"--output_files",
|
||||
str(output_files),
|
||||
]
|
||||
|
||||
run_component(args)
|
||||
|
||||
# check output dir and file names
|
||||
s1_file = output_dir / f"{input_h5mu_path.stem}_A.h5mu"
|
||||
s2_file = output_dir / f"{input_h5mu_path.stem}_B.h5mu"
|
||||
|
||||
# check that .obs columns with only nan values are dropped correctly
|
||||
s1 = mu.read_h5mu(s1_file)
|
||||
s2 = mu.read_h5mu(s2_file)
|
||||
|
||||
assert s1.n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file does not match input file"
|
||||
)
|
||||
assert s2.n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file does not match input file"
|
||||
)
|
||||
|
||||
assert s1.mod["mod1"].n_obs == 1, (
|
||||
"number of observations of split file s1 modality mod1 should equal 1"
|
||||
)
|
||||
assert s1.mod["mod2"].n_obs == input_h5mu.n_obs, (
|
||||
"number of observations of split file s1 modality mod2 should equal input file"
|
||||
)
|
||||
|
||||
assert len(s1.mod["mod1"].obs.keys()) == 1, (
|
||||
"number of observation keys split file s1 modality mod1 should equal 1"
|
||||
)
|
||||
assert len(s1.mod["mod2"].obs.keys()) == 1, (
|
||||
"number of observation keys split file s1 modality mod2 should equal 1"
|
||||
)
|
||||
|
||||
|
||||
def test_sanitizing(run_component, random_path, input_h5mu_path_non_unique_filenames):
|
||||
output_dir = random_path()
|
||||
output_files = random_path(extension="csv")
|
||||
|
||||
args = [
|
||||
"--input",
|
||||
input_h5mu_path_non_unique_filenames,
|
||||
"--output",
|
||||
str(output_dir),
|
||||
"--modality",
|
||||
"mod3",
|
||||
"--obs_feature",
|
||||
"Obs",
|
||||
"--drop_obs_nan",
|
||||
"true",
|
||||
"--output_files",
|
||||
str(output_files),
|
||||
]
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError) as err:
|
||||
run_component(args)
|
||||
assert re.search(
|
||||
r"ValueError: File names are not unique after sanitizing the --obs_feature Obs values",
|
||||
err.value.stdout.decode("utf-8"),
|
||||
)
|
||||
|
||||
args_san = [
|
||||
"--input",
|
||||
input_h5mu_path_non_unique_filenames,
|
||||
"--output",
|
||||
str(output_dir),
|
||||
"--modality",
|
||||
"mod3",
|
||||
"--obs_feature",
|
||||
"Obs",
|
||||
"--drop_obs_nan",
|
||||
"true",
|
||||
"--output_files",
|
||||
str(output_files),
|
||||
"--ensure_unique_filenames",
|
||||
"true",
|
||||
]
|
||||
|
||||
run_component(args_san)
|
||||
|
||||
# check output dir and file names
|
||||
dir_content = [
|
||||
h5mu_file
|
||||
for h5mu_file in output_dir.iterdir()
|
||||
if h5mu_file.suffix == ".h5mu"
|
||||
and h5mu_file != input_h5mu_path_non_unique_filenames
|
||||
]
|
||||
s1_file = output_dir / f"{input_h5mu_path_non_unique_filenames.stem}_C_C.h5mu"
|
||||
s2_file = output_dir / f"{input_h5mu_path_non_unique_filenames.stem}_C_C_1.h5mu"
|
||||
|
||||
assert s1_file.is_file(), f"{s1_file} does not exist"
|
||||
assert s2_file.is_file(), f"{s2_file} does not exist"
|
||||
assert set(dir_content) == set([s1_file, s2_file]), (
|
||||
"Output files do not match file names in csv"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main([__file__]))
|
||||
111
src/feature_annotation/spatial_autocorr/config.vsh.yaml
Normal file
111
src/feature_annotation/spatial_autocorr/config.vsh.yaml
Normal file
@@ -0,0 +1,111 @@
|
||||
name: spatial_autocorr
|
||||
namespace: feature_annotation
|
||||
label: Spatial Autocorrelation
|
||||
summary: Calculate spatial autocorrelation for genes using Moran's I or Geary's C.
|
||||
description: |
|
||||
Calculate spatial autocorrelation for genes using Moran's I or Geary's C.
|
||||
This allows identifying spatially variable genes.
|
||||
|
||||
argument_groups:
|
||||
- name: Inputs
|
||||
arguments:
|
||||
- name: --input
|
||||
type: file
|
||||
required: true
|
||||
description: Input h5mu file.
|
||||
- name: --modality
|
||||
type: string
|
||||
default: rna
|
||||
description: Modality to use.
|
||||
- name: --layer
|
||||
type: string
|
||||
description: |
|
||||
Layer in the AnnData object to use.
|
||||
- If `attr` is 'X', this is the key in `.layers` to use. If not provided, `.X` is used.
|
||||
- If `attr` is 'obsm', this is the key in `.obsm` to use.
|
||||
- name: --input_genes
|
||||
type: string
|
||||
multiple: true
|
||||
multiple_sep: ","
|
||||
description: |
|
||||
The features to calculate autocorrelation for. Meaning depends on `--attr`:
|
||||
- If `attr` is 'X' (default), this must be a list of gene names from `.var_names`.
|
||||
If not provided, it defaults to using genes in `.var['highly_variable']` (if present), or all genes.
|
||||
This behavior can be overridden by setting `--use_all_genes` to `true`.
|
||||
Note: You cannot pass a column name from `.var` here.
|
||||
- If `attr` is 'obs', this must be a list of column names from `.obs`.
|
||||
- If `attr` is 'obsm', this must be indices in `.obsm[layer]` (as strings).
|
||||
- name: --obsp_neighborhood_graph
|
||||
type: string
|
||||
default: spatial_connectivities
|
||||
description: Key in .obsp where spatial connectivities are stored.
|
||||
- name: --use_all_genes
|
||||
type: boolean
|
||||
default: false
|
||||
description: |
|
||||
Whether to use all genes even if highly variable genes are present in .var.
|
||||
If set to true, all genes will be used.
|
||||
|
||||
- name: Parameters
|
||||
arguments:
|
||||
- name: --mode
|
||||
type: string
|
||||
default: moran
|
||||
choices: [moran, geary]
|
||||
description: Mode of spatial autocorrelation.
|
||||
- name: --attr
|
||||
type: string
|
||||
default: X
|
||||
choices: [X, obs, obsm]
|
||||
description: |
|
||||
The attribute of the AnnData object to use for calculation.
|
||||
- 'X': Use gene expression data (default).
|
||||
- 'obs': Use cell metadata.
|
||||
- 'obsm': Use multidimensional embeddings.
|
||||
- name: --n_perms
|
||||
type: integer
|
||||
default: 100
|
||||
description: Number of permutations for p-value calculation.
|
||||
- name: --use_raw
|
||||
type: boolean
|
||||
default: false
|
||||
description: Whether to use .raw attribute of AnnData.
|
||||
|
||||
- name: Outputs
|
||||
arguments:
|
||||
- name: --output
|
||||
type: file
|
||||
direction: output
|
||||
required: true
|
||||
description: Output h5mu file with results in .uns.
|
||||
|
||||
resources:
|
||||
- type: python_script
|
||||
path: script.py
|
||||
|
||||
test_resources:
|
||||
- type: python_script
|
||||
path: test.py
|
||||
- path: /resources_test/xenium/xenium_tiny.qc.neighbors.h5mu
|
||||
|
||||
engines:
|
||||
- type: docker
|
||||
image: python:3.13-slim
|
||||
setup:
|
||||
- type: apt
|
||||
packages:
|
||||
- procps
|
||||
- type: python
|
||||
__merge__: [/src/base/requirements/anndata_mudata.yaml, /src/base/requirements/scanpy.yaml, /src/base/requirements/squidpy.yaml]
|
||||
test_setup:
|
||||
- type: python
|
||||
packages:
|
||||
- pytest
|
||||
- viashpy
|
||||
- type: native
|
||||
|
||||
runners:
|
||||
- type: executable
|
||||
- type: nextflow
|
||||
directives:
|
||||
label: [midcpu, midmem]
|
||||
80
src/feature_annotation/spatial_autocorr/script.py
Normal file
80
src/feature_annotation/spatial_autocorr/script.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import mudata as mu
|
||||
import squidpy as sq
|
||||
|
||||
## VIASH START
|
||||
par = {
|
||||
"input": "resources_test/xenium/xenium_tiny_qc_graph.h5mu",
|
||||
"output": "output.h5mu",
|
||||
"modality": "rna",
|
||||
"mode": "moran",
|
||||
"input_genes": None,
|
||||
"attr": "X",
|
||||
"n_perms": 100,
|
||||
"layer": None,
|
||||
"use_raw": False,
|
||||
"obsp_neighborhood_graph": "spatial_connectivities",
|
||||
"use_all_genes": False,
|
||||
}
|
||||
## VIASH END
|
||||
|
||||
|
||||
def main():
|
||||
print("Reading input MuData...", flush=True)
|
||||
mdata = mu.read_h5mu(par["input"])
|
||||
adata = mdata.mod[par["modality"]]
|
||||
|
||||
# Check for connectivity key
|
||||
if par["obsp_neighborhood_graph"] not in adata.obsp:
|
||||
raise ValueError(
|
||||
f"Connectivity key '{par['obsp_neighborhood_graph']}' not found in .obsp of modality '{par['modality']}'."
|
||||
)
|
||||
|
||||
genes = par["input_genes"]
|
||||
if genes and len(genes) == 0:
|
||||
genes = None
|
||||
|
||||
if genes is None and par["use_all_genes"] and par["attr"] == "X":
|
||||
genes = list(adata.var_names)
|
||||
|
||||
# Handle layer
|
||||
layer = par["layer"]
|
||||
if layer == "None":
|
||||
layer = None
|
||||
|
||||
print(f"Calculating spatial autocorrelation ({par['mode']})...", flush=True)
|
||||
|
||||
# Run Squidpy spatial_autocorr
|
||||
# Note: sq.gr.spatial_autocorr modifies adata in-place, adding results to .uns
|
||||
sq.gr.spatial_autocorr(
|
||||
adata,
|
||||
connectivity_key=par["obsp_neighborhood_graph"],
|
||||
genes=genes,
|
||||
mode=par["mode"],
|
||||
attr=par["attr"],
|
||||
n_perms=par["n_perms"],
|
||||
layer=layer,
|
||||
use_raw=par["use_raw"],
|
||||
)
|
||||
|
||||
result_key = f"{par['mode']}I" if par["mode"] == "moran" else f"{par['mode']}C"
|
||||
|
||||
if result_key in adata.uns:
|
||||
# Log top spatially variable genes
|
||||
df = adata.uns[result_key]
|
||||
if not df.empty:
|
||||
sort_col = "I" if par["mode"] == "moran" else "C"
|
||||
print("Top spatially variable genes:", flush=True)
|
||||
print(df.sort_values(by=sort_col, ascending=False).head(), flush=True)
|
||||
else:
|
||||
print(
|
||||
f"Warning: Expected key '{result_key}' not found in .uns after calculation.",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
print("Writing output...", flush=True)
|
||||
mdata.write_h5mu(par["output"])
|
||||
print("Done!", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
220
src/feature_annotation/spatial_autocorr/test.py
Normal file
220
src/feature_annotation/spatial_autocorr/test.py
Normal file
@@ -0,0 +1,220 @@
|
||||
import mudata as mu
|
||||
import sys
|
||||
import pytest
|
||||
import pandas as pd
|
||||
|
||||
## VIASH START
|
||||
meta = {
|
||||
"resources_dir": "resources_test/xenium",
|
||||
"executable": "./calculate_spatial_autocorrelation",
|
||||
}
|
||||
## VIASH END
|
||||
|
||||
|
||||
def test_calculate_spatial_autocorrelation_moran(run_component, tmp_path):
|
||||
input_path = meta["resources_dir"] + "/xenium_tiny.qc.neighbors.h5mu"
|
||||
output_path = tmp_path / "output_moran.h5mu"
|
||||
|
||||
print(f"Running component with Moran's I on {input_path}")
|
||||
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
str(input_path),
|
||||
"--output",
|
||||
str(output_path),
|
||||
"--modality",
|
||||
"rna",
|
||||
"--obsp_neighborhood_graph",
|
||||
"spatial_connectivities",
|
||||
"--mode",
|
||||
"moran",
|
||||
"--n_perms",
|
||||
"10", # Reduce permutations for speed
|
||||
]
|
||||
)
|
||||
|
||||
assert output_path.exists(), "Output file not created"
|
||||
|
||||
mdata = mu.read_h5mu(output_path)
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
assert "moranI" in adata.uns, "moranI key missing from .uns"
|
||||
df = adata.uns["moranI"]
|
||||
assert isinstance(df, pd.DataFrame), "moranI should be a DataFrame"
|
||||
assert not df.empty, "moranI DataFrame is empty"
|
||||
|
||||
# Check essential columns
|
||||
expected_cols = ["I", "pval_norm", "var_norm"]
|
||||
for col in expected_cols:
|
||||
assert col in df.columns, f"Missing column {col} in moranI dataframe"
|
||||
|
||||
# Check values range
|
||||
assert df["I"].max() <= 1.0, "Moran's I > 1 (theoretical max)"
|
||||
assert df["I"].min() >= -1.0, "Moran's I < -1 (theoretical min)"
|
||||
|
||||
|
||||
def test_calculate_spatial_autocorrelation_geary(run_component, tmp_path):
|
||||
input_path = meta["resources_dir"] + "/xenium_tiny.qc.neighbors.h5mu"
|
||||
output_path = tmp_path / "output_geary.h5mu"
|
||||
|
||||
mdata = mu.read_h5mu(input_path)
|
||||
genes = list(mdata.mod["rna"].var_names[:5]) # Test with first 5 genes
|
||||
genes_str = ",".join(genes)
|
||||
|
||||
cmd = [
|
||||
"--input",
|
||||
str(input_path),
|
||||
"--output",
|
||||
str(output_path),
|
||||
"--modality",
|
||||
"rna",
|
||||
"--obsp_neighborhood_graph",
|
||||
"spatial_connectivities",
|
||||
"--mode",
|
||||
"geary",
|
||||
"--n_perms",
|
||||
"10",
|
||||
"--input_genes",
|
||||
genes_str,
|
||||
]
|
||||
|
||||
print(
|
||||
f"Running component with Geary's C on {input_path} for subset of genes: {genes_str}"
|
||||
)
|
||||
run_component(cmd)
|
||||
|
||||
assert output_path.exists()
|
||||
|
||||
mdata = mu.read_h5mu(output_path)
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
assert "gearyC" in adata.uns
|
||||
df = adata.uns["gearyC"]
|
||||
|
||||
assert len(df) == 5, f"Expected results for 5 genes, got {len(df)}"
|
||||
assert all(g in df.index for g in genes), (
|
||||
"Not all requested genes are in output index"
|
||||
)
|
||||
|
||||
assert "C" in df.columns
|
||||
|
||||
|
||||
def test_calculate_spatial_autocorrelation_obs(run_component, tmp_path):
|
||||
input_path = meta["resources_dir"] + "/xenium_tiny.qc.neighbors.h5mu"
|
||||
output_path = tmp_path / "output_obs.h5mu"
|
||||
|
||||
features = "total_counts,cell_area,nucleus_area"
|
||||
|
||||
print(
|
||||
f"Running component with Moran's I on {input_path} for obs features: {features}"
|
||||
)
|
||||
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
str(input_path),
|
||||
"--output",
|
||||
str(output_path),
|
||||
"--modality",
|
||||
"rna",
|
||||
"--obsp_neighborhood_graph",
|
||||
"spatial_connectivities",
|
||||
"--mode",
|
||||
"moran",
|
||||
"--attr",
|
||||
"obs",
|
||||
"--input_genes",
|
||||
features,
|
||||
"--n_perms",
|
||||
"10",
|
||||
]
|
||||
)
|
||||
|
||||
assert output_path.exists()
|
||||
|
||||
mdata = mu.read_h5mu(output_path)
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
assert "moranI" in adata.uns
|
||||
df = adata.uns["moranI"]
|
||||
|
||||
assert len(df) == 3, f"Expected results for 3 features, got {len(df)}"
|
||||
# When attr='obs', the index contains the column names
|
||||
for feature in features.split(","):
|
||||
assert feature in df.index, f"Feature {feature} missing from index: {df.index}"
|
||||
|
||||
|
||||
def test_calculate_spatial_autocorrelation_use_all_genes(run_component, tmp_path):
|
||||
input_path = meta["resources_dir"] + "/xenium_tiny.qc.neighbors.h5mu"
|
||||
temp_input_path = tmp_path / "xenium_tiny_hvg.h5mu"
|
||||
output_path_hvg = tmp_path / "output_hvg.h5mu"
|
||||
output_path_all = tmp_path / "output_all.h5mu"
|
||||
|
||||
# Create dataset with highly variable genes
|
||||
mdata = mu.read_h5mu(input_path)
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
# Mark first 5 genes as highly variable
|
||||
adata.var["highly_variable"] = False
|
||||
genes = list(adata.var_names)
|
||||
for g in genes[:5]:
|
||||
adata.var.loc[g, "highly_variable"] = True
|
||||
|
||||
mdata.write_h5mu(temp_input_path)
|
||||
|
||||
# Test 1: Default behavior (should use only HVG)
|
||||
print("Running component with default settings (expecting HVG usage)")
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
str(temp_input_path),
|
||||
"--output",
|
||||
str(output_path_hvg),
|
||||
"--modality",
|
||||
"rna",
|
||||
"--obsp_neighborhood_graph",
|
||||
"spatial_connectivities",
|
||||
"--mode",
|
||||
"moran",
|
||||
"--n_perms",
|
||||
"10",
|
||||
]
|
||||
)
|
||||
|
||||
assert output_path_hvg.exists()
|
||||
mdata_hvg = mu.read_h5mu(output_path_hvg)
|
||||
df_hvg = mdata_hvg.mod["rna"].uns["moranI"]
|
||||
assert len(df_hvg) == 5, f"Expected 5 genes (HVG), got {len(df_hvg)}"
|
||||
|
||||
# Test 2: Override to use all genes
|
||||
print("Running component with --use_all_genes (expecting all genes)")
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
str(temp_input_path),
|
||||
"--output",
|
||||
str(output_path_all),
|
||||
"--modality",
|
||||
"rna",
|
||||
"--obsp_neighborhood_graph",
|
||||
"spatial_connectivities",
|
||||
"--mode",
|
||||
"moran",
|
||||
"--n_perms",
|
||||
"10",
|
||||
"--use_all_genes",
|
||||
"true",
|
||||
]
|
||||
)
|
||||
|
||||
assert output_path_all.exists()
|
||||
mdata_all = mu.read_h5mu(output_path_all)
|
||||
df_all = mdata_all.mod["rna"].uns["moranI"]
|
||||
assert len(df_all) == len(genes), (
|
||||
f"Expected all {len(genes)} genes, got {len(df_all)}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main([__file__]))
|
||||
109
src/feature_annotation/xenium_spatial_statistics/config.vsh.yaml
Normal file
109
src/feature_annotation/xenium_spatial_statistics/config.vsh.yaml
Normal file
@@ -0,0 +1,109 @@
|
||||
name: xenium_spatial_statistics
|
||||
namespace: feature_annotation
|
||||
label: Xenium Spatial Statistics
|
||||
description: |
|
||||
Calculate various spatial statistics from Xenium data including cell morphology
|
||||
ratios, position-based features, local density metrics, and global spatial patterns.
|
||||
This component expects a MuData object with a pre-computed spatial neighborhood graph
|
||||
in `.obsp`.
|
||||
|
||||
argument_groups:
|
||||
- name: Inputs
|
||||
arguments:
|
||||
- name: --input
|
||||
type: file
|
||||
required: true
|
||||
example: input.h5mu
|
||||
description: |
|
||||
A MuData file containing spatial transcriptomics data and a
|
||||
pre-computed spatial neighborhood graph in `.obsp`.
|
||||
|
||||
- name: --modality
|
||||
type: string
|
||||
required: true
|
||||
default: "rna"
|
||||
description: |
|
||||
The name of the modality to use from the MuData object.
|
||||
This specifies which AnnData object contains the spatial data.
|
||||
|
||||
- name: --obsm_spatial_coordinates
|
||||
type: string
|
||||
default: "spatial"
|
||||
description: |
|
||||
The key in `.obsm` where spatial coordinates are stored.
|
||||
Expected shape is (n_cells, 2) for 2D coordinates.
|
||||
|
||||
- name: Outputs
|
||||
arguments:
|
||||
- name: --output
|
||||
type: file
|
||||
direction: output
|
||||
default: output.h5mu
|
||||
description: |
|
||||
The output MuData file with calculated spatial statistics.
|
||||
Per-cell metrics are stored in `.obs` and global statistics in `.uns`.
|
||||
|
||||
- name: --output_prefix
|
||||
type: string
|
||||
default: "spatial_"
|
||||
description: |
|
||||
Prefix to add to all generated column names in `.obs`.
|
||||
|
||||
- name: Parameters
|
||||
arguments:
|
||||
- name: --density_bandwidth
|
||||
type: double
|
||||
default: 50.0
|
||||
description: |
|
||||
Bandwidth parameter for Gaussian kernel density estimation in spatial units
|
||||
(typically microns). Larger values create smoother density estimates.
|
||||
|
||||
- name: "--calculate_ripley_l"
|
||||
type: boolean
|
||||
default: false
|
||||
description: |
|
||||
Whether to calculate Ripley's L statistic.
|
||||
Warning: This is an O(N^2) operation and can be very slow for large datasets (>5000 cells).
|
||||
|
||||
- name: "--n_subsample_ripley"
|
||||
type: integer
|
||||
default: -1
|
||||
description: |
|
||||
Number of cells to subsample for Ripley's L calculation.
|
||||
If -1, use all cells. Recommended to keep this below 5000 for performance.
|
||||
|
||||
resources:
|
||||
- type: python_script
|
||||
path: script.py
|
||||
|
||||
test_resources:
|
||||
- type: python_script
|
||||
path: test.py
|
||||
- path: /resources_test/xenium/xenium_tiny.qc.neighbors.h5mu
|
||||
|
||||
engines:
|
||||
- type: docker
|
||||
image: python:3.13-slim
|
||||
setup:
|
||||
- type: apt
|
||||
packages:
|
||||
- procps
|
||||
- type: python
|
||||
__merge__:
|
||||
- /src/base/requirements/anndata_mudata.yaml
|
||||
- /src/base/requirements/scanpy.yaml
|
||||
- /src/base/requirements/squidpy.yaml
|
||||
packages:
|
||||
- scikit-learn
|
||||
test_setup:
|
||||
- type: python
|
||||
packages:
|
||||
- pytest
|
||||
- viashpy
|
||||
- type: native
|
||||
|
||||
runners:
|
||||
- type: executable
|
||||
- type: nextflow
|
||||
directives:
|
||||
label: [singlecpu, midmem, lowdisk]
|
||||
315
src/feature_annotation/xenium_spatial_statistics/script.py
Normal file
315
src/feature_annotation/xenium_spatial_statistics/script.py
Normal file
@@ -0,0 +1,315 @@
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
import mudata as mu
|
||||
import numpy as np
|
||||
import squidpy as sq
|
||||
from scipy.spatial import ConvexHull, Voronoi, distance_matrix
|
||||
from sklearn.neighbors import KernelDensity
|
||||
|
||||
## VIASH START
|
||||
par = {
|
||||
"input": "resources_test/xenium/xenium_tiny_qc.h5mu",
|
||||
"output": "output.h5mu",
|
||||
"modality": "rna",
|
||||
"obsm_spatial_coordinates": "spatial",
|
||||
"density_bandwidth": 50.0,
|
||||
"calculate_ripley_l": False,
|
||||
"n_subsample_ripley": -1,
|
||||
"output_prefix": "spatial_",
|
||||
}
|
||||
## VIASH END
|
||||
|
||||
|
||||
def calculate_morphology_metrics(adata, prefix):
|
||||
"""Calculate cell morphology ratios and features."""
|
||||
print(" Calculating morphology metrics...", flush=True)
|
||||
|
||||
if "cell_area" not in adata.obs or "nucleus_area" not in adata.obs:
|
||||
warnings.warn(
|
||||
"cell_area and/or nucleus_area not found in .obs. "
|
||||
"Skipping morphology metrics."
|
||||
)
|
||||
return
|
||||
|
||||
# Nucleus to cell area ratio - can be removed once https://github.com/openpipelines-bio/openpipeline_qc/issues/18 is fixed.
|
||||
adata.obs[f"{prefix}nucleus_cell_ratio"] = (
|
||||
adata.obs["nucleus_area"] / adata.obs["cell_area"]
|
||||
)
|
||||
|
||||
# Cell area percentile (relative size)
|
||||
adata.obs[f"{prefix}cell_area_percentile"] = (
|
||||
adata.obs["cell_area"].rank(pct=True) * 100
|
||||
)
|
||||
|
||||
print(
|
||||
f" Added: {prefix}nucleus_cell_ratio, {prefix}cell_area_percentile",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
|
||||
def calculate_position_features(adata, spatial_coords, prefix):
|
||||
"""Calculate position-based features."""
|
||||
print(" Calculating position-based features...", flush=True)
|
||||
|
||||
# Tissue centroid
|
||||
centroid = spatial_coords.mean(axis=0)
|
||||
|
||||
# Distance to centroid
|
||||
distances_to_centroid = np.linalg.norm(spatial_coords - centroid, axis=1)
|
||||
adata.obs[f"{prefix}distance_to_centroid"] = distances_to_centroid
|
||||
|
||||
# Normalized coordinates (0-1 scale)
|
||||
min_coords = spatial_coords.min(axis=0)
|
||||
max_coords = spatial_coords.max(axis=0)
|
||||
coord_range = max_coords - min_coords
|
||||
|
||||
normalized_coords = (spatial_coords - min_coords) / coord_range
|
||||
adata.obs[f"{prefix}norm_x"] = normalized_coords[:, 0]
|
||||
adata.obs[f"{prefix}norm_y"] = normalized_coords[:, 1]
|
||||
|
||||
# Distance to convex hull boundary
|
||||
try:
|
||||
hull = ConvexHull(spatial_coords)
|
||||
hull_points = spatial_coords[hull.vertices]
|
||||
|
||||
# For each point, find distance to nearest hull vertex (approximation)
|
||||
distances_to_boundary = np.min(
|
||||
distance_matrix(spatial_coords, hull_points), axis=1
|
||||
)
|
||||
adata.obs[f"{prefix}distance_to_boundary"] = distances_to_boundary
|
||||
print(
|
||||
" Added: distance_to_centroid, norm_x, norm_y, distance_to_boundary",
|
||||
flush=True,
|
||||
)
|
||||
except Exception as e:
|
||||
warnings.warn(f"Could not calculate convex hull: {e}")
|
||||
print(" Added: distance_to_centroid, norm_x, norm_y", flush=True)
|
||||
|
||||
|
||||
def calculate_density_metrics(adata, spatial_coords, bandwidth, prefix):
|
||||
"""Calculate local density metrics."""
|
||||
print(" Calculating density metrics...", flush=True)
|
||||
|
||||
# Kernel density estimation
|
||||
kde = KernelDensity(bandwidth=bandwidth, kernel="gaussian")
|
||||
kde.fit(spatial_coords)
|
||||
log_density = kde.score_samples(spatial_coords)
|
||||
adata.obs[f"{prefix}kernel_density"] = np.exp(log_density)
|
||||
|
||||
# Calculate degree centrality (as a proxy for local density / number of neighbors)
|
||||
# This assumes spatial_connectivities is already present in .obsp (from build_spatial_graph)
|
||||
if "spatial_connectivities" in adata.obsp:
|
||||
spatial_connectivities = adata.obsp["spatial_connectivities"]
|
||||
degrees = spatial_connectivities.sum(axis=1)
|
||||
# If sparse matrix, it returns matrix object, need to convert to array
|
||||
if hasattr(degrees, "A1"):
|
||||
degrees = degrees.A1
|
||||
adata.obs[f"{prefix}graph_degree"] = degrees
|
||||
|
||||
print(" Added: kernel_density, graph_degree", flush=True)
|
||||
else:
|
||||
print(
|
||||
" Warning: 'spatial_connectivities' not found in .obsp. Skipping graph_degree.",
|
||||
flush=True,
|
||||
)
|
||||
print(" Added: kernel_density", flush=True)
|
||||
|
||||
|
||||
def calculate_voronoi_metrics(adata, spatial_coords, prefix):
|
||||
"""Calculate Voronoi tessellation statistics."""
|
||||
print(" Calculating Voronoi tessellation...", flush=True)
|
||||
|
||||
try:
|
||||
vor = Voronoi(spatial_coords)
|
||||
|
||||
polygon_areas = []
|
||||
neighbor_counts = []
|
||||
|
||||
for point_idx in range(len(spatial_coords)):
|
||||
region_idx = vor.point_region[point_idx]
|
||||
region = vor.regions[region_idx]
|
||||
|
||||
# Skip infinite regions
|
||||
if -1 in region or len(region) == 0:
|
||||
polygon_areas.append(np.nan)
|
||||
neighbor_counts.append(np.nan)
|
||||
continue
|
||||
|
||||
# Calculate polygon area using shoelace formula
|
||||
vertices = vor.vertices[region]
|
||||
x = vertices[:, 0]
|
||||
y = vertices[:, 1]
|
||||
area = 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)))
|
||||
polygon_areas.append(area)
|
||||
|
||||
# Count neighbors (shared vertices)
|
||||
neighbor_counts.append(len(region))
|
||||
|
||||
adata.obs[f"{prefix}voronoi_area"] = polygon_areas
|
||||
adata.obs[f"{prefix}voronoi_neighbors"] = neighbor_counts
|
||||
|
||||
print(" Added: voronoi_area, voronoi_neighbors", flush=True)
|
||||
except Exception as e:
|
||||
warnings.warn(f"Could not calculate Voronoi tessellation: {e}")
|
||||
|
||||
|
||||
def calculate_global_statistics(adata, spatial_coords, par):
|
||||
"""Calculate global spatial pattern statistics."""
|
||||
print(" Calculating global spatial statistics...", flush=True)
|
||||
|
||||
stats = {}
|
||||
|
||||
# Global density
|
||||
try:
|
||||
hull = ConvexHull(spatial_coords)
|
||||
area = hull.volume # In 2D, volume of convex hull is the area
|
||||
stats["area_calculation_method"] = "convex_hull"
|
||||
stats["cell_density"] = len(spatial_coords) / area
|
||||
stats["total_area"] = area
|
||||
stats["n_cells"] = len(spatial_coords)
|
||||
except Exception as e:
|
||||
print(f" Error: Could not calculate convex hull area ({e})", flush=True)
|
||||
|
||||
# Ripley's L (using squidpy)
|
||||
if par["calculate_ripley_l"]:
|
||||
print(" Computing Ripley's L function (Squidpy)...", flush=True)
|
||||
|
||||
n_subsample = par["n_subsample_ripley"]
|
||||
|
||||
try:
|
||||
# Create a working AnnData for Ripley's
|
||||
if n_subsample > 0 and len(adata) > n_subsample:
|
||||
print(f" Subsampling to {n_subsample} random cells...", flush=True)
|
||||
|
||||
# Use numpy to generate random indices
|
||||
indices = np.random.choice(len(adata), n_subsample, replace=False)
|
||||
adata_ripley = adata[indices].copy()
|
||||
stats["ripley_l_subsampled"] = True
|
||||
else:
|
||||
adata_ripley = adata.copy()
|
||||
stats["ripley_l_subsampled"] = False
|
||||
|
||||
# Squidpy requires a cluster key. We create a dummy one for "global" context.
|
||||
adata_ripley.obs["_temp_global"] = "all"
|
||||
adata_ripley.obs["_temp_global"] = adata_ripley.obs["_temp_global"].astype(
|
||||
"category"
|
||||
)
|
||||
|
||||
# Calculate Ripley's L statistic
|
||||
# This stores the result in adata.uns['all_L']
|
||||
sq.gr.ripley(
|
||||
adata_ripley,
|
||||
cluster_key="_temp_global",
|
||||
mode="L",
|
||||
spatial_key=par["obsm_spatial_coordinates"],
|
||||
n_simulations=50,
|
||||
)
|
||||
|
||||
# Extract basic stats from the results
|
||||
if "all_L" in adata_ripley.uns and "L_stat" in adata_ripley.uns["all_L"]:
|
||||
l_stat_df = adata_ripley.uns["all_L"]["L_stat"]
|
||||
stats["ripley_l_max"] = float(l_stat_df.max().max())
|
||||
stats["ripley_l_mean"] = float(l_stat_df.mean().mean())
|
||||
|
||||
# Clean up
|
||||
if "all_L" in adata_ripley.uns:
|
||||
del adata_ripley.uns["all_L"]
|
||||
|
||||
except Exception as e:
|
||||
print(f" Error calculating Ripley's L: {e}", flush=True)
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
else:
|
||||
print(" Skipping Ripley's L (disabled in config)...", flush=True)
|
||||
|
||||
# Spatial extent
|
||||
min_coords = spatial_coords.min(axis=0)
|
||||
max_coords = spatial_coords.max(axis=0)
|
||||
|
||||
stats["spatial_extent_x"] = float(max_coords[0] - min_coords[0])
|
||||
stats["spatial_extent_y"] = float(max_coords[1] - min_coords[1])
|
||||
stats["centroid_x"] = float(spatial_coords[:, 0].mean())
|
||||
stats["centroid_y"] = float(spatial_coords[:, 1].mean())
|
||||
|
||||
if "cell_density" in stats:
|
||||
print(
|
||||
f" Global stats: cell_density={stats['cell_density']:.4f}",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
def main(par):
|
||||
print(f"\n>>> Reading MuData from '{par['input']}'...", flush=True)
|
||||
mdata = mu.read_h5mu(par["input"])
|
||||
print(mdata, flush=True)
|
||||
|
||||
print(f"\n>>> Extracting modality '{par['modality']}'...", flush=True)
|
||||
if par["modality"] not in mdata.mod:
|
||||
raise KeyError(
|
||||
f"Modality '{par['modality']}' not found in MuData. "
|
||||
f"Available modalities: {list(mdata.mod.keys())}"
|
||||
)
|
||||
adata = mdata[par["modality"]]
|
||||
print(adata, flush=True)
|
||||
|
||||
print(
|
||||
f"\n>>> Extracting spatial coordinates from .obsm['{par['obsm_spatial_coordinates']}']...",
|
||||
flush=True,
|
||||
)
|
||||
if par["obsm_spatial_coordinates"] not in adata.obsm:
|
||||
raise KeyError(
|
||||
f"Spatial key '{par['obsm_spatial_coordinates']}' not found in .obsm. "
|
||||
f"Available keys: {list(adata.obsm.keys())}"
|
||||
)
|
||||
|
||||
spatial_coords = adata.obsm[par["obsm_spatial_coordinates"]]
|
||||
if spatial_coords.shape[1] != 2:
|
||||
raise ValueError(
|
||||
f"Expected 2D spatial coordinates, got shape {spatial_coords.shape}"
|
||||
)
|
||||
print(f" Shape: {spatial_coords.shape} (n_cells × 2)", flush=True)
|
||||
|
||||
prefix = par["output_prefix"]
|
||||
|
||||
# Calculate morphology metrics
|
||||
print("\n>>> Calculating morphology metrics...", flush=True)
|
||||
calculate_morphology_metrics(adata, prefix)
|
||||
|
||||
# Calculate position features
|
||||
print("\n>>> Calculating position-based features...", flush=True)
|
||||
calculate_position_features(adata, spatial_coords, prefix)
|
||||
|
||||
# Calculate density metrics
|
||||
print("\n>>> Calculating density metrics...", flush=True)
|
||||
calculate_density_metrics(
|
||||
adata,
|
||||
spatial_coords,
|
||||
par["density_bandwidth"],
|
||||
prefix,
|
||||
)
|
||||
|
||||
# Calculate Voronoi tessellation
|
||||
print("\n>>> Calculating Voronoi tessellation...", flush=True)
|
||||
calculate_voronoi_metrics(adata, spatial_coords, prefix)
|
||||
|
||||
# Calculate global statistics
|
||||
print("\n>>> Calculating global spatial statistics...", flush=True)
|
||||
global_stats = calculate_global_statistics(adata, spatial_coords, par)
|
||||
|
||||
# Store in uns
|
||||
if "spatial_stats" not in adata.uns:
|
||||
adata.uns["spatial_stats"] = {}
|
||||
adata.uns["spatial_stats"].update(global_stats)
|
||||
|
||||
print(f"\n>>> Writing output to '{par['output']}'...", flush=True)
|
||||
mdata.write_h5mu(par["output"])
|
||||
|
||||
print("\n>>> Done!\n", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(par))
|
||||
75
src/feature_annotation/xenium_spatial_statistics/test.py
Normal file
75
src/feature_annotation/xenium_spatial_statistics/test.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import mudata as mu
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
## VIASH START
|
||||
meta = {
|
||||
"resources_dir": "resources_test/xenium",
|
||||
"executable": "./xenium_spatial_statistics",
|
||||
}
|
||||
## VIASH END
|
||||
|
||||
|
||||
def test_calculate_spatial_statistics(run_component, tmp_path):
|
||||
input_path = meta["resources_dir"] + "/xenium_tiny.qc.neighbors.h5mu"
|
||||
output_path = tmp_path / "output.h5mu"
|
||||
|
||||
# Run the component directly on the input file
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
str(input_path),
|
||||
"--output",
|
||||
str(output_path),
|
||||
"--modality",
|
||||
"rna",
|
||||
"--obsm_spatial_coordinates",
|
||||
"spatial",
|
||||
"--density_bandwidth",
|
||||
"50.0",
|
||||
"--calculate_ripley_l",
|
||||
"false",
|
||||
]
|
||||
)
|
||||
|
||||
assert output_path.exists(), "Output file not created"
|
||||
|
||||
mdata_out = mu.read_h5mu(output_path)
|
||||
adata_out = mdata_out.mod["rna"]
|
||||
|
||||
# Check for expected columns in .obs
|
||||
expected_cols = [
|
||||
"spatial_nucleus_cell_ratio",
|
||||
"spatial_cell_area_percentile",
|
||||
"spatial_distance_to_centroid",
|
||||
"spatial_norm_x",
|
||||
"spatial_norm_y",
|
||||
"spatial_kernel_density",
|
||||
"spatial_graph_degree",
|
||||
"spatial_voronoi_area",
|
||||
"spatial_voronoi_neighbors",
|
||||
]
|
||||
|
||||
for col in expected_cols:
|
||||
assert col in adata_out.obs.columns, f"Column {col} missing from output .obs"
|
||||
|
||||
# Check for expected metrics in .uns['spatial_stats']
|
||||
assert "spatial_stats" in adata_out.uns, "spatial_stats missing from .uns"
|
||||
stats = adata_out.uns["spatial_stats"]
|
||||
|
||||
expected_stats = [
|
||||
"cell_density",
|
||||
"total_area",
|
||||
"n_cells",
|
||||
"spatial_extent_x",
|
||||
"spatial_extent_y",
|
||||
"centroid_x",
|
||||
"centroid_y",
|
||||
]
|
||||
|
||||
for stat in expected_stats:
|
||||
assert stat in stats, f"Stat {stat} missing from spatial_stats"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main([__file__]))
|
||||
91
src/neighbors/join_graphs/config.vsh.yaml
Normal file
91
src/neighbors/join_graphs/config.vsh.yaml
Normal file
@@ -0,0 +1,91 @@
|
||||
name: join_graphs
|
||||
namespace: neighbors
|
||||
description: |
|
||||
Combine spatial and expression neighborhood graphs into a single graph for
|
||||
use in downstream clustering or trajectory analysis.
|
||||
|
||||
The fusion is a linear combination of the expression connectivities
|
||||
and spatial connectivities matrices, weighted by `alpha`.
|
||||
|
||||
$C_{joint} = (1 - \alpha) \cdot C_{expression} + \alpha \cdot C_{spatial}$
|
||||
|
||||
authors:
|
||||
- __merge__: /src/authors/jakub_majercik.yaml
|
||||
roles: [ maintainer ]
|
||||
|
||||
argument_groups:
|
||||
- name: "Inputs"
|
||||
arguments:
|
||||
- name: "--input"
|
||||
type: file
|
||||
required: true
|
||||
description: Input H5MU file with pre-computed expression and spatial neighborhood graphs.
|
||||
- name: "--modality"
|
||||
type: string
|
||||
default: "rna"
|
||||
required: false
|
||||
description: Modality from the input MuData file to process.
|
||||
- name: "--input_obsp_expression_graph"
|
||||
type: string
|
||||
default: "connectivities"
|
||||
description: |
|
||||
Key in `adata.obsp` containing the expression connectivity matrix.
|
||||
- name: "--input_obsp_spatial_graph"
|
||||
type: string
|
||||
default: "spatial_connectivities"
|
||||
description: |
|
||||
Key in `adata.obsp` containing the spatial connectivity matrix.
|
||||
|
||||
- name: "Parameters"
|
||||
arguments:
|
||||
- name: "--alpha"
|
||||
type: double
|
||||
default: 0.5
|
||||
min: 0.0
|
||||
max: 1.0
|
||||
description: |
|
||||
Weight of the spatial graph in the connection fusion.
|
||||
A value of 0 results in the original expression graph;
|
||||
a value of 1 results in the spatial graph only.
|
||||
|
||||
- name: Outputs
|
||||
arguments:
|
||||
- name: "--output"
|
||||
type: file
|
||||
direction: output
|
||||
required: true
|
||||
description: Output H5MU file path.
|
||||
example: output.h5mu
|
||||
- name: "--output_obsp_graph"
|
||||
type: string
|
||||
default: "spatial_expression_connectivities"
|
||||
description: |
|
||||
Key under which to store the fused connectivity matrix in `adata.obsp`.
|
||||
__merge__: [., /src/base/h5_compression_argument.yaml]
|
||||
|
||||
resources:
|
||||
- type: python_script
|
||||
path: script.py
|
||||
- path: /src/utils/setup_logger.py
|
||||
|
||||
test_resources:
|
||||
- type: python_script
|
||||
path: test.py
|
||||
- path: /resources_test/xenium/xenium_tiny.qc.all_neighbors.pca.h5mu
|
||||
|
||||
engines:
|
||||
- type: docker
|
||||
image: python:3.12-slim
|
||||
setup:
|
||||
- type: apt
|
||||
packages:
|
||||
- procps
|
||||
- type: python
|
||||
__merge__: [ /src/base/requirements/scanpy.yaml, /src/base/requirements/anndata_mudata.yaml, . ]
|
||||
__merge__: [ /src/base/requirements/python_test_setup.yaml, .]
|
||||
|
||||
runners:
|
||||
- type: executable
|
||||
- type: nextflow
|
||||
directives:
|
||||
label: [midcpu, midmem, middisk]
|
||||
63
src/neighbors/join_graphs/script.py
Normal file
63
src/neighbors/join_graphs/script.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import sys
|
||||
import mudata as mu
|
||||
|
||||
## VIASH START
|
||||
par = {
|
||||
# Inputs
|
||||
"input": "resources_test/xenium/xenium_tiny.spatial_expression_neighbors.h5mu",
|
||||
"modality": "rna",
|
||||
"input_obsp_expression_graph": "connectivities",
|
||||
"input_obsp_spatial_graph": "spatial_connectivities",
|
||||
# Fusion options
|
||||
"alpha": 0.2,
|
||||
# Outputs
|
||||
"output": "foo.h5mu",
|
||||
"output_compression": None,
|
||||
"output_obsp_graph": "spatial_expression_connectivities",
|
||||
}
|
||||
meta = {"resources_dir": "src/utils/"}
|
||||
## VIASH END
|
||||
|
||||
sys.path.append(meta["resources_dir"])
|
||||
from setup_logger import setup_logger
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
## Read data
|
||||
logger.info("Reading input data...")
|
||||
adata = mu.read_h5ad(par["input"], mod=par["modality"])
|
||||
|
||||
## Validate inputs
|
||||
spatial_key = par["input_obsp_spatial_graph"]
|
||||
if spatial_key not in adata.obsp:
|
||||
raise ValueError(f"Spatial graph key '{spatial_key}' not found in .obsp.")
|
||||
|
||||
expr_key = par["input_obsp_expression_graph"]
|
||||
if expr_key not in adata.obsp:
|
||||
raise ValueError(f"Expression graph key '{expr_key}' not found in .obsp.")
|
||||
|
||||
nn_graph_genes = adata.obsp[expr_key]
|
||||
nn_graph_space = adata.obsp[spatial_key]
|
||||
|
||||
## Combine graphs
|
||||
alpha = par["alpha"]
|
||||
logger.info(
|
||||
f"Combining graphs (alpha={alpha}: spatial weight, "
|
||||
f"{1 - alpha:.2f}: expression weight)..."
|
||||
)
|
||||
joint_graph = (1 - alpha) * nn_graph_genes + alpha * nn_graph_space
|
||||
out_key = par["output_obsp_graph"]
|
||||
logger.info(f"Storing result in .obsp['{out_key}']...")
|
||||
adata.obsp[out_key] = joint_graph
|
||||
adata.uns[out_key] = {
|
||||
"params": {"alpha": alpha},
|
||||
"inputs": {
|
||||
"expression_graph": expr_key,
|
||||
"spatial_graph": spatial_key,
|
||||
},
|
||||
}
|
||||
|
||||
## Write output
|
||||
logger.info("Saving output data...")
|
||||
mdata = mu.MuData({par["modality"]: adata})
|
||||
mdata.write_h5mu(par["output"], compression=par["output_compression"])
|
||||
103
src/neighbors/join_graphs/test.py
Normal file
103
src/neighbors/join_graphs/test.py
Normal file
@@ -0,0 +1,103 @@
|
||||
import pytest
|
||||
import mudata as mu
|
||||
import sys
|
||||
|
||||
## VIASH START
|
||||
meta = {
|
||||
"executable": "./target/executable/neighbors/join_graphs/join_graphs",
|
||||
"resources_dir": "resources_test/xenium/",
|
||||
}
|
||||
## VIASH END
|
||||
|
||||
input_file = f"{meta['resources_dir']}/xenium_tiny.qc.all_neighbors.pca.h5mu"
|
||||
|
||||
|
||||
def test_default_execution(run_component, tmp_path):
|
||||
output = tmp_path / "fused_neighbors.h5mu"
|
||||
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input_file,
|
||||
"--output",
|
||||
str(output),
|
||||
"--output_obsp_graph",
|
||||
"fused_conn",
|
||||
"--alpha",
|
||||
"0.2",
|
||||
"--output_compression",
|
||||
"gzip",
|
||||
]
|
||||
)
|
||||
|
||||
assert output.is_file(), "Output file was not created."
|
||||
mdata = mu.read_h5mu(output)
|
||||
assert "rna" in mdata.mod, "Expected 'rna' modality in output."
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
assert "fused_conn" in adata.obsp.keys(), (
|
||||
"Expected output obsp connectivities key to be present."
|
||||
)
|
||||
assert "fused_conn" in adata.uns.keys(), "Expected metadata for fusion in .uns."
|
||||
assert adata.uns["fused_conn"]["params"]["alpha"] == 0.2, (
|
||||
"Expected alpha parameter to be stored in .uns."
|
||||
)
|
||||
|
||||
# Check graph properties (should be combination of input graphs)
|
||||
fused = adata.obsp["fused_conn"]
|
||||
spatial = adata.obsp["spatial_connectivities"]
|
||||
expr = adata.obsp["connectivities"]
|
||||
|
||||
assert fused.shape == expr.shape == spatial.shape, (
|
||||
"Fused graph should have same shape as input graphs."
|
||||
)
|
||||
|
||||
|
||||
def test_alpha_zero_equals_expression(run_component, tmp_path):
|
||||
output = tmp_path / "alpha_zero.h5mu"
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input_file,
|
||||
"--output",
|
||||
str(output),
|
||||
"--alpha",
|
||||
"0.0",
|
||||
"--output_obsp_graph",
|
||||
"fused_zero",
|
||||
]
|
||||
)
|
||||
mdata = mu.read_h5mu(output)
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
fused = adata.obsp["fused_zero"]
|
||||
# Should equal expression graph exactly (dense check might be heavy, check nnz or sum)
|
||||
expr = adata.obsp["connectivities"]
|
||||
assert abs(fused.sum() - expr.sum()) < 1e-6
|
||||
|
||||
|
||||
def test_alpha_one_equals_spatial(run_component, tmp_path):
|
||||
output = tmp_path / "alpha_one.h5mu"
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input_file,
|
||||
"--output",
|
||||
str(output),
|
||||
"--alpha",
|
||||
"1.0",
|
||||
"--output_obsp_graph",
|
||||
"fused_one",
|
||||
]
|
||||
)
|
||||
mdata = mu.read_h5mu(output)
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
fused = adata.obsp["fused_one"]
|
||||
# Should equal spatial graph exactly
|
||||
spatial = adata.obsp["spatial_connectivities"]
|
||||
assert abs(fused.sum() - spatial.sum()) < 1e-6
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main([__file__]))
|
||||
@@ -33,6 +33,12 @@ argument_groups:
|
||||
type: string
|
||||
required: false
|
||||
description: "Input layer to use. If None, X is used"
|
||||
- name: "--var_input"
|
||||
type: string
|
||||
default: "filter_with_hvg"
|
||||
description: |
|
||||
Key in adata.var that indicates which features to include as input for the NicheCompass model.
|
||||
If not provided, all features will be included.
|
||||
- name: "--input_obsp_spatial_connectivities"
|
||||
type: string
|
||||
default: "spatial_connectivities"
|
||||
@@ -429,6 +435,7 @@ resources:
|
||||
- type: python_script
|
||||
path: script.py
|
||||
- path: /src/utils/setup_logger.py
|
||||
- path: /src/utils/subset_vars.py
|
||||
|
||||
test_resources:
|
||||
- type: python_script
|
||||
|
||||
@@ -15,6 +15,7 @@ par = {
|
||||
"input_gp_mask": "resources_test/niche/prior_knowledge_gp_mask.json",
|
||||
"input_obs_covariates": None,
|
||||
"input_obsp_spatial_connectivities": "spatial_connectivities",
|
||||
"var_input": "filter_with_hvg",
|
||||
## GP Mask
|
||||
"min_genes_per_gp": 2,
|
||||
"min_source_genes_per_gp": 1,
|
||||
@@ -89,6 +90,7 @@ meta = {"resources_dir": "src/utils/"}
|
||||
|
||||
sys.path.append(meta["resources_dir"])
|
||||
from setup_logger import setup_logger
|
||||
from subset_vars import subset_vars
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
@@ -101,6 +103,11 @@ logger.info(f"GPU count: {torch.cuda.device_count()}")
|
||||
## Read in data
|
||||
adata = mu.read_h5ad(par["input"], mod=par["modality"])
|
||||
|
||||
# Subset to HVG
|
||||
if par["var_input"]:
|
||||
# Subset to HVG
|
||||
adata = subset_vars(adata, subset_col=par["var_input"]).copy()
|
||||
|
||||
# Counts need to be float32 to be processed by nichecompass model
|
||||
# See https://discuss.pytorch.org/t/runtimeerror-mat1-and-mat2-must-have-the-same-dtype/166759
|
||||
counts_dtype = (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
import mudata as mu
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
## VIASH START
|
||||
@@ -8,21 +9,38 @@ meta = {
|
||||
}
|
||||
## VIASH END
|
||||
|
||||
input_xenium = f"{meta['resources_dir']}/xenium_tiny.h5mu"
|
||||
input_cosmx = f"{meta['resources_dir']}/Lung5_Rep2_tiny.h5mu"
|
||||
input_path_xenium = f"{meta['resources_dir']}/xenium_tiny.h5mu"
|
||||
input_path_cosmx = f"{meta['resources_dir']}/Lung5_Rep2_tiny.h5mu"
|
||||
gp_mask = f"{meta['resources_dir']}/prior_knowledge_gp_mask.json"
|
||||
|
||||
|
||||
def test_simple_execution_xenium(run_component, tmp_path):
|
||||
@pytest.fixture
|
||||
def input_xenium_with_hvg_filter(tmp_path):
|
||||
mdata = mu.read_h5mu(input_path_xenium)
|
||||
adata = mdata.mod["rna"]
|
||||
np.random.seed(42)
|
||||
n_select = min(1000, adata.n_vars)
|
||||
selected = np.random.choice(adata.n_vars, size=n_select, replace=False)
|
||||
mask = np.zeros(adata.n_vars, dtype=bool)
|
||||
mask[selected] = True
|
||||
adata.var["filter_with_hvg"] = mask
|
||||
output = tmp_path / "xenium_with_hvg_filter.h5mu"
|
||||
mdata.write_h5mu(output)
|
||||
return str(output)
|
||||
|
||||
|
||||
def test_simple_execution_xenium(run_component, tmp_path, input_xenium_with_hvg_filter):
|
||||
output = tmp_path / "nc_xenium.h5mu"
|
||||
|
||||
# run component
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input_xenium,
|
||||
input_xenium_with_hvg_filter,
|
||||
"--input_gp_mask",
|
||||
gp_mask,
|
||||
"--var_input",
|
||||
"filter_with_hvg",
|
||||
"--n_epochs",
|
||||
"1",
|
||||
"--n_epochs_all_gps",
|
||||
@@ -84,5 +102,48 @@ def test_simple_execution_xenium(run_component, tmp_path):
|
||||
), "Expected GP targets and sources varm to have same shape"
|
||||
|
||||
|
||||
def test_no_var_input(run_component, tmp_path, input_xenium_with_hvg_filter):
|
||||
output = tmp_path / "nc_xenium_no_var_input.h5mu"
|
||||
|
||||
# run component without var_input (all genes are used)
|
||||
run_component(
|
||||
[
|
||||
"--input",
|
||||
input_xenium_with_hvg_filter,
|
||||
"--input_gp_mask",
|
||||
gp_mask,
|
||||
"--var_input",
|
||||
"",
|
||||
"--n_epochs",
|
||||
"1",
|
||||
"--n_epochs_all_gps",
|
||||
"0",
|
||||
"--n_epochs_no_edge_recon",
|
||||
"0",
|
||||
"--n_epochs_no_cat_covariates_contrastive",
|
||||
"0",
|
||||
"--output",
|
||||
str(output),
|
||||
"--output_model",
|
||||
"test_model_no_var_input",
|
||||
"--output_compression",
|
||||
"gzip",
|
||||
]
|
||||
)
|
||||
|
||||
assert output.is_file(), "output file was not created"
|
||||
mdata = mu.read_h5mu(output)
|
||||
assert list(mdata.mod.keys()) == ["rna"], "Expected modality rna"
|
||||
adata = mdata.mod["rna"]
|
||||
|
||||
expected_uns_keys = [
|
||||
"nichecompass_gp_names",
|
||||
"nichecompass_active_gp_names",
|
||||
]
|
||||
assert all([uns in adata.uns.keys() for uns in expected_uns_keys]), (
|
||||
f"Expected uns keys: {expected_uns_keys}, found: {list(adata.uns.keys())}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main([__file__]))
|
||||
|
||||
49
src/utils/subset_vars.py
Normal file
49
src/utils/subset_vars.py
Normal file
@@ -0,0 +1,49 @@
|
||||
def subset_vars(adata, subset_col):
|
||||
"""
|
||||
Subset AnnData object on highly variable genes or a boolean mask.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
adata : AnnData
|
||||
Annotated data object
|
||||
subset_col : str, pd.Series, pd.Index, or np.ndarray
|
||||
Name of the boolean column in `adata.var` that contains the information if features should be used or not,
|
||||
or a boolean mask (same length as adata.var)
|
||||
|
||||
Returns
|
||||
-------
|
||||
AnnData
|
||||
Copy of `adata` with subsetted features
|
||||
"""
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
# Convert all input types to a pandas Series
|
||||
if isinstance(subset_col, str):
|
||||
if subset_col not in adata.var.columns:
|
||||
raise ValueError(
|
||||
f"Requested to use .var column '{subset_col}' as a selection of genes, but the column is not available."
|
||||
)
|
||||
mask = adata.var[subset_col]
|
||||
elif isinstance(subset_col, pd.Series):
|
||||
mask = subset_col
|
||||
elif isinstance(subset_col, (pd.Index, np.ndarray, list)):
|
||||
mask = pd.Series(subset_col, index=adata.var.index)
|
||||
else:
|
||||
raise TypeError(
|
||||
"subset_col must be a string (column name) or a boolean mask (Series, Index, ndarray, or list)."
|
||||
)
|
||||
|
||||
# Validate mask
|
||||
if not pd.api.types.is_bool_dtype(mask):
|
||||
raise ValueError(
|
||||
f"Expected mask to be boolean, but found {mask.dtype}. Can not subset data."
|
||||
)
|
||||
if mask.isna().sum() > 0:
|
||||
raise ValueError("Mask contains NaN values. Can not subset data.")
|
||||
if len(mask) != adata.n_vars:
|
||||
raise ValueError(
|
||||
f"Mask length {len(mask)} does not match number of variables {adata.n_vars}."
|
||||
)
|
||||
|
||||
return adata[:, mask].copy()
|
||||
@@ -57,18 +57,18 @@ argument_groups:
|
||||
type: string
|
||||
default: "spatial"
|
||||
description: "Key in adata.obsm where spatial coordinates are stored"
|
||||
- name: "--var_input"
|
||||
type: string
|
||||
default: "filter_with_hvg"
|
||||
description: |
|
||||
Key in adata.var that indicates which features to include as input for the NicheCompass model.
|
||||
If not provided, all features will be included.
|
||||
|
||||
- name: "Sample ID options"
|
||||
description: |
|
||||
Options for adding the id to .obs on the MuData object. Having a sample
|
||||
id present in a requirement of several components for this pipeline.
|
||||
arguments:
|
||||
- name: "--include_sample_as_covariate"
|
||||
description: |
|
||||
Whether to include the sample information as a categorical covariate for the
|
||||
NicheCompass model.
|
||||
type: boolean
|
||||
default: true
|
||||
- name: "--add_id_to_obs"
|
||||
description: "Add the value passed with --id to .obs."
|
||||
type: boolean
|
||||
@@ -357,6 +357,7 @@ dependencies:
|
||||
- name: neighbors/spatial_neighborhood_graph
|
||||
- name: nichecompass/nichecompass
|
||||
- name: dataflow/split_h5mu
|
||||
repository: openpipeline
|
||||
- name: workflows/multiomics/neighbors_leiden_umap
|
||||
repository: openpipeline
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ workflow run_wf {
|
||||
"input": state.input,
|
||||
"input_gp_mask": state.input_gp_mask,
|
||||
"input_obs_covariates": state.input_obs_covariates,
|
||||
"var_input": state.var_input,
|
||||
"modality": state.modality,
|
||||
"layer": state.layer,
|
||||
"min_genes_per_gp": state.min_genes_per_gp,
|
||||
|
||||
@@ -19,7 +19,8 @@ workflow test_wf {
|
||||
n_epochs_all_gps: 0,
|
||||
n_epochs_no_edge_recon: 0,
|
||||
n_epochs_no_cat_covariates_contrastive_loss: 0,
|
||||
output_model: "simple_execution_test_model"
|
||||
output_model: "simple_execution_test_model",
|
||||
var_input: null
|
||||
]
|
||||
])
|
||||
| map { state -> [state.id, state] }
|
||||
|
||||
@@ -112,7 +112,7 @@ repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
docker_registry: "ghcr.io"
|
||||
@@ -227,7 +227,7 @@ build_info:
|
||||
output: "target/_private/executable/filter/subset_cosmx"
|
||||
executable: "target/_private/executable/filter/subset_cosmx/subset_cosmx"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_commit: "87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
@@ -241,7 +241,7 @@ package_config:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
|
||||
@@ -458,9 +458,9 @@ RUN pip install --upgrade pip && \
|
||||
|
||||
LABEL org.opencontainers.image.authors="Dorien Roosen, Weiwei Schultz"
|
||||
LABEL org.opencontainers.image.description="Companion container for running component filter subset_cosmx"
|
||||
LABEL org.opencontainers.image.created="2026-02-17T11:00:57Z"
|
||||
LABEL org.opencontainers.image.created="2026-03-25T10:11:21Z"
|
||||
LABEL org.opencontainers.image.source="https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
LABEL org.opencontainers.image.revision="ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
LABEL org.opencontainers.image.revision="87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
LABEL org.opencontainers.image.version="niche-compass"
|
||||
|
||||
VIASHDOCKER
|
||||
|
||||
@@ -112,7 +112,7 @@ repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
docker_registry: "ghcr.io"
|
||||
@@ -227,7 +227,7 @@ build_info:
|
||||
output: "target/_private/nextflow/filter/subset_cosmx"
|
||||
executable: "target/_private/nextflow/filter/subset_cosmx/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_commit: "87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
@@ -241,7 +241,7 @@ package_config:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
|
||||
@@ -3187,7 +3187,7 @@ meta = [
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
}
|
||||
],
|
||||
"links" : {
|
||||
@@ -3333,7 +3333,7 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/_private/nextflow/filter/subset_cosmx",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "ad19aba349736848d99a9646870d8e7868eb6515",
|
||||
"git_commit" : "87e62605aafd706d539bf2978ef47ede6fe41926",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
},
|
||||
"package_config" : {
|
||||
@@ -3353,7 +3353,7 @@ meta = [
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
}
|
||||
],
|
||||
"viash_version" : "0.9.4",
|
||||
|
||||
@@ -48,7 +48,7 @@ repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
docker_registry: "ghcr.io"
|
||||
@@ -157,7 +157,7 @@ build_info:
|
||||
output: "target/_test/executable/test_workflows/ingestion/spaceranger_mapping_test"
|
||||
executable: "target/_test/executable/test_workflows/ingestion/spaceranger_mapping_test/spaceranger_mapping_test"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_commit: "87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
@@ -171,7 +171,7 @@ package_config:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
|
||||
@@ -459,9 +459,9 @@ RUN pip install --upgrade pip && \
|
||||
|
||||
LABEL org.opencontainers.image.authors="Dorien Roosen"
|
||||
LABEL org.opencontainers.image.description="Companion container for running component test_workflows/ingestion spaceranger_mapping_test"
|
||||
LABEL org.opencontainers.image.created="2026-02-17T11:00:59Z"
|
||||
LABEL org.opencontainers.image.created="2026-03-25T10:11:23Z"
|
||||
LABEL org.opencontainers.image.source="https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
LABEL org.opencontainers.image.revision="ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
LABEL org.opencontainers.image.revision="87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
LABEL org.opencontainers.image.version="niche-compass"
|
||||
|
||||
VIASHDOCKER
|
||||
|
||||
@@ -47,7 +47,7 @@ repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
docker_registry: "ghcr.io"
|
||||
@@ -156,7 +156,7 @@ build_info:
|
||||
output: "target/_test/executable/test_workflows/niche/nichecompass_leiden_test"
|
||||
executable: "target/_test/executable/test_workflows/niche/nichecompass_leiden_test/nichecompass_leiden_test"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_commit: "87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
@@ -170,7 +170,7 @@ package_config:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
|
||||
@@ -459,9 +459,9 @@ RUN pip install --upgrade pip && \
|
||||
|
||||
LABEL org.opencontainers.image.authors="Dorien Roosen"
|
||||
LABEL org.opencontainers.image.description="Companion container for running component test_workflows/niche nichecompass_leiden_test"
|
||||
LABEL org.opencontainers.image.created="2026-02-17T11:00:59Z"
|
||||
LABEL org.opencontainers.image.created="2026-03-25T10:11:23Z"
|
||||
LABEL org.opencontainers.image.source="https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
LABEL org.opencontainers.image.revision="ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
LABEL org.opencontainers.image.revision="87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
LABEL org.opencontainers.image.version="niche-compass"
|
||||
|
||||
VIASHDOCKER
|
||||
|
||||
@@ -48,7 +48,7 @@ repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
docker_registry: "ghcr.io"
|
||||
@@ -157,7 +157,7 @@ build_info:
|
||||
output: "target/_test/nextflow/test_workflows/ingestion/spaceranger_mapping_test"
|
||||
executable: "target/_test/nextflow/test_workflows/ingestion/spaceranger_mapping_test/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_commit: "87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
@@ -171,7 +171,7 @@ package_config:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
|
||||
@@ -3104,7 +3104,7 @@ meta = [
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
}
|
||||
],
|
||||
"links" : {
|
||||
@@ -3235,7 +3235,7 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/_test/nextflow/test_workflows/ingestion/spaceranger_mapping_test",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "ad19aba349736848d99a9646870d8e7868eb6515",
|
||||
"git_commit" : "87e62605aafd706d539bf2978ef47ede6fe41926",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
},
|
||||
"package_config" : {
|
||||
@@ -3255,7 +3255,7 @@ meta = [
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
}
|
||||
],
|
||||
"viash_version" : "0.9.4",
|
||||
|
||||
@@ -47,7 +47,7 @@ repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
docker_registry: "ghcr.io"
|
||||
@@ -156,7 +156,7 @@ build_info:
|
||||
output: "target/_test/nextflow/test_workflows/niche/nichecompass_leiden_test"
|
||||
executable: "target/_test/nextflow/test_workflows/niche/nichecompass_leiden_test/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_commit: "87e62605aafd706d539bf2978ef47ede6fe41926"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
@@ -170,7 +170,7 @@ package_config:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
tag: "v4.0.3"
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
|
||||
@@ -3104,7 +3104,7 @@ meta = [
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
}
|
||||
],
|
||||
"links" : {
|
||||
@@ -3235,7 +3235,7 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/_test/nextflow/test_workflows/niche/nichecompass_leiden_test",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "ad19aba349736848d99a9646870d8e7868eb6515",
|
||||
"git_commit" : "87e62605aafd706d539bf2978ef47ede6fe41926",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
},
|
||||
"package_config" : {
|
||||
@@ -3255,7 +3255,7 @@ meta = [
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
}
|
||||
],
|
||||
"viash_version" : "0.9.4",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "split_modalities"
|
||||
namespace: "workflows/multiomics"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries Schaumont"
|
||||
roles:
|
||||
@@ -183,13 +183,13 @@ build_info:
|
||||
output: "target/_private/nextflow/workflows/multiomics/split_modalities"
|
||||
executable: "target/_private/nextflow/workflows/multiomics/split_modalities/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
dependencies:
|
||||
- "target/nextflow/dataflow/split_modalities"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -219,7 +219,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// split_modalities v4.0.2
|
||||
// split_modalities v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "split_modalities",
|
||||
"namespace" : "workflows/multiomics",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries Schaumont",
|
||||
@@ -3274,12 +3274,12 @@ meta = [
|
||||
"engine" : "native",
|
||||
"output" : "/workdir/root/repo/target/_private/nextflow/workflows/multiomics/split_modalities",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3304,7 +3304,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'workflows/multiomics/split_modalities'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'A pipeline to split a multimodal mudata files into several unimodal mudata files.'
|
||||
author = 'Dries Schaumont'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "log_normalize"
|
||||
namespace: "workflows/rna"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries Schaumont"
|
||||
roles:
|
||||
@@ -198,7 +198,7 @@ build_info:
|
||||
output: "target/_private/nextflow/workflows/rna/log_normalize"
|
||||
executable: "target/_private/nextflow/workflows/rna/log_normalize/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
dependencies:
|
||||
- "target/nextflow/transform/normalize_total"
|
||||
@@ -206,7 +206,7 @@ build_info:
|
||||
- "target/nextflow/transform/delete_layer"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -236,7 +236,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// log_normalize v4.0.2
|
||||
// log_normalize v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "log_normalize",
|
||||
"namespace" : "workflows/rna",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries Schaumont",
|
||||
@@ -3294,12 +3294,12 @@ meta = [
|
||||
"engine" : "native",
|
||||
"output" : "/workdir/root/repo/target/_private/nextflow/workflows/rna/log_normalize",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3324,7 +3324,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'workflows/rna/log_normalize'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'Performs normalization and subsequent log-transformation of raw count data.'
|
||||
author = 'Dries Schaumont'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "leiden"
|
||||
namespace: "cluster"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries De Maeyer"
|
||||
roles:
|
||||
@@ -215,7 +215,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.13-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v4.0.2"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -258,11 +258,11 @@ build_info:
|
||||
output: "target/nextflow/cluster/leiden"
|
||||
executable: "target/nextflow/cluster/leiden/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -292,7 +292,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// leiden v4.0.2
|
||||
// leiden v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "leiden",
|
||||
"namespace" : "cluster",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries De Maeyer",
|
||||
@@ -3294,7 +3294,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.13-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "v4.0.2",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3352,12 +3352,12 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/cluster/leiden",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3382,7 +3382,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -4147,7 +4147,7 @@ meta["defaults"] = [
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline/cluster/leiden",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"highcpu",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'cluster/leiden'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'Cluster cells using the [Leiden algorithm] [Traag18] implemented in the [Scanpy framework] [Wolf18]. \nLeiden is an improved version of the [Louvain algorithm] [Blondel08]. \nIt has been proposed for single-cell analysis by [Levine15] [Levine15]. \nThis requires having ran `neighbors/find_neighbors` or `neighbors/bbknn` first.\n\n[Blondel08]: Blondel et al. (2008), Fast unfolding of communities in large networks, J. Stat. Mech. \n[Levine15]: Levine et al. (2015), Data-Driven Phenotypic Dissection of AML Reveals Progenitor-like Cells that Correlate with Prognosis, Cell. \n[Traag18]: Traag et al. (2018), From Louvain to Leiden: guaranteeing well-connected communities arXiv. \n[Wolf18]: Wolf et al. (2018), Scanpy: large-scale single-cell gene expression data analysis, Genome Biology. \n'
|
||||
author = 'Dries De Maeyer'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "concatenate_h5mu"
|
||||
namespace: "dataflow"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries Schaumont"
|
||||
roles:
|
||||
@@ -253,7 +253,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.13-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v4.0.2"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -300,11 +300,11 @@ build_info:
|
||||
output: "target/nextflow/dataflow/concatenate_h5mu"
|
||||
executable: "target/nextflow/dataflow/concatenate_h5mu/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -334,7 +334,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// concatenate_h5mu v4.0.2
|
||||
// concatenate_h5mu v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "concatenate_h5mu",
|
||||
"namespace" : "dataflow",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries Schaumont",
|
||||
@@ -3328,7 +3328,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.13-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "v4.0.2",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3393,12 +3393,12 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/dataflow/concatenate_h5mu",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3423,7 +3423,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -4266,7 +4266,7 @@ meta["defaults"] = [
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline/dataflow/concatenate_h5mu",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"midcpu",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'dataflow/concatenate_h5mu'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'Concatenate observations from samples in several (uni- and/or multi-modal) MuData files into a single file.\n'
|
||||
author = 'Dries Schaumont'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "merge"
|
||||
namespace: "dataflow"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries Schaumont"
|
||||
roles:
|
||||
@@ -163,7 +163,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.12-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v4.0.2"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -204,11 +204,11 @@ build_info:
|
||||
output: "target/nextflow/dataflow/merge"
|
||||
executable: "target/nextflow/dataflow/merge/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -238,7 +238,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// merge v4.0.2
|
||||
// merge v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "merge",
|
||||
"namespace" : "dataflow",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries Schaumont",
|
||||
@@ -3246,7 +3246,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.12-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "v4.0.2",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3302,12 +3302,12 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/dataflow/merge",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3332,7 +3332,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -3847,7 +3847,7 @@ meta["defaults"] = [
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline/dataflow/merge",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"singlecpu",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'dataflow/merge'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'Combine one or more single-modality .h5mu files together into one .h5mu file.\n'
|
||||
author = 'Dries Schaumont'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "split_h5mu"
|
||||
namespace: "dataflow"
|
||||
version: "niche-compass"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dorien Roosen"
|
||||
roles:
|
||||
@@ -123,13 +123,9 @@ status: "enabled"
|
||||
scope:
|
||||
image: "public"
|
||||
target: "public"
|
||||
repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
license: "MIT"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline"
|
||||
docker_registry: "ghcr.io"
|
||||
runners:
|
||||
- type: "executable"
|
||||
@@ -207,7 +203,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.12-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "niche-compass"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -233,7 +229,7 @@ engines:
|
||||
- type: "python"
|
||||
user: false
|
||||
packages:
|
||||
- "viashpy==0.9.0"
|
||||
- "viashpy==0.8.0"
|
||||
github:
|
||||
- "openpipelines-bio/core#subdirectory=packages/python/openpipeline_testutils"
|
||||
upgrade: true
|
||||
@@ -248,21 +244,31 @@ build_info:
|
||||
output: "target/nextflow/dataflow/split_h5mu"
|
||||
executable: "target/nextflow/dataflow/split_h5mu/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "ad19aba349736848d99a9646870d8e7868eb6515"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
version: "niche-compass"
|
||||
name: "openpipeline"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
\nIn terms of workflows, the following has been made available, but keep in mind\
|
||||
\ that\nindividual tools and functionality can be executed as standalone components\
|
||||
\ as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n\
|
||||
\ * Ingestion: Read mapping and generating a count matrix.\n * Single sample\
|
||||
\ processing: cell filtering and doublet detection.\n * Multisample processing:\
|
||||
\ Count transformation, normalization, QC metric calulations.\n * Integration:\
|
||||
\ Clustering, integration and batch correction using single and multimodal methods.\n\
|
||||
\ * Downstream analysis workflows\n"
|
||||
info:
|
||||
test_resources:
|
||||
- type: "s3"
|
||||
path: "s3://openpipelines-bio/openpipeline_spatial/resources_test"
|
||||
path: "s3://openpipelines-data"
|
||||
dest: "resources_test"
|
||||
repositories:
|
||||
- type: "vsh"
|
||||
name: "openpipeline"
|
||||
repo: "openpipeline"
|
||||
tag: "v4.0.2"
|
||||
nextflow_labels_ci:
|
||||
- path: "src/workflows/utils/labels_ci.config"
|
||||
description: "Adds the correct memory and CPU labels when running on the Viash\
|
||||
\ Hub CI."
|
||||
viash_version: "0.9.4"
|
||||
source: "src"
|
||||
target: "target"
|
||||
@@ -272,8 +278,15 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'niche-compass'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
license: "MIT"
|
||||
organization: "vsh"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline"
|
||||
docker_registry: "ghcr.io"
|
||||
homepage: "https://openpipelines.bio"
|
||||
documentation: "https://openpipelines.bio/fundamentals"
|
||||
issue_tracker: "https://github.com/openpipelines-bio/openpipeline/issues"
|
||||
@@ -1,4 +1,4 @@
|
||||
// split_h5mu niche-compass
|
||||
// split_h5mu v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "split_h5mu",
|
||||
"namespace" : "dataflow",
|
||||
"version" : "niche-compass",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dorien Roosen",
|
||||
@@ -3192,16 +3192,9 @@ meta = [
|
||||
"image" : "public",
|
||||
"target" : "public"
|
||||
},
|
||||
"repositories" : [
|
||||
{
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
}
|
||||
],
|
||||
"license" : "MIT",
|
||||
"links" : {
|
||||
"repository" : "https://github.com/openpipelines-bio/openpipeline_spatial",
|
||||
"repository" : "https://github.com/openpipelines-bio/openpipeline",
|
||||
"docker_registry" : "ghcr.io"
|
||||
},
|
||||
"runners" : [
|
||||
@@ -3292,7 +3285,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.12-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "niche-compass",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3328,7 +3321,7 @@ meta = [
|
||||
"type" : "python",
|
||||
"user" : false,
|
||||
"packages" : [
|
||||
"viashpy==0.9.0"
|
||||
"viashpy==0.8.0"
|
||||
],
|
||||
"github" : [
|
||||
"openpipelines-bio/core#subdirectory=packages/python/openpipeline_testutils"
|
||||
@@ -3348,29 +3341,29 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/dataflow/split_h5mu",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "ad19aba349736848d99a9646870d8e7868eb6515",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline_spatial",
|
||||
"version" : "niche-compass",
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
"test_resources" : [
|
||||
{
|
||||
"type" : "s3",
|
||||
"path" : "s3://openpipelines-bio/openpipeline_spatial/resources_test",
|
||||
"path" : "s3://openpipelines-data",
|
||||
"dest" : "resources_test"
|
||||
}
|
||||
],
|
||||
"nextflow_labels_ci" : [
|
||||
{
|
||||
"path" : "src/workflows/utils/labels_ci.config",
|
||||
"description" : "Adds the correct memory and CPU labels when running on the Viash Hub CI."
|
||||
}
|
||||
]
|
||||
},
|
||||
"repositories" : [
|
||||
{
|
||||
"type" : "vsh",
|
||||
"name" : "openpipeline",
|
||||
"repo" : "openpipeline",
|
||||
"tag" : "v4.0.2"
|
||||
}
|
||||
],
|
||||
"viash_version" : "0.9.4",
|
||||
"source" : "/workdir/root/repo/src",
|
||||
"target" : "/workdir/root/repo/target",
|
||||
@@ -3378,12 +3371,20 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'niche-compass'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
"multimodal"
|
||||
],
|
||||
"license" : "MIT",
|
||||
"organization" : "vsh",
|
||||
"links" : {
|
||||
"repository" : "https://github.com/openpipelines-bio/openpipeline_spatial",
|
||||
"docker_registry" : "ghcr.io"
|
||||
"repository" : "https://github.com/openpipelines-bio/openpipeline",
|
||||
"docker_registry" : "ghcr.io",
|
||||
"homepage" : "https://openpipelines.bio",
|
||||
"documentation" : "https://openpipelines.bio/fundamentals",
|
||||
"issue_tracker" : "https://github.com/openpipelines-bio/openpipeline/issues"
|
||||
}
|
||||
}
|
||||
}'''))
|
||||
@@ -3908,8 +3909,8 @@ meta["defaults"] = [
|
||||
directives: readJsonBlob('''{
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline_spatial/dataflow/split_h5mu",
|
||||
"tag" : "niche-compass"
|
||||
"image" : "vsh/openpipeline/dataflow/split_h5mu",
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"lowcpu",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'dataflow/split_h5mu'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'niche-compass'
|
||||
version = 'v4.0.3'
|
||||
description = 'Split the samples of a single modality from a .h5mu (multimodal) sample into seperate .h5mu files based on the values of an .obs column of this modality. \n'
|
||||
author = 'Dorien Roosen'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "split_modalities"
|
||||
namespace: "dataflow"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries Schaumont"
|
||||
roles:
|
||||
@@ -190,7 +190,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.12-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v4.0.2"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -231,11 +231,11 @@ build_info:
|
||||
output: "target/nextflow/dataflow/split_modalities"
|
||||
executable: "target/nextflow/dataflow/split_modalities/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -265,7 +265,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// split_modalities v4.0.2
|
||||
// split_modalities v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3036,7 +3036,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "split_modalities",
|
||||
"namespace" : "dataflow",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries Schaumont",
|
||||
@@ -3280,7 +3280,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.12-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "v4.0.2",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3336,12 +3336,12 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/dataflow/split_modalities",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3366,7 +3366,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -3865,7 +3865,7 @@ meta["defaults"] = [
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline/dataflow/split_modalities",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"singlecpu",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'dataflow/split_modalities'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'Split the modalities from a single .h5mu multimodal sample into seperate .h5mu files. \n'
|
||||
author = 'Dries Schaumont, Robrecht Cannoodt'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "pca"
|
||||
namespace: "dimred"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries De Maeyer"
|
||||
roles:
|
||||
@@ -240,7 +240,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.12-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v4.0.2"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -276,11 +276,11 @@ build_info:
|
||||
output: "target/nextflow/dimred/pca"
|
||||
executable: "target/nextflow/dimred/pca/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -310,7 +310,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// pca v4.0.2
|
||||
// pca v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "pca",
|
||||
"namespace" : "dimred",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries De Maeyer",
|
||||
@@ -3333,7 +3333,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.12-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "v4.0.2",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3380,12 +3380,12 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/dimred/pca",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3410,7 +3410,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -3933,7 +3933,7 @@ meta["defaults"] = [
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline/dimred/pca",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"highcpu",
|
||||
@@ -2,7 +2,7 @@ manifest {
|
||||
name = 'dimred/pca'
|
||||
mainScript = 'main.nf'
|
||||
nextflowVersion = '!>=20.12.1-edge'
|
||||
version = 'v4.0.2'
|
||||
version = 'v4.0.3'
|
||||
description = 'Computes PCA coordinates, loadings and variance decomposition. Uses the implementation of scikit-learn [Pedregosa11].\n'
|
||||
author = 'Dries De Maeyer'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "umap"
|
||||
namespace: "dimred"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
authors:
|
||||
- name: "Dries De Maeyer"
|
||||
roles:
|
||||
@@ -294,7 +294,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.12-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v4.0.2"
|
||||
target_tag: "v4.0.3"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -330,11 +330,11 @@ build_info:
|
||||
output: "target/nextflow/dimred/umap"
|
||||
executable: "target/nextflow/dimred/umap/main.nf"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62"
|
||||
git_commit: "7bfad4ea12f87eca59213be3ab08deff67cc4206"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline"
|
||||
package_config:
|
||||
name: "openpipeline"
|
||||
version: "v4.0.2"
|
||||
version: "v4.0.3"
|
||||
summary: "Best-practice workflows for single-cell multi-omics analyses.\n"
|
||||
description: "OpenPipelines are extensible single cell analysis pipelines for reproducible\
|
||||
\ and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\
|
||||
@@ -364,7 +364,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
keywords:
|
||||
- "single-cell"
|
||||
- "multimodal"
|
||||
@@ -1,4 +1,4 @@
|
||||
// umap v4.0.2
|
||||
// umap v4.0.3
|
||||
//
|
||||
// This wrapper script is auto-generated by viash 0.9.4 and is thus a derivative
|
||||
// work thereof. This software comes with ABSOLUTELY NO WARRANTY from Data
|
||||
@@ -3035,7 +3035,7 @@ meta = [
|
||||
"config": processConfig(readJsonBlob('''{
|
||||
"name" : "umap",
|
||||
"namespace" : "dimred",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Dries De Maeyer",
|
||||
@@ -3382,7 +3382,7 @@ meta = [
|
||||
"id" : "docker",
|
||||
"image" : "python:3.12-slim",
|
||||
"target_registry" : "images.viash-hub.com",
|
||||
"target_tag" : "v4.0.2",
|
||||
"target_tag" : "v4.0.3",
|
||||
"namespace_separator" : "/",
|
||||
"setup" : [
|
||||
{
|
||||
@@ -3429,12 +3429,12 @@ meta = [
|
||||
"engine" : "docker|native",
|
||||
"output" : "/workdir/root/repo/target/nextflow/dimred/umap",
|
||||
"viash_version" : "0.9.4",
|
||||
"git_commit" : "cd7beddfa85b60b543399a9e2554b8e7b8eaaf62",
|
||||
"git_commit" : "7bfad4ea12f87eca59213be3ab08deff67cc4206",
|
||||
"git_remote" : "https://github.com/openpipelines-bio/openpipeline"
|
||||
},
|
||||
"package_config" : {
|
||||
"name" : "openpipeline",
|
||||
"version" : "v4.0.2",
|
||||
"version" : "v4.0.3",
|
||||
"summary" : "Best-practice workflows for single-cell multi-omics analyses.\n",
|
||||
"description" : "OpenPipelines are extensible single cell analysis pipelines for reproducible and large-scale single cell processing using [Viash](https://viash.io) and [Nextflow](https://www.nextflow.io/).\n\nIn terms of workflows, the following has been made available, but keep in mind that\nindividual tools and functionality can be executed as standalone components as well.\n\n * Demultiplexing: conversion of raw sequencing data to FASTQ objects.\n * Ingestion: Read mapping and generating a count matrix.\n * Single sample processing: cell filtering and doublet detection.\n * Multisample processing: Count transformation, normalization, QC metric calulations.\n * Integration: Clustering, integration and batch correction using single and multimodal methods.\n * Downstream analysis workflows\n",
|
||||
"info" : {
|
||||
@@ -3459,7 +3459,7 @@ meta = [
|
||||
".resources += {path: '/src/workflows/utils/labels.config', dest: 'nextflow_labels.config'}\n.runners[.type == 'nextflow'].config.script := 'includeConfig(\\"nextflow_labels.config\\")'",
|
||||
".engines += { type: \\"native\\" }",
|
||||
".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'",
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.2'"
|
||||
".engines[.type == 'docker'].target_tag := 'v4.0.3'"
|
||||
],
|
||||
"keywords" : [
|
||||
"single-cell",
|
||||
@@ -3971,7 +3971,7 @@ meta["defaults"] = [
|
||||
"container" : {
|
||||
"registry" : "images.viash-hub.com",
|
||||
"image" : "vsh/openpipeline/dimred/umap",
|
||||
"tag" : "v4.0.2"
|
||||
"tag" : "v4.0.3"
|
||||
},
|
||||
"label" : [
|
||||
"highcpu",
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user