Cellmotif2domain
Cellmotif2domain identifies spatial domains from single-cell spatial maps using recurrent cell-type motifs. It only requires spatial coordinates and cell-type labels. The method builds a sample-wise Delaunay graph, extracts graph-constrained cell-type motifs, calculates cell-level motif enrichment against a sample-specific null model, and clusters the resulting cell-by-motif matrix into spatial domains.
The package is designed for single-cell spatial proteomics, spatial transcriptomics after cell typing, and other imaging-based spatial omics datasets.
Installation
Install from a local checkout:
cd cellmotif2domain
pip install .
For editable development:
cd cellmotif2domain
pip install -e .
Core dependencies are numpy, pandas, scipy, scikit-learn, matplotlib, numba, and threadpoolctl.
Input Data
Cellmotif2domain expects one cell-level table in CSV, CSV.GZ, TSV, TSV.GZ or Parquet format. Each row is one cell.
Required columns:
| Column | Meaning |
|---|---|
sample_id |
Tissue section, FOV, core, or sample identifier. Graphs are built separately for each sample. |
cell_id |
Unique cell identifier. |
x |
Spatial x coordinate. |
y |
Spatial y coordinate. |
cell_type |
Cell-type label used for motif construction. |
Optional columns:
| Column | Meaning |
|---|---|
dataset_id |
Dataset or cohort name. |
true_domain |
Reference spatial-domain annotation, if available. |
true_domain_id |
Numeric reference-domain annotation, if available. |
Example:
sample_id,cell_id,x,y,cell_type
sample_1,cell_001,0.0,0.0,Tumor
sample_1,cell_002,1.0,0.1,Tumor
sample_1,cell_003,0.2,1.1,Stroma
sample_1,cell_004,1.2,1.0,T_cell
sample_2,cell_001,0.1,0.2,B_cell
If your columns have different names, pass them with --x-col, --y-col, --sample-col, --cell-id-col, and --celltype-col.
Quick Start
Run motif feature construction and domain calling in one command:
cellmotif2domain run \
--cell-table cells.csv \
--sample-col sample_id \
--cell-id-col cell_id \
--x-col x \
--y-col y \
--celltype-col cell_type \
--n-domains 8 \
--output-dir results/cellmotif2domain_k8 \
--walk-length 10 \
--walks-per-cell 100 \
--n-jobs 16 \
--export-csv
The --export-csv flag writes the final domain table and cell-by-motif matrix as CSV.GZ files for downstream analysis.
Two-Step Usage
For exploring multiple k values, run motif construction once, then run domain calling repeatedly:
cellmotif2domain motifwalk \
--cell-table cells.csv \
--output-dir results/motifwalk_L10 \
--walk-length 10 \
--walks-per-cell 100 \
--motif-min-len 3 \
--motif-max-len 5 \
--max-selected-motifs 2000 \
--n-jobs 16 \
--export-csv
cellmotif2domain domaincall \
--motif-dir results/motifwalk_L10 \
--n-domains 8 \
--export-csv
cellmotif2domain domaincall \
--motif-dir results/motifwalk_L10 \
--n-domains 12 \
--export-csv
This is usually faster than rerunning the full workflow for every candidate k.
Python API
from cellmotif2domain import Cellmotif2domain, MotifWalk, DomainCall
from cellmotif2domain import export_cell_by_motif_csv, export_domains_csv
domains = Cellmotif2domain(
"cells.csv",
n_domains=8,
x_col="x",
y_col="y",
celltype_col="cell_type",
sample_col="sample_id",
cell_id_col="cell_id",
output_dir="results/cellmotif2domain_k8",
walk_length=10,
walks_per_cell=100,
motif_min_len=3,
motif_max_len=5,
max_selected_motifs=2000,
enrichment=True,
n_jobs=16,
random_seed=42,
)
export_domains_csv("results/cellmotif2domain_k8", n_domains=8)
export_cell_by_motif_csv("results/cellmotif2domain_k8")
The older internal name SpaMotifDomain is kept as an alias for compatibility, but new analyses should use Cellmotif2domain.
Main Parameters
| Parameter | Default | Meaning |
|---|---|---|
--n-domains |
required | Number of spatial domains to call. |
--walk-length |
10 |
Length of graph-constrained random walks. |
--walks-per-cell |
100 |
Number of seeded walks requested per cell. |
--motif-min-len |
3 |
Minimum cell-type motif length. |
--motif-max-len |
walk_length / 2, capped at 10 |
Maximum motif length. |
--max-selected-motifs |
2000 |
Number of selected motif features used for clustering. |
--enrichment |
true |
Use analytic null-model log2 enrichment instead of raw log2 counts. |
--pca-components |
30 |
PCA dimensions before clustering. |
--n-jobs |
auto | CPU threads for motif counting. |
--save-walks |
off | Save raw walk paths. This can be large. |
Recommended starting point: walk_length=10, walks_per_cell=100, motif_min_len=3, motif_max_len=5, enrichment=true, and max_selected_motifs=2000.
Output Files
For an output directory such as results/cellmotif2domain_k8, the main files are:
| File | Description |
|---|---|
metadata/spatial_cells.tsv.gz |
Cleaned input cell table with encoded cell types. |
outputs/graphs/spatial_delaunay_neighbors.npy |
Delaunay graph neighbor array. |
outputs/graphs/spatial_delaunay_graph_summary.tsv |
Per-sample graph summary. |
outputs/motifs/motif_counts_L*_L*.tsv.gz |
Global candidate motif counts. |
outputs/motifs/selected_motif_features.tsv |
Selected motifs with motif sequence and count/prevalence metadata. |
outputs/motifs/selected_motif_analytic_background.tsv |
Observed/expected motif counts under the analytic null model. |
outputs/features/cell_selected_motif_counts.npz |
Sparse cell-by-motif count matrix. |
outputs/features/cell_selected_motif_log2_enrichment.npz |
Sparse cell-by-motif log2 enrichment matrix. |
outputs/features/cell_by_motif_matrix.csv.gz |
CSV export of the selected cell-by-motif matrix when --export-csv is used. |
outputs/domains/cellmotif2domain_domains_k*.tsv.gz |
Domain assignments per cell. |
outputs/domains/cellmotif2domain_domains_k*.csv.gz |
CSV export of domain assignments when --export-csv is used. |
outputs/figures/cellmotif2domain_smoothed_domain_k*.pdf |
Spatial domain map as editable PDF. |
The domain table contains:
| Column | Meaning |
|---|---|
cell_id, sample_id, x, y, cell_type |
Cell metadata. |
cellmotif2domain_raw |
Cluster label before spatial smoothing. |
cellmotif2domain_smoothed |
Cluster label after one round of Delaunay-neighbor majority smoothing. |
The cell-by-motif CSV uses columns named like:
motif_0001|B_cell-T_cell-Macrophage
Values are log2 enrichment scores when --enrichment true is used. A value above 0 means the motif is enriched relative to the sample-specific null expectation.
Algorithm Summary
- Build a Delaunay triangulation graph independently for each
sample_id. - Start graph-constrained self-avoiding random walks from each cell.
- Extract cell-type motif windows from each walk.
- Canonicalize motif direction so a motif and its reverse are treated as the same motif.
- Count motifs at the cell level.
- Estimate expected motif counts from sample-wise cell-type frequencies.
- Compute a sparse cell-by-motif log2 enrichment matrix.
- Reduce the motif matrix by PCA.
- Cluster cells with diagonal Gaussian mixture modeling and apply one round of spatial smoothing.
GitHub Release Checklist
Before pushing this package to GitHub, keep raw data and large outputs out of the repository:
cd cellmotif2domain
git init
git add .
git commit -m "Initial release of Cellmotif2domain"
git branch -M main
git remote add origin git@github.com:YOUR_USERNAME/cellmotif2domain.git
git push -u origin main
Do not commit patient-level raw data, large matrices, private logs, tokens, or local result folders.
PyPI Packaging
Build a source distribution and wheel:
cd cellmotif2domain
python -m pip install build twine
python -m build
python -m twine check dist/*
Upload to TestPyPI first:
python -m twine upload --repository testpypi dist/*
Then install-test in a clean environment:
pip install -i https://test.pypi.org/simple/ cellmotif2domain
GitHub and PyPI use tokens or SSH keys; do not enter or share your GitHub password in scripts.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cellmotif2domain-0.1.0.tar.gz.
File metadata
- Download URL: cellmotif2domain-0.1.0.tar.gz
- Upload date:
- Size: 25.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54641ef23080a41ee3fcc04396061497800280943c73fae14c89708ffae0707e
|
|
| MD5 |
984297e86fb52f3f1de0cd99d885669e
|
|
| BLAKE2b-256 |
85506a169f4af24a2246cd103a79bff532af626e5e8c26f426db6d3a8623e9c9
|
File details
Details for the file cellmotif2domain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cellmotif2domain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
450370e1c2bf9269d18422a7557276d985281639f09dd3454572ba7999fc4ebd
|
|
| MD5 |
00b2f6fb9138b0c90407bfed78a58a11
|
|
| BLAKE2b-256 |
b700475276907f39f2c7b1cc01ba90921acaec495ec85e2a1bc20fe18ad0f533
|