Our models are trained with nvidia GPUs. To run on GPUs appropiate CUDA versions must be installed. Installing via conda can result in cuda version mismatches or in the installation of CPU versions. Appropiate versions can be found here.
Setup via Anaconda environment:
conda install -c anaconda python=3.11.5
pip install torch -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install torch-geometric -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install torch-cluster -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install torchvision -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install squidpy
pip install decoupler
#pip install imctools
The following data is required to start training:
ln -s /path/to/images/*.tiff data/raw/{EXPERIMENT NAME}/[train/test]. [train/test] are folders in which to split the data, data in train/ is used for training and validation, data in test/ is used for testing.data/raw/{EXPERIMENT NAME}/. The csv contains Cellpostion information of all images. It consists out of the following columns with these exact names: The first column is named Image and contains the name of the images, e.g. CRC03.ome.tif. The second and third column should be named Centroid.X.px and Centroid.Y.px, which contain Cell positions in pixel(!) values. We expect coordinates to start at (0,0) at the upper left corner of each corresponding image. The 4th column should be named Class and contains Celltype information, if existing. This can also be empty. Every column after this is optional, and represents count data of the cells. This can be used to create smaller areas of the image to train on. This is only useful when already spatialomics count data for cells exists(e.g. to investigate model performace). This can be normalized counts, but do not use log normalized counts.data/raw/. The csv contains information of the overall count data for an image. It consists out of the following columns: The first column is named ROI and contains the name of the image, minus everything after the first .(CRC02.ome.tif->CRC02). The second column is named Patient_ID and contains some ID to which the Image corresponds. Every column after this is interpreted as Count data. Each entry has the whole count data of the whole Image. This can be normalized counts, but o not use log normalized counts.Now we are ready to go!
The first process is to normalize Image data and uniformly cut out Cells:
python -m cellcontrast --image_preprocess --preprocess_dir 'data/raw/{EXPERIMENT NAME}/[train/test]/' --cell_cutout 34 --preprocess_workers 26 --preprocess_channels 0,10,14,19 --calc_mean_std
--image_preprocess:--preprocess_dir:{measurements}.csv in direct parent directory.--cell_cutout:--preprocess_workers:--preprocess_channels:
Channels to preprocess. If not specified use all Channels. Seperate Channel indicies, starting from 0, with commas.--calc_mean_stdr:mean.npy and std.npy in direct parent directory of --preprocess_dir.Preprocessing produces files for each Image: {IMAGE NAME}_cells.npy in the shape of (Number of Cells, Channels, --cell_cutout, --cell_cutout).
--deterministic:--seed:--root_dir:data/.--raw_subset_dir:--batch_size:--epochs:--num_workers:--lr:--weight_decay:--early_stopping:--output_name:Next, we learn Visual Representations of Cells via Contrastive learning:
python -m cellcontrast --train_image_model --embed_image_data --output_name 'out/models/image_contrast_model.pt' --raw_subset_dir '{EXPERIMENT NAME}' --weight_decay 1e-6 --resnet_model '18' --batch_size 4096 --epochs 100 --warmup_epochs 10 --num_workers 25 --lr 0.1 --embed 32 --contrast 16 --crop_factor 0.2 --n_clusters_image 20
--train_image_model:--embed_image_data:--resnet_model:'18'.--embed:--contrast:--crop_factor:--n_clusters_image:We extract visual representations after training a model to learn visual representations. Embedding produces files for each {IMAGE NAME}_cells.npy in the same directory: {IMAGE NAME}_cells_embed.pt in the shape of (Number of Cells, --embed.
Next, we learn what each Cell contributes to the Count Data of an Image:
python -m cellprediction --train_gnn --embed_gnn_data --output_name 'out/models/image_graph_model.pt' --output_graph_embed '/out/graph_model/' --init_image_model 'out/models/image_contrast_model.pt' --init_graph_model 'out/models/graph_model.pt' --root_dir 'data/' --raw_subset_dir '{EXPERIMENT NAME}' --label_data '{label}.csv' --batch_size 64 --epochsh 1000 --num_workers 12 --lr 0.005 --early_stopping 50 --weight_decay 1e-4 --train_ratio 0.6 --val_ratio 0.2 --node_dropout 0.0 --edge_dropout 0.3 --cell_pos_jitter 40 --cell_n_knn 6 --subgraphs_per_graph 0 --num_hops_subgraph 0 --model_type 'Image2Count' --data_use_log_graph --graph_mse_mult 1 --graph_cos_sim_mult 1 --lin_layers 3 --gat_layers 3 --num_node_features 32 --num_edge_features 1 --num_embed_features 128 --heads 4 --embed_dropout 0.1 --conv_dropout 0.1 --num_cfolds 0
--train_gnn:--embed_gnn_data:--embed_graph_train_data:--output_graph_embed:--init_image_model:IMAGE in modeltype.--init_graph_model:IMAGE in modeltype.--label_data:{label}.csv label data in the raw dir containing count data.--train_ratio:train/ folder.--val_ratio:train/ folder.--num_cfolds:train/ folder split over patients. Only used when greater > 1. --output_name of model gets split at . and becomes a folder in which one model per split, named after split number [n].pt, is saved.--node_dropout:--edge_dropout:--cell_pos_jitter:-cell_n_knn:--subgraphs_per_graph:{measurements}.csv contains Cell count data.--num_hops_subgraph:--model_type:--data_use_log_graph:--graph_mse_mult:--graph_cos_sim_mult:--lin_layers:--gat_layers:-num_node_features:--num_edge_features:--num_embed_features:--heads:--embed_dropout:--conv_dropout:After training a model to predict the Expression of Single Cells, the predicted Expression of all Single Cells in the specified directory get embeded in the specified output graph embed directory. Each graph gets embedded seperatly in shape (Number of Cells, Number of Genes/Transcripts/Proteins/...). It is important to note that models trained on subgraphs will embed subgraphs, if the embedding is not done in a seperate call where --subgraphs_per_graph is set to 0. Subgraphs are stored in processed/{EXPERIMENT NAME}/subgraphs/ if created.
python -m cellevaluation --merge --embed_dir out/graph_model/ --h5ad_dir 'out/' --vis_label_data {label}.csv --processed_subset_dir dataset/test --vis_name graph_model --embed_to_h5ad
--merge:embed_dir:--h5ad_dir:--vis_label_data:--processed_subset_dir:--vis_name:_all.h5ad is appended when saving.--embed_to_h5ad:python -m cellevaluation --vis_label_data dataset/measurements.csv --h5ad_dir 'out/' --vis_name_pattern 'cosmx_lin_[0-5]_all.h5ad' --num_subgraphs_per_graph 36 --num_hops_per_subgraph 1 2 3 5 8 11 --do_clusterin_metrics --do_performance_metrics --do_pathway_metrics --performance_metrics --figure_dir figures/cosmx/lin/metrics/
--vis_label_data:--h5ad_dir:--vis_name_pattern:.h5ad files which to consider. Iterates over all if multiple and creates averages of performance.--num_subgraphs_per_graph:--num_hops_per_subgraph:--do_clusterin_metrics:--do_performance_metrics:--do_pathway_metrics:--do_clustering_metrics.--performance_metrics:--figure_dir:--sum_by_graph:Model runs can be visualized as follows:
python -m cellevaluation --visualize_model_run --model_path 'out/models/graph_model.pt' --output_model_name 'Image Contrast Model' --figure_model_dir 'figures/graph_model/' --is_cs
--visualize_model_run:--model_path:--output_model_name:--figure_model_dir:--is_cs:The predicted single cell Expression can be visualized:
python -m cellevaluation --visualize_expression --vis_label_data '{label}.csv' --processed_subset_dir '{EXPERIMENT NAME}/test' --figure_dir 'figures/graph_model/' --embed_dir 'out/graph_model/' --vis_select_cells 50000 --vis_name '_graph_model' --has_expr_data --merge
--visualize_expression:--vis_label_data:--processed_subset_dir:train/test{/subgraphs} directory of processed/ and raw/ of data.--figure_dir:--embed_dir:--vis_select_cells:--vis_name:{NAME}.h5ad in out/. Additional unproccesed save with all cells is named {NAME}_all.h5ad.--has_expr_data:measurements.csv, calculates per cell correlation.--raw_subset_dir:--merge:The predicted single cell Expression can be also visualized on the Images themselfs:
python -m cellevaluation --visualize_image --vis_img_raw_subset_dir '{EXPERIMENT NAME}' --name_tiff 'CRC02.ome.tif' --figure_img_dir 'figures/graph_model/' --vis_protein 'CD45,CD8,Keratin,Ki67,Fibronectin,Some.Name' --vis_img_xcoords 0 0 --vis_img_ycoords 0 0 --vis_all_channels --vis_name '_graph_model.h5ad' --vis_name_og 'original_data.h5ad'
--visualize_image:--vis_img_raw_subset_dir:--name_tiff:--figure_img_dir:--vis_protein:,; . converts to space.--vis_img_xcoords:--vis_img_ycoords:--vis_all_channels:--vis_name:out/{NAME} produced via visualizing expression, needs to be given.--vis_name_og:out/{NAME} of original single-cell expression data, manualy created for a dataset if given data present. Contrasts predicted expression with observed expression.Tutorials to repreduce our results can be found in the reproduce/ directory.
Python
82.0%
Shell
17.4%
Our models are trained with nvidia GPUs. To run on GPUs appropiate CUDA versions must be installed. Installing via conda can result in cuda version mismatches or in the installation of CPU versions. Appropiate versions can be found here.
Setup via Anaconda environment:
conda install -c anaconda python=3.11.5
pip install torch -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install torch-geometric -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install torch-cluster -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install torchvision -f https://data.pyg.org/whl/torch-2.4.0+cu121.html
pip install squidpy
pip install decoupler
#pip install imctools
The following data is required to start training:
ln -s /path/to/images/*.tiff data/raw/{EXPERIMENT NAME}/[train/test]. [train/test] are folders in which to split the data, data in train/ is used for training and validation, data in test/ is used for testing.data/raw/{EXPERIMENT NAME}/. The csv contains Cellpostion information of all images. It consists out of the following columns with these exact names: The first column is named Image and contains the name of the images, e.g. CRC03.ome.tif. The second and third column should be named Centroid.X.px and Centroid.Y.px, which contain Cell positions in pixel(!) values. We expect coordinates to start at (0,0) at the upper left corner of each corresponding image. The 4th column should be named Class and contains Celltype information, if existing. This can also be empty. Every column after this is optional, and represents count data of the cells. This can be used to create smaller areas of the image to train on. This is only useful when already spatialomics count data for cells exists(e.g. to investigate model performace). This can be normalized counts, but do not use log normalized counts.data/raw/. The csv contains information of the overall count data for an image. It consists out of the following columns: The first column is named ROI and contains the name of the image, minus everything after the first .(CRC02.ome.tif->CRC02). The second column is named Patient_ID and contains some ID to which the Image corresponds. Every column after this is interpreted as Count data. Each entry has the whole count data of the whole Image. This can be normalized counts, but o not use log normalized counts.Now we are ready to go!
The first process is to normalize Image data and uniformly cut out Cells:
python -m cellcontrast --image_preprocess --preprocess_dir 'data/raw/{EXPERIMENT NAME}/[train/test]/' --cell_cutout 34 --preprocess_workers 26 --preprocess_channels 0,10,14,19 --calc_mean_std
--image_preprocess:--preprocess_dir:{measurements}.csv in direct parent directory.--cell_cutout:--preprocess_workers:--preprocess_channels:
Channels to preprocess. If not specified use all Channels. Seperate Channel indicies, starting from 0, with commas.--calc_mean_stdr:mean.npy and std.npy in direct parent directory of --preprocess_dir.Preprocessing produces files for each Image: {IMAGE NAME}_cells.npy in the shape of (Number of Cells, Channels, --cell_cutout, --cell_cutout).
--deterministic:--seed:--root_dir:data/.--raw_subset_dir:--batch_size:--epochs:--num_workers:--lr:--weight_decay:--early_stopping:--output_name:Next, we learn Visual Representations of Cells via Contrastive learning:
python -m cellcontrast --train_image_model --embed_image_data --output_name 'out/models/image_contrast_model.pt' --raw_subset_dir '{EXPERIMENT NAME}' --weight_decay 1e-6 --resnet_model '18' --batch_size 4096 --epochs 100 --warmup_epochs 10 --num_workers 25 --lr 0.1 --embed 32 --contrast 16 --crop_factor 0.2 --n_clusters_image 20
--train_image_model:--embed_image_data:--resnet_model:'18'.--embed:--contrast:--crop_factor:--n_clusters_image:We extract visual representations after training a model to learn visual representations. Embedding produces files for each {IMAGE NAME}_cells.npy in the same directory: {IMAGE NAME}_cells_embed.pt in the shape of (Number of Cells, --embed.
Next, we learn what each Cell contributes to the Count Data of an Image:
python -m cellprediction --train_gnn --embed_gnn_data --output_name 'out/models/image_graph_model.pt' --output_graph_embed '/out/graph_model/' --init_image_model 'out/models/image_contrast_model.pt' --init_graph_model 'out/models/graph_model.pt' --root_dir 'data/' --raw_subset_dir '{EXPERIMENT NAME}' --label_data '{label}.csv' --batch_size 64 --epochsh 1000 --num_workers 12 --lr 0.005 --early_stopping 50 --weight_decay 1e-4 --train_ratio 0.6 --val_ratio 0.2 --node_dropout 0.0 --edge_dropout 0.3 --cell_pos_jitter 40 --cell_n_knn 6 --subgraphs_per_graph 0 --num_hops_subgraph 0 --model_type 'Image2Count' --data_use_log_graph --graph_mse_mult 1 --graph_cos_sim_mult 1 --lin_layers 3 --gat_layers 3 --num_node_features 32 --num_edge_features 1 --num_embed_features 128 --heads 4 --embed_dropout 0.1 --conv_dropout 0.1 --num_cfolds 0
--train_gnn:--embed_gnn_data:--embed_graph_train_data:--output_graph_embed:--init_image_model:IMAGE in modeltype.--init_graph_model:IMAGE in modeltype.--label_data:{label}.csv label data in the raw dir containing count data.--train_ratio:train/ folder.--val_ratio:train/ folder.--num_cfolds:train/ folder split over patients. Only used when greater > 1. --output_name of model gets split at . and becomes a folder in which one model per split, named after split number [n].pt, is saved.--node_dropout:--edge_dropout:--cell_pos_jitter:-cell_n_knn:--subgraphs_per_graph:{measurements}.csv contains Cell count data.--num_hops_subgraph:--model_type:--data_use_log_graph:--graph_mse_mult:--graph_cos_sim_mult:--lin_layers:--gat_layers:-num_node_features:--num_edge_features:--num_embed_features:--heads:--embed_dropout:--conv_dropout:After training a model to predict the Expression of Single Cells, the predicted Expression of all Single Cells in the specified directory get embeded in the specified output graph embed directory. Each graph gets embedded seperatly in shape (Number of Cells, Number of Genes/Transcripts/Proteins/...). It is important to note that models trained on subgraphs will embed subgraphs, if the embedding is not done in a seperate call where --subgraphs_per_graph is set to 0. Subgraphs are stored in processed/{EXPERIMENT NAME}/subgraphs/ if created.
python -m cellevaluation --merge --embed_dir out/graph_model/ --h5ad_dir 'out/' --vis_label_data {label}.csv --processed_subset_dir dataset/test --vis_name graph_model --embed_to_h5ad
--merge:embed_dir:--h5ad_dir:--vis_label_data:--processed_subset_dir:--vis_name:_all.h5ad is appended when saving.--embed_to_h5ad:python -m cellevaluation --vis_label_data dataset/measurements.csv --h5ad_dir 'out/' --vis_name_pattern 'cosmx_lin_[0-5]_all.h5ad' --num_subgraphs_per_graph 36 --num_hops_per_subgraph 1 2 3 5 8 11 --do_clusterin_metrics --do_performance_metrics --do_pathway_metrics --performance_metrics --figure_dir figures/cosmx/lin/metrics/
--vis_label_data:--h5ad_dir:--vis_name_pattern:.h5ad files which to consider. Iterates over all if multiple and creates averages of performance.--num_subgraphs_per_graph:--num_hops_per_subgraph:--do_clusterin_metrics:--do_performance_metrics:--do_pathway_metrics:--do_clustering_metrics.--performance_metrics:--figure_dir:--sum_by_graph:Model runs can be visualized as follows:
python -m cellevaluation --visualize_model_run --model_path 'out/models/graph_model.pt' --output_model_name 'Image Contrast Model' --figure_model_dir 'figures/graph_model/' --is_cs
--visualize_model_run:--model_path:--output_model_name:--figure_model_dir:--is_cs:The predicted single cell Expression can be visualized:
python -m cellevaluation --visualize_expression --vis_label_data '{label}.csv' --processed_subset_dir '{EXPERIMENT NAME}/test' --figure_dir 'figures/graph_model/' --embed_dir 'out/graph_model/' --vis_select_cells 50000 --vis_name '_graph_model' --has_expr_data --merge
--visualize_expression:--vis_label_data:--processed_subset_dir:train/test{/subgraphs} directory of processed/ and raw/ of data.--figure_dir:--embed_dir:--vis_select_cells:--vis_name:{NAME}.h5ad in out/. Additional unproccesed save with all cells is named {NAME}_all.h5ad.--has_expr_data:measurements.csv, calculates per cell correlation.--raw_subset_dir:--merge:The predicted single cell Expression can be also visualized on the Images themselfs:
python -m cellevaluation --visualize_image --vis_img_raw_subset_dir '{EXPERIMENT NAME}' --name_tiff 'CRC02.ome.tif' --figure_img_dir 'figures/graph_model/' --vis_protein 'CD45,CD8,Keratin,Ki67,Fibronectin,Some.Name' --vis_img_xcoords 0 0 --vis_img_ycoords 0 0 --vis_all_channels --vis_name '_graph_model.h5ad' --vis_name_og 'original_data.h5ad'
--visualize_image:--vis_img_raw_subset_dir:--name_tiff:--figure_img_dir:--vis_protein:,; . converts to space.--vis_img_xcoords:--vis_img_ycoords:--vis_all_channels:--vis_name:out/{NAME} produced via visualizing expression, needs to be given.--vis_name_og:out/{NAME} of original single-cell expression data, manualy created for a dataset if given data present. Contrasts predicted expression with observed expression.Tutorials to repreduce our results can be found in the reproduce/ directory.
Python
82.0%
Shell
17.4%