|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +import numpy as np |
| 4 | +import anndata as ad |
| 5 | +import scanpy as sc |
| 6 | + |
| 7 | +import moscot as mt |
| 8 | +from moscot.problems.space import MappingProblem |
| 9 | + |
| 10 | +## VIASH START |
| 11 | + par = { |
| 12 | + 'input_spatial_normalized_counts': 'resources_test/task_ist_preprocessing/mouse_brain_combined/spatial_normalized_counts.h5ad', |
| 13 | + 'input_scrnaseq_reference': 'resources_test/task_ist_preprocessing/mouse_brain_combined/scrnaseq_reference.h5ad', |
| 14 | + 'output': 'spatial_with_celltypes.h5ad', |
| 15 | + 'celltype_key': 'cell_type', |
| 16 | + 'alpha': 0.8, |
| 17 | + 'epsilon': 0.01, |
| 18 | + 'tau': 1.0, |
| 19 | + 'rank': -1, |
| 20 | + 'mapping_mode': 'max', |
| 21 | + } |
| 22 | + meta = { |
| 23 | + 'name': 'moscot', |
| 24 | + } |
| 25 | + ## VIASH END |
| 26 | + |
| 27 | +# Optional parameter check: For this specific annotation method the par['input_spatial_normalized_counts'] and par['input_scrnaseq_reference'] are required |
| 28 | +assert par['input_spatial_normalized_counts'] is not None, 'Spatial input is required for this annotation method.' |
| 29 | +assert par['input_scrnaseq_reference'] is not None, 'Single cell input is required for this annotation method.' |
| 30 | + |
| 31 | +# Read input |
| 32 | +adata_sc = ad.read_h5ad(par['input_scrnaseq_reference']) |
| 33 | +adata_sp = ad.read_h5ad(par['input_spatial_normalized_counts']) |
| 34 | + |
| 35 | +# Check for normalized layer and centroid information |
| 36 | +assert "normalized" in adata_sc.layers.keys(), 'Layer "normalized" is required for single-cell anndata' |
| 37 | +assert "normalized" in adata_sp.layers.keys(), 'Layer "normalized" is required for spatial anndata' |
| 38 | +assert "centroid_x" in adata_sp.obs and "centroid_y" in adata_sp.obs, '"Observation level columns "centroid_x" and "centroid_y" are required for spatial anndata' |
| 39 | + |
| 40 | +# Use normalized layer and create spatial obsm |
| 41 | +adata_sc.X = adata_sc.layers["normalized"] |
| 42 | +adata_sp.X = adata_sp.layers["normalized"] |
| 43 | +adata_sp.obsm["spatial"] = adata_sp.obs[["centroid_x", "centroid_y"]].to_numpy() |
| 44 | + |
| 45 | +# Define mapping problem |
| 46 | +mp = MappingProblem(adata_sc=adata_sc, adata_sp=adata_sp) |
| 47 | + |
| 48 | +mp = mp.prepare( |
| 49 | + sc_attr={"attr": "layers", "key": "normalized"}, |
| 50 | + xy_callback="local-pca", |
| 51 | +) |
| 52 | + |
| 53 | +mp = mp.solve( |
| 54 | + alpha=par['alpha'], |
| 55 | + epsilon=par['epsilon'], |
| 56 | + tau_a=par['tau'], |
| 57 | + tau_b=par['tau'], |
| 58 | + rank=par['rank'], |
| 59 | +) |
| 60 | + |
| 61 | +# Map annotations |
| 62 | +anno_map_max = mp.annotation_mapping( |
| 63 | + mapping_mode=par['mapping_mode'], |
| 64 | + annotation_label=par['celltype_key'], |
| 65 | + source="src", |
| 66 | + forward=False, |
| 67 | +) |
| 68 | +adata_sp.obs[par['celltype_key']] = anno_map_max[par['celltype_key']].values |
| 69 | + |
| 70 | +# Write output |
| 71 | +adata_sp.write_h5ad(par['output']) |
0 commit comments