diff --git a/src/methods/scbsp/config.vsh.yaml b/src/methods/scbsp/config.vsh.yaml new file mode 100644 index 0000000..2f8b325 --- /dev/null +++ b/src/methods/scbsp/config.vsh.yaml @@ -0,0 +1,44 @@ +__merge__: ../../api/comp_method.yaml +name: scbsp +label: scBSP +summary: scBSP identifies spatially variable genes via granularity-based spatial statistics. +description: | + scBSP (single-cell BinSpect) detects spatially variable genes using a + granularity-based approach that tests for spatial patterns at multiple + resolutions. It bins spatial coordinates into grids at different + granularity levels and tests whether gene expression shows significant + spatial structure using a permutation-based statistical test. The method + is designed for large-scale spatial transcriptomics data. +references: + bibtex: + - | + @article{li2024scbsp, + title={scBSP: A fast and accurate tool for identifying spatially variable + genes from spatial transcriptomic data}, + author={Li, Jinpu and Shang, Yiqing and others}, + journal={Bioinformatics}, + year={2024} + } +info: + preferred_normalization: counts +links: + repository: https://github.com/juexinwang/scBSP +resources: + - type: python_script + path: script.py +engines: + - type: docker + image: openproblems/base_python:1.0.0 + setup: + - type: python + packages: + - pandas + - numpy + - scipy + - anndata + - scbsp +runners: + - type: executable + - type: nextflow + directives: + label: [midtime, highmem, lowcpu] diff --git a/src/methods/scbsp/script.py b/src/methods/scbsp/script.py new file mode 100644 index 0000000..c4e9fca --- /dev/null +++ b/src/methods/scbsp/script.py @@ -0,0 +1,55 @@ +import warnings +warnings.filterwarnings('ignore') + +import anndata as ad +import numpy as np +import pandas as pd + +# VIASH START +par = { + 'input_data': 'resources_test/task_spatially_variable_genes/mouse_brain_coronal/dataset.h5ad', + 'output': 'output.h5ad' +} +meta = { + 'name': 'scbsp' +} +# VIASH END + +print('Load data', flush=True) +adata = ad.read_h5ad(par['input_data']) + +print('Run scBSP', flush=True) +from scbsp import granp + +coords = adata.obsm['spatial'] +X = adata.layers['counts'] + +if hasattr(X, 'toarray'): + X_dense = X.toarray() +else: + X_dense = np.asarray(X) + +result_df = granp( + np.ascontiguousarray(coords, dtype=np.float64), + np.ascontiguousarray(X_dense, dtype=np.float64), +) + +# granp returns DataFrame with columns: gene_names, p_values +pvals = result_df['p_values'].values +scores = -np.log10(np.clip(pvals, 1e-300, 1)) + +df = pd.DataFrame({ + 'feature_id': list(adata.var_names), + 'pred_spatial_var_score': scores +}) + +output = ad.AnnData( + var=df, + uns={ + 'dataset_id': adata.uns['dataset_id'], + 'method_id': meta['name'] + } +) + +print('Write output to file', flush=True) +output.write_h5ad(par['output'])