Build branch openpipeline_spatial/v0.1 with version v0.1.1 to openpipeline_spatial on branch v0.1 (2baba3f)
Build pipeline: openpipelines-bio.openpipeline-spatial.0.1.1-5jtw5
Source commit: 2baba3fff0
Source message: merge main
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
name: "from_xenium_to_h5mu"
|
||||
namespace: "convert"
|
||||
version: "v0.1.0"
|
||||
version: "v0.1.1"
|
||||
authors:
|
||||
- name: "Dorien Roosen"
|
||||
roles:
|
||||
@@ -97,6 +97,8 @@ resources:
|
||||
is_executable: true
|
||||
- type: "file"
|
||||
path: "setup_logger.py"
|
||||
- type: "file"
|
||||
path: "unzip_archived_folder.py"
|
||||
- type: "file"
|
||||
path: "nextflow_labels.config"
|
||||
dest: "nextflow_labels.config"
|
||||
@@ -198,7 +200,7 @@ engines:
|
||||
id: "docker"
|
||||
image: "python:3.12-slim"
|
||||
target_registry: "images.viash-hub.com"
|
||||
target_tag: "v0.1.0"
|
||||
target_tag: "v0.1.1"
|
||||
namespace_separator: "/"
|
||||
setup:
|
||||
- type: "apt"
|
||||
@@ -217,6 +219,10 @@ engines:
|
||||
nelse: exit(1)\")"
|
||||
upgrade: true
|
||||
test_setup:
|
||||
- type: "apt"
|
||||
packages:
|
||||
- "zip"
|
||||
interactive: false
|
||||
- type: "python"
|
||||
user: false
|
||||
packages:
|
||||
@@ -233,11 +239,11 @@ build_info:
|
||||
output: "target/executable/convert/from_xenium_to_h5mu"
|
||||
executable: "target/executable/convert/from_xenium_to_h5mu/from_xenium_to_h5mu"
|
||||
viash_version: "0.9.4"
|
||||
git_commit: "3f8c1506dc59a8c9bb2a3fa6acb40e4e40291e36"
|
||||
git_commit: "2baba3fff0930478c26da7e1bd99b29ee5dd83b3"
|
||||
git_remote: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
package_config:
|
||||
name: "openpipeline_spatial"
|
||||
version: "v0.1.0"
|
||||
version: "v0.1.1"
|
||||
info:
|
||||
test_resources:
|
||||
- type: "s3"
|
||||
@@ -257,7 +263,7 @@ package_config:
|
||||
)'"
|
||||
- ".engines += { type: \"native\" }"
|
||||
- ".engines[.type == 'docker'].target_registry := 'images.viash-hub.com'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v0.1.0'"
|
||||
- ".engines[.type == 'docker'].target_tag := 'v0.1.1'"
|
||||
organization: "vsh"
|
||||
links:
|
||||
repository: "https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# from_xenium_to_h5mu v0.1.0
|
||||
# from_xenium_to_h5mu v0.1.1
|
||||
#
|
||||
# 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
|
||||
@@ -458,10 +458,10 @@ RUN pip install --upgrade pip && \
|
||||
|
||||
LABEL org.opencontainers.image.authors="Dorien Roosen"
|
||||
LABEL org.opencontainers.image.description="Companion container for running component convert from_xenium_to_h5mu"
|
||||
LABEL org.opencontainers.image.created="2025-08-25T12:22:56Z"
|
||||
LABEL org.opencontainers.image.created="2025-10-02T08:37:00Z"
|
||||
LABEL org.opencontainers.image.source="https://github.com/openpipelines-bio/openpipeline_spatial"
|
||||
LABEL org.opencontainers.image.revision="3f8c1506dc59a8c9bb2a3fa6acb40e4e40291e36"
|
||||
LABEL org.opencontainers.image.version="v0.1.0"
|
||||
LABEL org.opencontainers.image.revision="2baba3fff0930478c26da7e1bd99b29ee5dd83b3"
|
||||
LABEL org.opencontainers.image.version="v0.1.1"
|
||||
|
||||
VIASHDOCKER
|
||||
fi
|
||||
@@ -578,7 +578,7 @@ VIASH_DOCKER_RUN_ARGS=(-i --rm)
|
||||
|
||||
# ViashHelp: Display helpful explanation about this executable
|
||||
function ViashHelp {
|
||||
echo "from_xenium_to_h5mu v0.1.0"
|
||||
echo "from_xenium_to_h5mu v0.1.1"
|
||||
echo ""
|
||||
echo "Converts the output from Xenium to a single .h5mu file, where the count matrix"
|
||||
echo "is written to the \`rna\` modality."
|
||||
@@ -670,7 +670,7 @@ while [[ $# -gt 0 ]]; do
|
||||
shift 1
|
||||
;;
|
||||
--version)
|
||||
echo "from_xenium_to_h5mu v0.1.0"
|
||||
echo "from_xenium_to_h5mu v0.1.1"
|
||||
exit
|
||||
;;
|
||||
--input)
|
||||
@@ -839,7 +839,7 @@ if [[ "$VIASH_ENGINE_TYPE" == "docker" ]]; then
|
||||
|
||||
# determine docker image id
|
||||
if [[ "$VIASH_ENGINE_ID" == 'docker' ]]; then
|
||||
VIASH_DOCKER_IMAGE_ID='images.viash-hub.com/vsh/openpipeline_spatial/convert/from_xenium_to_h5mu:v0.1.0'
|
||||
VIASH_DOCKER_IMAGE_ID='images.viash-hub.com/vsh/openpipeline_spatial/convert/from_xenium_to_h5mu:v0.1.1'
|
||||
fi
|
||||
|
||||
# print dockerfile
|
||||
@@ -1154,7 +1154,9 @@ from pathlib import Path
|
||||
import scanpy as sc
|
||||
import pandas as pd
|
||||
import mudata as mu
|
||||
import zipfile
|
||||
import json
|
||||
import os
|
||||
|
||||
## VIASH START
|
||||
# The following code has been auto-generated by Viash.
|
||||
@@ -1194,21 +1196,46 @@ dep = {
|
||||
|
||||
sys.path.append(meta["resources_dir"])
|
||||
from setup_logger import setup_logger
|
||||
from unzip_archived_folder import extract_selected_files_from_zip
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
# Expected folder structure (showing only relevant files):
|
||||
# ├── cell_feature_matrix.h5
|
||||
# ├── cells.parquet
|
||||
# ├── experiment.xenium
|
||||
# └── metrics_summary.csv
|
||||
input_dir = Path(par["input"])
|
||||
input_data = {
|
||||
"count_matrix": input_dir / "cell_feature_matrix.h5",
|
||||
"cells_metadata": input_dir / "cells.parquet",
|
||||
"experiment": input_dir / "experiment.xenium",
|
||||
"metrics_summary": input_dir / "metrics_summary.csv",
|
||||
}
|
||||
|
||||
def _retrieve_input_data(xenium_output_bundle):
|
||||
# Expected folder structure (showing only relevant files):
|
||||
# ├── cell_feature_matrix.h5
|
||||
# ├── cells.parquet
|
||||
# ├── experiment.xenium
|
||||
# └── metrics_summary.csv
|
||||
|
||||
required_file_patterns = {
|
||||
"count_matrix": "**/cell_feature_matrix.h5",
|
||||
"cells_metadata": "**/cells.parquet",
|
||||
"experiment": "**/experiment.xenium",
|
||||
"metrics_summary": "**/metrics_summary.csv",
|
||||
}
|
||||
|
||||
if zipfile.is_zipfile(xenium_output_bundle):
|
||||
xenium_output_bundle = extract_selected_files_from_zip(
|
||||
xenium_output_bundle,
|
||||
members=[pattern for pattern in required_file_patterns.values()],
|
||||
)
|
||||
else:
|
||||
xenium_output_bundle = Path(xenium_output_bundle)
|
||||
|
||||
assert os.path.isdir(xenium_output_bundle), (
|
||||
"Input is expected to be a (compressed) directory."
|
||||
)
|
||||
|
||||
input_data = {}
|
||||
for key, pattern in required_file_patterns.items():
|
||||
file = list(xenium_output_bundle.glob(pattern))
|
||||
assert len(file) == 1, (
|
||||
f"Expected exactly one file matching pattern {pattern}, found {len(file)}."
|
||||
)
|
||||
input_data[key] = file[0]
|
||||
|
||||
return input_data
|
||||
|
||||
|
||||
def _format_cell_id_column(cell_id_column: pd.Series) -> pd.Series:
|
||||
@@ -1221,9 +1248,7 @@ def _format_cell_id_column(cell_id_column: pd.Series) -> pd.Series:
|
||||
# Read data from Xenium output bundle
|
||||
logger.info("Reading input data...")
|
||||
|
||||
assert all([file.exists() for file in input_data.values()]), (
|
||||
f"Not all required input files are found. Make sure that {par['input']} contains {input_data.values()}."
|
||||
)
|
||||
input_data = _retrieve_input_data(par["input"])
|
||||
|
||||
adata = sc.read_10x_h5(input_data["count_matrix"])
|
||||
metadata = pd.read_parquet(input_data["cells_metadata"], engine="pyarrow")
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import fnmatch
|
||||
import zipfile
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
|
||||
def unzip_archived_folder(archived_folder: Union[str, Path]) -> Union[str, Path]:
|
||||
"""
|
||||
Extracts a ZIP archive to a temporary directory and returns the path to the extracted folder.
|
||||
|
||||
Args:
|
||||
zip_path (Union[str, Path]): Path to the ZIP archive.
|
||||
|
||||
Returns:
|
||||
extracted_path (Union[str, Path]): Path to the extracted folder inside the temporary directory.
|
||||
"""
|
||||
|
||||
temp_dir = Path(tempfile.TemporaryDirectory().name)
|
||||
with zipfile.ZipFile(archived_folder, "r") as archive:
|
||||
archive.extractall(temp_dir)
|
||||
|
||||
return temp_dir / Path(archived_folder).stem
|
||||
|
||||
|
||||
def extract_selected_files_from_zip(
|
||||
zip_path: Union[str, Path], members: list[Union[str, Path]]
|
||||
) -> Union[str, Path]:
|
||||
"""
|
||||
Extracts selected files (supports glob patterns) from a ZIP archive to a temporary directory.
|
||||
|
||||
Args:
|
||||
zip_path (Union[str, Path]): Path to the ZIP archive.
|
||||
members (list[str]): List of file paths within the archive to extract.
|
||||
|
||||
Returns:
|
||||
Path: Path to the extraction directory.
|
||||
"""
|
||||
|
||||
temp_dir = Path(tempfile.TemporaryDirectory().name)
|
||||
|
||||
with zipfile.ZipFile(zip_path, "r") as archive:
|
||||
all_files = archive.namelist()
|
||||
selected = set()
|
||||
for pattern in members:
|
||||
selected.update(fnmatch.filter(all_files, str(pattern)))
|
||||
for member in selected:
|
||||
archive.extract(member, temp_dir)
|
||||
|
||||
return temp_dir
|
||||
Reference in New Issue
Block a user