From e1b96c5ab8478493284f7d528b465363a51c516b Mon Sep 17 00:00:00 2001 From: seohyonkim Date: Wed, 12 Aug 2026 12:34:06 +0200 Subject: [PATCH 1/2] add spatrack --- src/methods/spatrack/config.vsh.yaml | 74 ++++++++++++++++++++++++++++ src/methods/spatrack/script.py | 50 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/methods/spatrack/config.vsh.yaml create mode 100644 src/methods/spatrack/script.py diff --git a/src/methods/spatrack/config.vsh.yaml b/src/methods/spatrack/config.vsh.yaml new file mode 100644 index 0000000..d0678f8 --- /dev/null +++ b/src/methods/spatrack/config.vsh.yaml @@ -0,0 +1,74 @@ +__merge__: ../../api/comp_method.yaml + +name: spatrack +label: spaTrack +summary: "spaTrack captures fine local details of trajectory within a single tissue section of spatial transcriptomics (ST) data, as well as reconstruct cell dynamics across multiple tissue sections in a time series." +description: | #TODO come back with detailed description of how WE are implementing it + To capture potential dynamic drivers, spaTrack models the fate of a cell as a function of expression profile + along the time points driven by transcription factors, which facilitates the identification of key molecular + regulators that govern cellular trajectories. In this task, the starting cluster is automatically determined + using the functions provided by spaTrack. +references: + doi: + - 10.1016/j.cels.2025.101194 +links: + documentation: https://spatrack.readthedocs.io/en/latest/ + repository: https://github.com/yzf072/spaTrack + + + +info: + preferred_normalization: log_cp10k + +arguments: + - name: "--alpha1" + type: "double" + default: 0.5 + description: The proportion of gene expression information. + - name: "--alpha2" + type: "double" + default: 0.5 + description: The proportion of spatial location information. + +resources: + - type: python_script + path: script.py + +engines: + # custom image due to spatrack's python 3.9 pin + - type: docker + image: python:3.9-slim + setup: + - type: apt + packages: + - procps # required by Nextflow + - git # pip needs it to install openproblems core from git+https + - build-essential # compiler for any source builds (pysal/rtree deps) + - libspatialindex-dev + - libgeos-dev + - type: python + upgrade: true + github: + - "openproblems-bio/core#subdirectory=packages/python/openproblems" + packages: + - anndata~=0.10.0 + - pyyaml + - requests + - jsonschema + - spatrack==1.0.2 + - pot>=0.9.0 + - scanpy>=1.9.3,<1.10 + - plotly>=5.15.0 + - pygam>=0.8.1 + - networkx>=3.0 + - numpy==1.24.4 + - scipy==1.10.1 + - torch>=2.0.1 + - pandas==1.4.3 + - pysal==2.6.0 + +runners: + - type: executable + - type: nextflow + directives: + label: [midtime,midmem,midcpu] diff --git a/src/methods/spatrack/script.py b/src/methods/spatrack/script.py new file mode 100644 index 0000000..8de8f45 --- /dev/null +++ b/src/methods/spatrack/script.py @@ -0,0 +1,50 @@ +import anndata as ad +import scipy.sparse as sp +import spaTrack as spt + +## VIASH START +par = { + 'input': 'resources_test/task_spatial_trajectory_inference/cxg_mouse_pancreas_atlas/dataset.h5ad', + 'output': 'output.h5ad', + 'alpha1': 0.5, + 'alpha2': 0.5, +} +meta = { + 'name': 'spatrack' +} +## VIASH END + +print('Reading input files', flush=True) +adata = ad.read_h5ad(par['input']) + +adata.X = adata.layers['normalized'] +if sp.issparse(adata.X): + adata.X = adata.X.toarray() +adata.obs['cluster'] = adata.obs['cell_type'].astype(str).astype('category') + +print('Calculate cell transition probability', flush=True) +adata.obsp['trans'] = spt.get_ot_matrix( + adata, + data_type='spatial', + alpha1=par['alpha1'], + alpha2=par['alpha2'], +) + +print('Determine starting cells', flush=True) +adata = spt.assess_start_cluster(adata) +start_cluster = list(adata.uns['entropy value order'].index)[0] +start_cells = spt.set_start_cells(adata, select_way='cell_type', cell_type=start_cluster) + +print('Generate predictions', flush=True) +adata.obs['pseudotime_inferred'] = spt.get_ptime(adata, start_cells) + +print('Write output AnnData to file', flush=True) +output = ad.AnnData( + obs=adata.obs[['pseudotime_inferred']], + uns={ + 'dataset_id': adata.uns['dataset_id'], + 'normalization_id': adata.uns['normalization_id'], + 'method_id': meta['name'], + }, +) +output.write_h5ad(par['output'], compression='gzip') From 9305a1bb8675ae7fc257145ff76fda67dd35691e Mon Sep 17 00:00:00 2001 From: seohyonkim Date: Wed, 12 Aug 2026 12:56:27 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 909c046..43e97b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## NEW FUNCTIONALITY +* Added `spaTrack` method (PR #4). ## MAJOR CHANGES