Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

## NEW FUNCTIONALITY

* Added `spaTrack` method (PR #4).

## MAJOR CHANGES

Expand Down
74 changes: 74 additions & 0 deletions src/methods/spatrack/config.vsh.yaml
Original file line number Diff line number Diff line change
@@ -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]
50 changes: 50 additions & 0 deletions src/methods/spatrack/script.py
Original file line number Diff line number Diff line change
@@ -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')
Loading