3D Reconstruction¶
ST-GEARS is a strong 3D reconstruction tool for Spatial Transcriptomics, with accurate position alignment plus distortion correction [Xia23].
ST-GEARS consists of methods to compute anchors, to align rigidly and to registrate sections elastically:
st_gearsthe main method which computes mappings between adjacent sections in serial, using Fused-Gromov Wasserstein Optimal Transport with our innovatie Distributive Constraints.stack_slices_pairwise_rigidrigidly aligns sections using Procrustes Analysis.stack_slices_pairwise_elas_fieldeliminates distorsions through Gaussian Smoothed Elastic Fields. Validity is proved mathematically.
Note
In order to run on GPU, Torch is necessary:
GPU(CUDA11): pip install torch==2.4.1+cu118 --extra-index-url https://download.pytorch.org/whl/
GPU(CUDA12): pip install torch==2.4.1+cu124 --extra-index-url https://download.pytorch.org/whl/
[1]:
import stereo as st
from stereo.core.ms_data import MSData
from natsort import natsorted
from glob import glob
Reading Data¶
Download our example data
[2]:
data_dir = '../data/mouse_brain/'
files_list = natsorted(glob(f'{data_dir}/*.h5ad'))
data_list = [st.io.read_h5ad(path) for path in files_list]
ms_data = MSData(_data_list=data_list)
ms_data
[2]:
ms_data: {'0': (805, 114), '1': (1051, 114), '2': (1188, 114), '3': (1206, 114), '4': (1448, 114), '5': (1487, 114), '6': (1584, 114), '7': (1652, 114), '8': (1748, 114), '9': (1766, 114), '10': (1649, 114), '11': (1667, 114), '12': (1783, 114), '13': (1730, 114), '14': (1810, 114), '15': (1812, 114), '16': (1680, 114), '17': (1692, 114), '18': (1586, 114), '19': (1634, 114), '20': (1604, 114), '21': (1531, 114), '22': (1527, 114), '23': (1676, 114), '24': (1399, 114), '25': (1388, 114), '26': (1221, 114), '27': (1149, 114), '28': (1163, 114), '29': (1172, 114), '30': (1023, 114), '31': (943, 114), '32': (847, 114), '33': (754, 114), '34': (751, 114), '35': (620, 114), '36': (629, 114), '37': (594, 114), '38': (509, 114), '39': (441, 114)}
num_slice: 40
names: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39']
obs: []
var: []
relationship: other
var_type: intersect to 0
mss: []
Showing the spatial distribution of cells type.¶
Here we take sample 8 to sample 11 as example.
We can see the last two samples are not aligned with the first two.
[3]:
ms_data[8:12].plt.ms_spatial_scatter(
color_by='cluster',
color_key='annotation',
ncols=2
)
[3]:
Running ST-Gears¶
start_i and end_i specify computing scope of samples, here means to compute sample 8 to sample 11.
For more details refer to ms_data.tl.st_gears.
[4]:
st_gears_ins = ms_data.tl.st_gears(
cluster_res_key='annotation',
start_i=8,
end_i=11,
tune_alpha_li=[0.8, 0.4, 0.2, 0.1, 0.05, 0.025, 0.013, 0.006],
numItermax=200,
dissimilarity_val='kl',
dissimilarity_weight_val='kl',
uniform_weight=True,
map_method_dis2wei='logistic',
filter_by_label=True,
use_gpu=False, # set to True to run on GPU
verbose=False
)
2024-05-21 17:22:29.602807: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /root/miniforge3/envs/stereopy/lib/python3.8/site-packages/cv2/../../lib64:
2024-05-21 17:22:29.602850: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2024-05-21 17:22:30.396780: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /root/miniforge3/envs/stereopy/lib/python3.8/site-packages/cv2/../../lib64:
2024-05-21 17:22:30.396820: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2024-05-21 17:22:30.396834: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (RCNSZOR29440A): /proc/driver/nvidia/version does not exist
2024-05-21 17:22:30.397043: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
/root/miniforge3/envs/stereopy/lib/python3.8/site-packages/ot/backend.py:2998: UserWarning: To use TensorflowBackend, you need to activate the tensorflow numpy API. You can activate it by running:
from tensorflow.python.ops.numpy_ops import np_config
np_config.enable_numpy_behavior()
register_backend(TensorflowBackend())
[2024-05-21 17:22:31][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[0]: 0.8
[2024-05-21 17:23:06][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.513073899588928
[2024-05-21 17:23:07][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[1]: 0.4
[2024-05-21 17:23:38][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5130738989987577
[2024-05-21 17:23:38][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[2]: 0.1
[2024-05-21 17:24:21][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5126084470579434
[2024-05-21 17:24:21][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[3]: 0.2
[2024-05-21 17:25:01][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5126084470579434
[2024-05-21 17:25:01][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[4]: 0.05
[2024-05-21 17:25:42][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5126084470579434
[2024-05-21 17:25:42][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[5]: 0.013
[2024-05-21 17:26:12][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5130738995805775
[2024-05-21 17:26:12][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[6]: 0.025
[2024-05-21 17:26:43][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.513073899588928
[2024-05-21 17:26:43][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 8, tune_alpha[7]: 0.006
[2024-05-21 17:27:07][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5130524923003253
[2024-05-21 17:27:07][Stereo][208994][MainThread][140512358360896][regis][381][INFO]: type_score_best: 0.513073899588928
[2024-05-21 17:27:07][Stereo][208994][MainThread][140512358360896][regis][386][INFO]: alpha_best: 0.8
[2024-05-21 17:27:07][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[0]: 0.8
[2024-05-21 17:28:31][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.2414243316366492
[2024-05-21 17:28:31][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[1]: 0.4
[2024-05-21 17:28:54][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.45907093574387764
[2024-05-21 17:28:54][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[2]: 0.1
[2024-05-21 17:29:16][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.4593077244256847
[2024-05-21 17:29:16][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[3]: 0.2
[2024-05-21 17:29:32][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.45907093574387764
[2024-05-21 17:29:32][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[4]: 0.05
[2024-05-21 17:30:00][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.4593077244332003
[2024-05-21 17:30:00][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[5]: 0.013
[2024-05-21 17:30:32][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.45930772443320084
[2024-05-21 17:30:32][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[6]: 0.025
[2024-05-21 17:31:08][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.45930772443320084
[2024-05-21 17:31:08][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 9, tune_alpha[7]: 0.006
[2024-05-21 17:31:36][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.45930772443233686
[2024-05-21 17:31:37][Stereo][208994][MainThread][140512358360896][regis][381][INFO]: type_score_best: 0.45930772443320084
[2024-05-21 17:31:37][Stereo][208994][MainThread][140512358360896][regis][386][INFO]: alpha_best: 0.013
[2024-05-21 17:31:37][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[0]: 0.8
[2024-05-21 17:32:17][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5053710730365645
[2024-05-21 17:32:18][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[1]: 0.4
[2024-05-21 17:32:52][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5053710730365645
[2024-05-21 17:32:52][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[2]: 0.1
[2024-05-21 17:33:11][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5135360723816852
[2024-05-21 17:33:12][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[3]: 0.2
[2024-05-21 17:33:38][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5053710730365645
[2024-05-21 17:33:38][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[4]: 0.05
[2024-05-21 17:33:59][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5135360723818474
[2024-05-21 17:33:59][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[5]: 0.013
[2024-05-21 17:34:23][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5135360723816823
[2024-05-21 17:34:23][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[6]: 0.025
[2024-05-21 17:34:49][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5135360723816794
[2024-05-21 17:34:49][Stereo][208994][MainThread][140512358360896][regis][308][INFO]: slice: 10, tune_alpha[7]: 0.006
[2024-05-21 17:35:07][Stereo][208994][MainThread][140512358360896][regis][320][INFO]: type score: 0.5135279752455112
[2024-05-21 17:35:07][Stereo][208994][MainThread][140512358360896][regis][381][INFO]: type_score_best: 0.5135360723818474
[2024-05-21 17:35:07][Stereo][208994][MainThread][140512358360896][regis][386][INFO]: alpha_best: 0.05
Rigidly aligning sections using Procrustes Analysis.¶
Setting set_as_position as True to use the rigidly aligned coordinates as the cells/bins position.
For more details refer to st_gears_ins.stack_slices_pairwise_rigid.
[5]:
st_gears_ins.stack_slices_pairwise_rigid(set_as_position=True)
Showing the spatial distribution of cells type after aligning.¶
We can see the last two samples have been aligned with the first two.
[6]:
ms_data[8:12].plt.ms_spatial_scatter(
color_by='cluster',
color_key='annotation',
ncols=2
)
[6]:
Eliminating distorsions through Gaussian Smoothed Elastic Fields¶
This method attempts to restore the shape of tissues.
Setting set_as_position as True to use the coordinates eliminated distorsions as the cells/bins position.
For more details refer to st_gears_ins.stack_slices_pairwise_elas_field.
This method can not be ran without running method stack_slices_pairwise_rigid.
[7]:
st_gears_ins.stack_slices_pairwise_elas_field(pixel_size=200, set_as_position=True)
Showing the spatial distribution of cells type after eliminating distorsions.¶
[8]:
ms_data[8:12].plt.ms_spatial_scatter(
color_by='cluster',
color_key='annotation',
ncols=2
)
[8]: