{ "cells": [ { "cell_type": "markdown", "id": "71b1d70e", "metadata": {}, "source": [ "### Human Thymus Multimodal Deconvolution\n", "\n", "This tutorial demonstrates multimodal deconvolution on simulated human thymus spatial data derived from a single-cell multiomic (CITE-seq) dataset with paired RNA and protein (ADT) measurements.\n", "\n", "The single-cell multiomic dataset contains 11 batches, which are paired to form 11 batch-pair datasets. Within each pair, one batch is used as the reference and the other is used to simulate spatial data. The simulation scheme follows the idea described in *[Spatial transcriptomics deconvolution methods generalize well to spatial chromatin accessibility data](https://academic.oup.com/bioinformatics/article/41/Supplement_1/i314/8199385)*. \n", "\n", "Datasets are available on [Zenodo](https://zenodo.org/records/19691472).\n" ] }, { "cell_type": "code", "execution_count": null, "id": "0ad9a20d", "metadata": {}, "outputs": [], "source": [ "import muon as mu\n", "import os\n", "from os.path import join\n", "import scanpy as sc\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import glob\n", "\n", "import sparank\n", "from sparank.config import ExpConfig, ModalityConfig, SimulationConfig\n", "from sparank.framework import SpaRank" ] }, { "cell_type": "code", "execution_count": 2, "id": "e6416d14", "metadata": {}, "outputs": [], "source": [ "data_dir = '../data/human_thymus/simulated'\n", "batch_pairs = pd.read_csv(f'{data_dir}/batch_pairs.csv')" ] }, { "cell_type": "markdown", "id": "96527998", "metadata": {}, "source": [ "#### Training\n", "\n", "The cell below shows the training configuration used in our experiments. It is commented out by default, so you only need to run it if you want to reproduce the models from scratch.\n", "\n", "A few settings are worth noting:\n", "\n", "- `modalities=[ModalityConfig(name=\"rna\", ...), ModalityConfig(name=\"adt\", ...)]`: specific configurations for RNA and protein modalities.\n", "- `context_key=None`: no context conditioning is used." ] }, { "cell_type": "code", "execution_count": 3, "id": "35a3be6c", "metadata": { "scrolled": true }, "outputs": [], "source": [ "# for (spot_batch, cell_batch) in zip(batch_pairs.spot, batch_pairs.cell):\n", "# pair_id = f'{spot_batch}-{cell_batch}'\n", "\n", "# mdata_ref = mu.read_h5mu(\n", "# glob.glob(join(data_dir, f'{cell_batch}-*', \"ref_data.h5mu\"))[0]\n", "# )\n", "# adx_sc_rna = mdata_ref.mod['rna']\n", "# adx_sc_adt = mdata_ref.mod['adt']\n", "\n", "# adx_sc_rna.var_names_make_unique()\n", "# adx_sc_adt.var_names_make_unique()\n", "\n", "# cfg = ExpConfig(\n", "# modalities=[\n", "# ModalityConfig(name=\"rna\", top_k=500, cl_dropout_rate=0.3, mrp_mask_rate=0.3),\n", "# ModalityConfig(name=\"adt\", top_k=500, cl_dropout_rate=0.3, mrp_mask_rate=0.3) # top_k will subset to the actual protein panel\n", "# ],\n", "# simulation=SimulationConfig(\n", "# total_samples=500_000, \n", "# batch_request_size=100_000,\n", "# batch_key='sample',\n", "# ),\n", "# celltype_key='annotation',\n", "# batch_key='sample',\n", "# context_key=None,\n", "# dim=128,\n", "# depth=2,\n", "# heads=4,\n", "# cl_weight=0.5,\n", "# cl_temperature=0.1,\n", "# mrp_weight=0.5,\n", "# cls_weight=1.0,\n", "# epochs=20,\n", "# num_workers=0\n", "# )\n", " \n", "# model = SpaRank(cfg=cfg, save_dir=f'../outputs/human_thymus/{pair_id}')\n", "# model.register_modality(\"rna\", adx_sc_rna)\n", "# model.register_modality(\"adt\", adx_sc_adt)\n", "# model.prepare() # use sp gene panel as a prior\n", "# model.fit() # train\n", "# model.save()\n", "\n", "# break" ] }, { "cell_type": "markdown", "id": "ccfe317d", "metadata": {}, "source": [ "#### Evaluation\n", "\n", "After training, we load the checkpoint and apply it to the corresponding simulated spatial sections. The predicted cell-type proportions are then compared against the ground truth from simulation.\n", "\n", "We report Jensen–Shannon divergence and Pearson correlation scores to assess deconvolution performance. We also track modality gate scores to examine how the model balances RNA and ADT signals." ] }, { "cell_type": "code", "execution_count": 4, "id": "a5d22529", "metadata": {}, "outputs": [], "source": [ "from typing import Union\n", "\n", "import numpy as np\n", "import pandas as pd\n", "from scipy.spatial.distance import jensenshannon\n", "from scipy.stats import pearsonr\n", "\n", "def _to_array(x):\n", " return x.values if isinstance(x, pd.DataFrame) else np.asarray(x)\n", "\n", "def jsd(true: Union[pd.DataFrame, np.ndarray], predicted: Union[pd.DataFrame, np.ndarray]) -> float:\n", " jsd_vals = jsd_per_col(true, predicted)\n", " return np.nanmean(jsd_vals)\n", "\n", "def jsd_per_col(true: Union[pd.DataFrame, np.ndarray], predicted: Union[pd.DataFrame, np.ndarray]) -> np.ndarray:\n", " t = _to_array(true)\n", " p = _to_array(predicted)\n", "\n", " n_cols = t.shape[1]\n", " vals = np.full(n_cols, np.nan, dtype=float)\n", " for i in range(n_cols):\n", " a = t[:, i].astype(float)\n", " b = p[:, i].astype(float)\n", " sa = a.sum()\n", " sb = b.sum()\n", " if sa == 0 or sb == 0:\n", " vals[i] = np.nan\n", " continue\n", " pa = a / sa\n", " pb = b / sb\n", " vals[i] = float(jensenshannon(pa, pb, axis=0, base=2))\n", " return vals\n", "\n", "\n", "def pcc(true: Union[pd.DataFrame, np.ndarray], predicted: Union[pd.DataFrame, np.ndarray]) -> float:\n", " r_vals = pcc_per_col(true, predicted)\n", " return float(np.nanmean(r_vals))\n", "\n", "\n", "def pcc_per_col(true: Union[pd.DataFrame, np.ndarray], predicted: Union[pd.DataFrame, np.ndarray]) -> np.ndarray:\n", " t = _to_array(true)\n", " p = _to_array(predicted)\n", "\n", " n_cols = t.shape[1]\n", " vals = np.full(n_cols, np.nan, dtype=float)\n", " for i in range(n_cols):\n", " x = t[:, i]\n", " y = p[:, i]\n", " if np.std(x) == 0 or np.std(y) == 0:\n", " vals[i] = np.nan\n", " continue\n", " vals[i], _ = pearsonr(x, y)\n", " return vals\n", "\n", "\n", "def eval_pred(targets, pred):\n", " \n", " jsd_mean_row = jsd(targets.T, pred.T) # by row\n", " pcc_mean_row = pcc(targets.T, pred.T)\n", " jsd_mean_col = jsd(targets, pred) # by row\n", " pcc_mean_col = pcc(targets, pred)\n", "\n", " d = {\n", " 'jsd-mean-row': jsd_mean_row,\n", " 'pcc-mean-row': pcc_mean_row,\n", " 'jsd-mean-col': jsd_mean_col,\n", " 'pcc-mean-col': pcc_mean_col,\n", " }\n", " return d" ] }, { "cell_type": "markdown", "id": "47ab8d0a", "metadata": {}, "source": [ "##### Metrics" ] }, { "cell_type": "code", "execution_count": 5, "id": "72e409c5", "metadata": { "scrolled": true }, "outputs": [], "source": [ "import torch\n", "\n", "rs = []\n", "gate_scores = {}\n", "for (spot_batch, cell_batch) in zip(batch_pairs.spot, batch_pairs.cell):\n", " pair_id = f'{spot_batch}-{cell_batch}'\n", "\n", " model = SpaRank.load(f'../outputs/human_thymus/{pair_id}', device=\"cuda:0\")\n", " mdata_sp = mu.read_h5mu(\n", " glob.glob(join(data_dir, f'{spot_batch}-*', \"sp_data.h5mu\"))[0]\n", " )\n", "\n", " adx_sp_rna = mdata_sp.mod['rna']\n", " adx_sp_adt = mdata_sp.mod['adt']\n", "\n", " adx_sp_rna.var_names_make_unique()\n", " adx_sp_adt.var_names_make_unique()\n", "\n", " gate_scores[pair_id] = []\n", " for ep in np.arange(model.cfg.epochs):\n", " ckpt = join(model.save_dir, f\"model_epoch{ep+1}.pth\")\n", " model.model.load_state_dict(torch.load(ckpt, map_location=model.device))\n", " \n", " preds, gates = model.predict(mod_adatas={'rna':adx_sp_rna, 'adt':adx_sp_adt}, return_gate_scores=True)\n", " df_true = pd.DataFrame(adx_sp_rna.obsm['proportions'], \n", " columns=adx_sp_rna.uns['proportion_names']).copy()\n", " df_pred = preds.reindex(columns=df_true.columns, fill_value=0)\n", " \n", " df_true = df_true.div(df_true.sum(axis=1), axis=0) \n", " df_pred = df_pred.div(df_pred.sum(axis=1), axis=0)\n", " rna_r = eval_pred(df_true, df_pred)\n", " rna_r['dataset'] = pair_id\n", " rna_r['ep'] = ep + 1\n", " \n", " # print(ep, rna_r)\n", " rs.append(rna_r)\n", " gate_scores[pair_id].append(gates.mean(axis=0)[0])\n", "\n", " break" ] }, { "cell_type": "code", "execution_count": 6, "id": "02e4c58f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
jsd-mean-rowpcc-mean-rowjsd-mean-colpcc-mean-coldatasetep
00.6209660.4224340.5479960.498087TT-CITE-1-TT-CITE-51
10.5857040.5066160.5388010.522315TT-CITE-1-TT-CITE-52
20.5425830.5952070.5243910.572617TT-CITE-1-TT-CITE-53
30.5309530.6169060.5135160.593068TT-CITE-1-TT-CITE-54
40.5214240.6306980.5063100.619039TT-CITE-1-TT-CITE-55
50.5087180.6423020.5010770.636270TT-CITE-1-TT-CITE-56
60.5076210.6425060.4947380.651287TT-CITE-1-TT-CITE-57
70.5214340.6143700.4966800.651511TT-CITE-1-TT-CITE-58
80.5119700.6184440.4887710.661643TT-CITE-1-TT-CITE-59
90.4959570.6493750.4848110.663655TT-CITE-1-TT-CITE-510
100.5052680.6310400.4848660.667103TT-CITE-1-TT-CITE-511
110.4978750.6399520.4841470.666498TT-CITE-1-TT-CITE-512
120.5153480.6063590.4940600.645583TT-CITE-1-TT-CITE-513
130.5079420.6308880.4877540.666721TT-CITE-1-TT-CITE-514
140.4991080.6338210.4842290.662645TT-CITE-1-TT-CITE-515
150.5041560.6232520.4842610.663488TT-CITE-1-TT-CITE-516
160.4984500.6329950.4857910.663203TT-CITE-1-TT-CITE-517
170.4970660.6321110.4849060.657270TT-CITE-1-TT-CITE-518
180.5099160.6160920.4868290.661512TT-CITE-1-TT-CITE-519
190.4972790.6389840.4857620.666644TT-CITE-1-TT-CITE-520
\n", "
" ], "text/plain": [ " jsd-mean-row pcc-mean-row jsd-mean-col pcc-mean-col \\\n", "0 0.620966 0.422434 0.547996 0.498087 \n", "1 0.585704 0.506616 0.538801 0.522315 \n", "2 0.542583 0.595207 0.524391 0.572617 \n", "3 0.530953 0.616906 0.513516 0.593068 \n", "4 0.521424 0.630698 0.506310 0.619039 \n", "5 0.508718 0.642302 0.501077 0.636270 \n", "6 0.507621 0.642506 0.494738 0.651287 \n", "7 0.521434 0.614370 0.496680 0.651511 \n", "8 0.511970 0.618444 0.488771 0.661643 \n", "9 0.495957 0.649375 0.484811 0.663655 \n", "10 0.505268 0.631040 0.484866 0.667103 \n", "11 0.497875 0.639952 0.484147 0.666498 \n", "12 0.515348 0.606359 0.494060 0.645583 \n", "13 0.507942 0.630888 0.487754 0.666721 \n", "14 0.499108 0.633821 0.484229 0.662645 \n", "15 0.504156 0.623252 0.484261 0.663488 \n", "16 0.498450 0.632995 0.485791 0.663203 \n", "17 0.497066 0.632111 0.484906 0.657270 \n", "18 0.509916 0.616092 0.486829 0.661512 \n", "19 0.497279 0.638984 0.485762 0.666644 \n", "\n", " dataset ep \n", "0 TT-CITE-1-TT-CITE-5 1 \n", "1 TT-CITE-1-TT-CITE-5 2 \n", "2 TT-CITE-1-TT-CITE-5 3 \n", "3 TT-CITE-1-TT-CITE-5 4 \n", "4 TT-CITE-1-TT-CITE-5 5 \n", "5 TT-CITE-1-TT-CITE-5 6 \n", "6 TT-CITE-1-TT-CITE-5 7 \n", "7 TT-CITE-1-TT-CITE-5 8 \n", "8 TT-CITE-1-TT-CITE-5 9 \n", "9 TT-CITE-1-TT-CITE-5 10 \n", "10 TT-CITE-1-TT-CITE-5 11 \n", "11 TT-CITE-1-TT-CITE-5 12 \n", "12 TT-CITE-1-TT-CITE-5 13 \n", "13 TT-CITE-1-TT-CITE-5 14 \n", "14 TT-CITE-1-TT-CITE-5 15 \n", "15 TT-CITE-1-TT-CITE-5 16 \n", "16 TT-CITE-1-TT-CITE-5 17 \n", "17 TT-CITE-1-TT-CITE-5 18 \n", "18 TT-CITE-1-TT-CITE-5 19 \n", "19 TT-CITE-1-TT-CITE-5 20 " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_res = pd.DataFrame(rs)\n", "df_res" ] }, { "cell_type": "markdown", "id": "083ff0c1", "metadata": {}, "source": [ "##### Modality ate score\n", "\n", "The plot below shows the average RNA gate score across training epochs for one dataset, illustrating how the model weights the RNA modality during optimization." ] }, { "cell_type": "code", "execution_count": 7, "id": "64bea3f1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0.5, 1.0, 'average gate score of RNA across epochs')" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# pair_id = 'TT-CITE-1-TT-CITE-5'\n", "\n", "plt.plot(gate_scores[pair_id])\n", "plt.title('average gate score of RNA across epochs')" ] }, { "cell_type": "code", "execution_count": null, "id": "1bc4d046-511f-4de0-9a99-aafbf4656088", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python (scvi)", "language": "python", "name": "scvi-env" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.11" } }, "nbformat": 4, "nbformat_minor": 5 }