Demo 4: STARmap to MERFISH

[2]:
import CAST
import scanpy as sc
import torch,os
import numpy as np

workdir = '$demo_path' #### input the demo path

This demo showcases an example workflow aligning a STARmap sample to a MERFISH sample using CAST Mark and CAST Stack.

Load / Prepare Data

[3]:
###  Load and plot the data

from CAST.visualize import plot_mid


# Output directory for the results
output_path = f'{workdir}/demo4_STARmap_to_MERFISH/demo_output'
os.makedirs(output_path,exist_ok=True)

# Loading the data
sdata = sc.read_h5ad(f'{workdir}/demo4_STARmap_to_MERFISH/data/STARmap_vs_MERFISH.h5ad')
sample_list= ['STARmap','MERFISH']
batch_key = 'batch'
coords_t = np.array(sdata.obs[['center_x', 'center_y']])

# Plotting the initial data
CAST.plot_mid(coords_t[sdata.obs[batch_key] == sample_list[0]],
         coords_t[sdata.obs[batch_key] == sample_list[1]],
         output_path=output_path,
         filename = 'Align_raw',
         title_t = [sample_list[1],
                    sample_list[0]],
         s_t = 8,scale_bar_t = None)
../_images/notebooks_demo4_STARmap_to_MERFISH_4_0.png
[4]:
### Extract expression and coordinates and save the data

from CAST.utils import extract_coords_exp, sub_data_extract


# Extract the coordinates and expression data
coords_raw,exps = CAST.extract_coords_exp(sdata, batch_key = 'batch', cols = ['center_x', 'center_y'], count_layer = '.X', data_format = 'norm1e4')
coords_sub,exp_sub,sub_node_idxs = CAST.sub_data_extract(sample_list,coords_raw, exps, nodenum_t = 20000)

# Save the data
torch.save(coords_raw, f'{output_path}/coords_raw.pt')
torch.save(sub_node_idxs, f'{output_path}/sub_node_idxs.pt')
torch.save(exp_sub, f'{output_path}/exp_sub.pt')
torch.save(coords_sub, f'{output_path}/coords_sub.pt')
Preprocessing...
/home/unix/panj/miniconda3/envs/cast_dev_nonrelease_cast/lib/python3.9/site-packages/scanpy/preprocessing/_normalization.py:197: UserWarning: Some cells have zero counts
  warn(UserWarning('Some cells have zero counts'))

CAST Mark

[5]:
### Run CAST Mark and plot the results

from CAST import CAST_MARK
from CAST.visualize import kmeans_plot_multiple


embed_dict = CAST_MARK(coords_sub,exp_sub,output_path,graph_strategy='delaunay')
kmeans_plot_multiple(embed_dict,sample_list,coords_sub,'demo1',output_path,k=20,dot_size = 10,minibatch=True)
Constructing delaunay graphs for 2 samples...
Training on cuda:0...
Loss: -435.040 step time=0.189s: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [01:17<00:00,  5.15it/s]
Finished.
The embedding, log, model files were saved to /home/unix/panj/wanglab/jessica/CAST/demo/demo4_STARmap_to_MERFISH/demo_output
Perform KMeans clustering on 40000 cells...
Plotting the KMeans clustering results...
[5]:
array([18, 11,  1, ..., 10,  2, 19], dtype=int32)
../_images/notebooks_demo4_STARmap_to_MERFISH_7_4.png
../_images/notebooks_demo4_STARmap_to_MERFISH_7_5.png
../_images/notebooks_demo4_STARmap_to_MERFISH_7_6.png

CAST Stack

[6]:
### Run CAST Stack - Align the two samples

from CAST import CAST_STACK
from CAST.CAST_Stack import reg_params


# Set up parameters
query_sample = sample_list[0]
params_dist = CAST.reg_params(dataname = query_sample,
                            gpu = 0 if torch.cuda.is_available() else -1,
                            #### Affine parameters
                            iterations=150,
                            dist_penalty1=0,
                            bleeding=500,
                            d_list = [3,2,1,1/2,1/3],
                            attention_params = [None,3,1,0],
                            #### FFD parameters
                            dist_penalty2 = [0],
                            alpha_basis_bs = [500],
                            meshsize = [8],
                            iterations_bs = [40],
                            attention_params_bs = [[None,3,1,0]],
                            mesh_weight = [None])
params_dist.alpha_basis = torch.Tensor([1/1000,1/1000,1/50,5,5]).reshape(5,1).to(params_dist.device)

# Run CAST Stack
coord_final = CAST.CAST_STACK(coords_raw,embed_dict,output_path,sample_list,params_dist,sub_node_idxs = sub_node_idxs, rescale=True) # v3.0
Loss: 3801.573: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 150/150 [00:22<00:00,  6.67it/s]
/home/unix/panj/miniconda3/envs/cast_dev_nonrelease_cast/lib/python3.9/site-packages/torch/functional.py:568: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at  /opt/conda/conda-bld/pytorch_1646756402876/work/aten/src/ATen/native/TensorShape.cpp:2228.)
  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]
Loss: 2705.461: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 40/40 [00:07<00:00,  5.31it/s]
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 40/40 [00:00<00:00, 168.28it/s]
../_images/notebooks_demo4_STARmap_to_MERFISH_9_1.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_2.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_3.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_4.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_5.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_6.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_7.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_8.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_9.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_10.png
../_images/notebooks_demo4_STARmap_to_MERFISH_9_11.png

Visualize Results

[7]:
### Plot the kmeans clustering of the final results

from CAST.visualize import kmeans_plot_multiple


# load the final coordinates
coord_final = torch.load(f'{output_path}/STARmap_align_to_MERFISH_coords_final.data')

# Load the embed dict and sub node indexes
sample_list= ['STARmap','MERFISH']
embed_dict = torch.load(f'{output_path}/demo_embed_dict.pt',map_location='cpu')
sub_node_idxs = torch.load(f'{output_path}/sub_node_idxs.pt')

# Extract the sub coordinates
coords_sub_new = dict()
for sample_t in sample_list:
    coords_sub_new[sample_t] = coord_final[sample_t][sub_node_idxs[sample_t],:]

# Plot the final results
kmeans_plot_multiple(embed_dict,sample_list,coords_sub_new,'demo1_new',output_path,k=20,dot_size = 10,minibatch=True,plot_strategy='stack')
Perform KMeans clustering on 40000 cells...
Plotting the KMeans clustering results...
[7]:
array([18, 11,  1, ..., 10,  2, 19], dtype=int32)
../_images/notebooks_demo4_STARmap_to_MERFISH_11_2.png