Digital Slide Archive (DSA) Visualization Tutorial¶
Welcome to the Digial Slide Archive (DSA) visualization notebook!
Digital Slide Archive (DSA) is a web application on which you can manage your pathology images and annotations. Luna provides a set of CLIs to help you convert your pathologist or model-generated annotations to a format that DSA accepts. For more details on the DSA platform, please refer to their documentation.
In this notebook, we will use dsa and dsa_upload CLIs to convert your annotations to a DSA compatible format and to upload them to DSA. We support results from Qupath/Stardist dectection models (link to docker image), tile scores in a tabular format, and also expert annotations in geojson format. Here are the steps we will review:
- Setup DSA
- DSA Visuzaliation CLIs
- Upload Qupath regional annotation results
- Upload a heatmap generated from tile scores
- Upload bitmasks PNGs
- Upload bmp results
- Upload Stardist object detection results
- Upload Stardist cell detection results
!echo LUNA_HOME: $LUNA_HOME
!echo PYTHONPATH: $PYTHONPATH
LUNA_HOME: /home/limr/vmount PYTHONPATH:
Setup DSA¶
Before running this notebook, make sure you have your pathology slides organized in DSA under a collection/folder. This will have already been done for you if you have run the previous notebooks in the tutorial.
The collection name 'TCGA collection' and image file name 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs on DSA will be used while uploading the annotations.
DSA Visualization CLIs¶
Luna Pathology offers 2 CLIs to help convert your annotation results to a DSA compatible json format and to upload them to DSA. The conversion and upload is divided in to 2 separate steps, so each step can be parallelized based on your computing capabilities and DSA platform setup.
dsa [COMMAND]
converts your annotation file format to a DSA compatible annotation json format.
dsa_upload
uploads the DSA compatible annotation json.
Once upload is done, the annotations may be viewed in the HistomicsUI viewer.
Note: Pushing and rendering a large number of annotation elements can take a long time. Please refer to DSA documentation, for user expectations and some tricks for managing annotations.
# check available dsa cli commands
!dsa --help
2023-04-04 20:21:40,215 - INFO - root - Initalized logger, log file at: luna.log Usage: dsa [OPTIONS] COMMAND [ARGS]... Convert segmentations, bitmasks, heatmaps to DSA annotation Json format. Options: --help Show this message and exit. Commands: bitmask-polygon Example: bmp-polygon Example: heatmap Example: qupath-polygon Example: regional-polygon Example: stardist-cell Example: stardist-polygon Example:
# check dsa cli commands help messages
!dsa stardist-polygon --help
2023-04-04 20:21:42,347 - INFO - root - Initalized logger, log file at: luna.log Usage: dsa stardist-polygon [OPTIONS] INPUT Example: dsa stardist-polygon ../dsa_input/test_object_classification.geojson --output_dir ../dsa_annotations/stardist_polygon --annotation_name stardist_polygon_segmentations --image_filename 123.svs --line_colors '{"Other": "rgb(0,255,0)", "Lymphocyte": "rgb(255,0,0)"}' --fill_colors '{"Other": "rgba(0,255,0,100)", "Lymphocyte": "rgba(255,0,0,100)"}' Options: -m, --method_param_path TEXT path to a metadata json/yaml file with method parameters to reproduce results -fc, --fill_colors TEXT user-provided line color map with {feature name:rgba values} -lc, --line_colors TEXT user-provided line color map with {feature name:rgb values} -a, --annotation_name TEXT name of the annotation to be displayed in DSA -f, --image_filename TEXT name of the image file in DSA e.g. 123.svs -o, --output_dir TEXT directory to save the DSA compatible annotation json --help Show this message and exit.
# check dsa_upload help messages
!dsa_upload --help
2023-04-04 20:21:43,740 - INFO - root - Initalized logger, log file at: luna.log Usage: dsa_upload [OPTIONS] DSA_ENDPOINT DSA Annotation Upload CLI Example: export DSA_USERNAME=username export DSA_PASSWORD=password dsa_upload http://localhost:8080/dsa/api/v1 --collection_name tcga- data --image_filename 123.svs --annotation_filepath /path/to/dsa_annotation.json Options: -c, --collection_name TEXT name of the collection in DSA -f, --image_filename TEXT name of the image file in DSA e.g. 123.svs -a, --annotation_filepath TEXT path to a DSA annotation json file -u, --username TEXT DSA username, can be inferred from DSA_USERNAME -p, --password TEXT DSA password, should be inferred from DSA_PASSWORD -m, --method_param_path TEXT path to a metadata json/yaml file with method parameters to reproduce results --help Show this message and exit.
Upload a heatmap generated from tile scores¶
the heatmap sub-command converts the output csv file containing tiles scores from the inference step to a DSA compatible json format.
Once the json file is uploaded to DSA using the upload command, the heatmap may be viewed in HistomicsUI.
We use the color palette "viridis" where the output color ranges from purple to yellow, for scores from 0 to 1.
# example data_config
!dsa heatmap --help
2023-04-04 20:21:45,722 - INFO - root - Initalized logger, log file at: luna.log Usage: dsa heatmap [OPTIONS] INPUT Example: dsa heatmap score.csv --output_dir ../dsa_annotations/heatmap --annotation_name heatmap --image_filename 123.svs --tile_size 256 --column tumor --scale_factor 1 dsa heatmap score.csv --output_dir ../dsa_annotations/heatmap --annotation_name heatmap --image_filename 123.svs --tile_size 256 --column tumor --column stroma --line_colors '{"tumor": "rgb(0,255,0)", "stroma": "rgb(255,0,0)"}' --fill_colors '{"tumor": "rgba(0,255,0,100)", "stroma": "rgba(255,0,0,100)"}' --scale_factor 1 Options: -m, --method_param_path TEXT path to a metadata json/yaml file with method parameters to reproduce results -sc, --scale_factor INTEGER scale to match image DSA. (default 1) -ts, --tile_size TEXT tile size -lc, --line_colors TEXT user-provided line color map with {feature name:rgb values} -fc, --fill_colors TEXT user-provided line color map with {feature name:rgba values} -c, --column TEXT column(s) to visualize e.g. tile_score. if multiple are specified, annotate the tile with the label with maximum score. -a, --annotation_name TEXT name of the annotation to be displayed in DSA -f, --image_filename TEXT name of the image file in DSA e.g. 123.svs -o, --output_dir TEXT directory to save the DSA compatible annotation json --help Show this message and exit.
# generate DSA compatible annotation
!dsa heatmap ../dsa_input/tile_scores.csv \
--output_dir ../dsa_annotations/heatmap \
--annotation_name heatmap \
--image_filename 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs \
--tile_size 256 \
--column purple_score \
--scale_factor 1
2023-04-04 20:21:47,890 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:21:47,893 - INFO - luna.common.utils - Started CLI Runner wtih <function heatmap_main at 0x7f513ec2be50> 2023-04-04 20:21:47,895 - INFO - luna.common.utils - Validating params... 2023-04-04 20:21:47,897 - INFO - luna.common.utils - -> Set column (<class 'list'>) = ['purple_score'] 2023-04-04 20:21:47,899 - INFO - luna.common.utils - -> Set tile_size (<class 'int'>) = 256 2023-04-04 20:21:47,901 - INFO - luna.common.utils - -> Set annotation_name (<class 'str'>) = heatmap 2023-04-04 20:21:47,902 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs 2023-04-04 20:21:47,904 - INFO - luna.common.utils - -> Set output_dir (<class 'str'>) = ../dsa_annotations/heatmap 2023-04-04 20:21:47,905 - INFO - luna.common.utils - -> Set input (<class 'str'>) = ../dsa_input/tile_scores.csv 2023-04-04 20:21:47,908 - INFO - luna.common.utils - -> Set scale_factor (<class 'int'>) = 1 2023-04-04 20:21:47,911 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:21:47,912 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:21:47,914 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:47,914 - INFO - luna.common.utils - Starting transform::heatmap_main 2023-04-04 20:21:47,914 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:47,977 - INFO - luna.common.utils - Code block 'transform::heatmap_main' took: 0.062102266994770616s 2023-04-04 20:21:47,979 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:47,979 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:21:47,979 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:47,984 - INFO - luna.common.utils - Done.
# push annotation to DSA
!dsa_upload http://girder:8080/api/v1 \
--collection_name 'TCGA collection' \
--image_filename 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs \
--annotation_filepath ../dsa_annotations/heatmap/purple_score_heatmap_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json \
--username admin \
--password password1
2023-04-04 20:21:49,375 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:21:49,377 - INFO - luna.common.utils - Started CLI Runner wtih <function upload_annotation_to_dsa at 0x7fe9357af280> 2023-04-04 20:21:49,379 - INFO - luna.common.utils - Validating params... 2023-04-04 20:21:49,381 - INFO - luna.common.utils - -> Set annotation_filepath (<class 'str'>) = ../dsa_annotations/heatmap/purple_score_heatmap_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json 2023-04-04 20:21:49,383 - INFO - luna.common.utils - -> Set collection_name (<class 'str'>) = TCGA collection 2023-04-04 20:21:49,384 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs 2023-04-04 20:21:49,386 - INFO - luna.common.utils - -> Set dsa_endpoint (<class 'str'>) = http://girder:8080/api/v1 2023-04-04 20:21:49,388 - INFO - luna.common.utils - -> Set username (<class 'str'>) = ***** 2023-04-04 20:21:49,389 - INFO - luna.common.utils - -> Set password (<class 'str'>) = ***** 2023-04-04 20:21:49,391 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:21:49,392 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:21:49,394 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:49,394 - INFO - luna.common.utils - Starting transform::upload_annotation_to_dsa 2023-04-04 20:21:49,394 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:49,659 - INFO - luna.pathology.dsa.dsa_api_handler - Successfully connected to DSA 2023-04-04 20:21:49,687 - INFO - luna.pathology.dsa.dsa_api_handler - Found collection id=642b13a033dd668f85bbc1ee for collection=TCGA collection Image file 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs found with id: 642b13a033dd668f85bbc1f0 2023-04-04 20:21:49,810 - INFO - luna.pathology.dsa.dsa_api_handler - Annotation successfully pushed to DSA. 2023-04-04 20:21:49,812 - INFO - luna.pathology.dsa.dsa_api_handler - Time to push annotation 0.11490583419799805 2023-04-04 20:21:49,814 - INFO - luna.pathology.dsa.dsa_api_handler - http://girder:8080//histomics#?image=642b13a033dd668f85bbc1f0 2023-04-04 20:21:49,816 - INFO - luna.common.utils - Code block 'transform::upload_annotation_to_dsa' took: 0.420063235971611s 2023-04-04 20:21:49,817 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:49,817 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:21:49,817 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:49,819 - INFO - luna.common.utils - Done.
Upload bitmasks PNGs¶
Simple PNG bitmasks can also be visualized in DSA. Use the bitmask-polygon sub-command and specify pngs with the corresponding labels. Then upload to view in HistomicsUI.
# generate DSA compatible annotation
!dsa bitmask-polygon \
'{"OTSU": "../PRO-12-123/tiling/inference/detect/otsu_mask.png"}' \
--output_dir ../dsa_annotations/bitmask \
--annotation_name bitmask \
--image_filename 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs \
--line_colors '{"OTSU": "rgb(255,255,0)"}' \
--fill_colors '{"OTSU": "rgba(255,255,0,100)"}'
# push annotation to DSA
!dsa_upload http://girder:8080/api/v1 \
--collection_name 'TCGA collection' \
--image_filename 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs \
--annotation_filepath ../dsa_annotations/bitmask/bitmask_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json \
--username admin \
--password password1
2023-04-04 20:21:51,789 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:21:51,792 - INFO - luna.common.utils - Started CLI Runner wtih <function bitmask_polygon_main at 0x7f8e859dfdc0> 2023-04-04 20:21:51,794 - INFO - luna.common.utils - Validating params... 2023-04-04 20:21:51,795 - INFO - luna.common.utils - -> Set fill_colors (<class 'dict'>) = {'OTSU': 'rgba(255,255,0,100)'} 2023-04-04 20:21:51,798 - INFO - luna.common.utils - -> Set line_colors (<class 'dict'>) = {'OTSU': 'rgb(255,255,0)'} 2023-04-04 20:21:51,800 - INFO - luna.common.utils - -> Set annotation_name (<class 'str'>) = bitmask 2023-04-04 20:21:51,802 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs 2023-04-04 20:21:51,803 - INFO - luna.common.utils - -> Set output_dir (<class 'str'>) = ../dsa_annotations/bitmask 2023-04-04 20:21:51,805 - INFO - luna.common.utils - -> Set input (<class 'dict'>) = {'OTSU': '../PRO-12-123/tiling/inference/detect/otsu_mask.png'} 2023-04-04 20:21:51,807 - INFO - luna.common.utils - -> Set scale_factor (<class 'int'>) = 1 2023-04-04 20:21:51,809 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:21:51,810 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:21:51,812 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:21:51,812 - INFO - luna.common.utils - Starting transform::bitmask_polygon_main 2023-04-04 20:21:51,812 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:31,488 - INFO - luna.common.utils - Code block 'transform::bitmask_polygon_main' took: 39.674094040005s 2023-04-04 20:22:31,490 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:31,490 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:31,490 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:31,498 - INFO - luna.common.utils - Done. 2023-04-04 20:22:32,882 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:22:32,884 - INFO - luna.common.utils - Started CLI Runner wtih <function upload_annotation_to_dsa at 0x7f481f9861f0> 2023-04-04 20:22:32,886 - INFO - luna.common.utils - Validating params... 2023-04-04 20:22:32,887 - INFO - luna.common.utils - -> Set annotation_filepath (<class 'str'>) = ../dsa_annotations/bitmask/bitmask_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json 2023-04-04 20:22:32,889 - INFO - luna.common.utils - -> Set collection_name (<class 'str'>) = TCGA collection 2023-04-04 20:22:32,891 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs 2023-04-04 20:22:32,893 - INFO - luna.common.utils - -> Set dsa_endpoint (<class 'str'>) = http://girder:8080/api/v1 2023-04-04 20:22:32,895 - INFO - luna.common.utils - -> Set username (<class 'str'>) = ***** 2023-04-04 20:22:32,897 - INFO - luna.common.utils - -> Set password (<class 'str'>) = ***** 2023-04-04 20:22:32,900 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:22:32,901 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:22:32,903 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:32,903 - INFO - luna.common.utils - Starting transform::upload_annotation_to_dsa 2023-04-04 20:22:32,903 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:33,161 - INFO - luna.pathology.dsa.dsa_api_handler - Successfully connected to DSA 2023-04-04 20:22:34,333 - INFO - luna.pathology.dsa.dsa_api_handler - Found collection id=642b13a033dd668f85bbc1ee for collection=TCGA collection Image file 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs found with id: 642b13a033dd668f85bbc1f0 2023-04-04 20:22:46,067 - INFO - luna.pathology.dsa.dsa_api_handler - Annotation successfully pushed to DSA. 2023-04-04 20:22:46,070 - INFO - luna.pathology.dsa.dsa_api_handler - Time to push annotation 11.727005958557129 2023-04-04 20:22:46,072 - INFO - luna.pathology.dsa.dsa_api_handler - http://girder:8080//histomics#?image=642b13a033dd668f85bbc1f0 2023-04-04 20:22:46,158 - INFO - luna.common.utils - Code block 'transform::upload_annotation_to_dsa' took: 13.253162581997458s 2023-04-04 20:22:46,161 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:46,161 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:46,161 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:46,165 - INFO - luna.common.utils - Done.
Upload bmp results¶
Similary, BMP is another file format that may be used to store segmentation or classification results. bmp-polygon converts the bmps to the DSA compatible json annotation.
!dsa bmp-polygon --help
2023-04-04 20:22:48,174 - INFO - root - Initalized logger, log file at: luna.log Usage: dsa bmp-polygon [OPTIONS] INPUT Example: dsa bmp-polygon results.bmp --output_dir ../dsa_annotations/bmp --annotation_name bmp --image_filename 123.svs --label '{0: "Tumor", 1: "Other"}' --scale_factor 1 --line_colors '{"Other": "rgb(0,255,0)", "Tumor": "rgb(255,0,0)"}' --fill_colors '{"Other": "rgba(0,255,0,100)", "Tumor": "rgba(255,0,0,100)"}' Options: -m, --method_param_path TEXT path to a metadata json/yaml file with method parameters to reproduce results -sc, --scale_factor TEXT scale to match image DSA. (default 1) -fc, --fill_colors TEXT user-provided line color map with {feature name:rgba values} -lc, --line_colors TEXT user-provided line color map with {feature name:rgb values} -a, --annotation_name TEXT name of the annotation to be displayed in DSA -f, --image_filename TEXT name of the image file in DSA e.g. 123.svs -o, --output_dir TEXT directory to save the DSA compatible annotation json -l, --label TEXT map of {label_num:label_name} --help Show this message and exit.
Upload Qupath regional annotation results¶
Regional annotations generated by Qupath includes regional polygons from object detection along with nuclear properties.
For object and cell detection models in QuPath, please checkout our Qupath/Stardist docker.
# generate DSA compatible annotation
!dsa qupath-polygon \
../PRO-12-123/data/toy_data_set/table/ANNOTATIONS/01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.annotation.geojson \
--output_dir ../dsa_annotations/quppath \
--annotation_name quppath \
--image_filename 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs \
--classes_to_include Other \
--line_colors '{"Other": "rgb(0,255,255)"}' \
--fill_colors '{"Other": "rgba(0,255,255,100)"}'
2023-04-04 20:22:50,291 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:22:50,294 - INFO - luna.common.utils - Started CLI Runner wtih <function qupath_polygon_main at 0x7f3f6ddf3d30> 2023-04-04 20:22:50,296 - INFO - luna.common.utils - Validating params... 2023-04-04 20:22:50,298 - INFO - luna.common.utils - -> Set fill_colors (<class 'dict'>) = {'Other': 'rgba(0,255,255,100)'} 2023-04-04 20:22:50,300 - INFO - luna.common.utils - -> Set line_colors (<class 'dict'>) = {'Other': 'rgb(0,255,255)'} 2023-04-04 20:22:50,301 - INFO - luna.common.utils - -> Set annotation_name (<class 'str'>) = quppath 2023-04-04 20:22:50,302 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.svs 2023-04-04 20:22:50,304 - INFO - luna.common.utils - -> Set output_dir (<class 'str'>) = ../dsa_annotations/quppath 2023-04-04 20:22:50,305 - INFO - luna.common.utils - -> Set input (<class 'str'>) = ../PRO-12-123/data/toy_data_set/table/ANNOTATIONS/01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.annotation.geojson 2023-04-04 20:22:50,307 - INFO - luna.common.utils - -> Set classes_to_include (<class 'list'>) = ['O', 't', 'h', 'e', 'r'] 2023-04-04 20:22:50,309 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:22:50,311 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:22:50,312 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:50,312 - INFO - luna.common.utils - Starting transform::qupath_polygon_main 2023-04-04 20:22:50,312 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:50,320 - INFO - luna.common.utils - Code block 'transform::qupath_polygon_main' took: 0.00604663701960817s 2023-04-04 20:22:50,321 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:50,321 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:50,321 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:50,327 - INFO - luna.common.utils - Done.
%%bash
ls ../dsa_annotations/quppath/
metadata.yml quppath_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json
# push annotation to DSA
!dsa_upload http://girder:8080/api/v1 \
--collection_name 'TCGA collection' \
--image_filename 123.svs \
--annotation_filepath ../dsa_annotations/quppath/quppath_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json \
--username admin \
--password password1
2023-04-04 20:22:51,767 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:22:51,769 - INFO - luna.common.utils - Started CLI Runner wtih <function upload_annotation_to_dsa at 0x7f7b153a31f0> 2023-04-04 20:22:51,771 - INFO - luna.common.utils - Validating params... 2023-04-04 20:22:51,773 - INFO - luna.common.utils - -> Set annotation_filepath (<class 'str'>) = ../dsa_annotations/quppath/quppath_01OV002-bd8cdc70-3d46-40ae-99c4-90ef77.json 2023-04-04 20:22:51,775 - INFO - luna.common.utils - -> Set collection_name (<class 'str'>) = TCGA collection 2023-04-04 20:22:51,776 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 123.svs 2023-04-04 20:22:51,777 - INFO - luna.common.utils - -> Set dsa_endpoint (<class 'str'>) = http://girder:8080/api/v1 2023-04-04 20:22:51,779 - INFO - luna.common.utils - -> Set username (<class 'str'>) = ***** 2023-04-04 20:22:51,781 - INFO - luna.common.utils - -> Set password (<class 'str'>) = ***** 2023-04-04 20:22:51,782 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:22:51,783 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:22:51,785 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:51,785 - INFO - luna.common.utils - Starting transform::upload_annotation_to_dsa 2023-04-04 20:22:51,785 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:52,036 - INFO - luna.pathology.dsa.dsa_api_handler - Successfully connected to DSA 2023-04-04 20:22:52,065 - INFO - luna.pathology.dsa.dsa_api_handler - Found collection id=642b13a033dd668f85bbc1ee for collection=TCGA collection 2023-04-04 20:22:52,074 - WARNING - luna.pathology.dsa.dsa_api_handler - Image file 123.svs not found 2023-04-04 20:22:52,076 - INFO - luna.common.utils - Code block 'transform::upload_annotation_to_dsa' took: 0.289324740995653s 2023-04-04 20:22:52,077 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:52,077 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:52,077 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:52,079 - INFO - luna.common.utils - Done.
Upload Stardist object detection results¶
Stardist is a nuclear segmentation algorithm that is quite capable in detecting and segmenting cells/nuclei in pathology images. stardist-polygon option converts Stardist object detection results as polygons capturing different types of cells.
Note: this command can take a few minutes if object detection is run on the whole slide.
# generate DSA annotation
!dsa stardist-polygon \
../dsa_input/test_object_classification.geojson \
--output_dir ../dsa_annotations/stardist_polygon \
--annotation_name stardist_polygon_segmentations \
--image_filename 123.svs \
--line_colors '{"Other": "rgb(0,255,0)", "Lymphocyte": "rgb(255,0,0)"}' \
--fill_colors '{"Other": "rgba(0,255,0,100)", "Lymphocyte": "rgba(255,0,0,100)"}'
2023-04-04 20:22:54,110 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:22:54,113 - INFO - luna.common.utils - Started CLI Runner wtih <function stardist_polygon_main at 0x7f7508c349d0> 2023-04-04 20:22:54,114 - INFO - luna.common.utils - Validating params... 2023-04-04 20:22:54,116 - INFO - luna.common.utils - -> Set fill_colors (<class 'dict'>) = {'Other': 'rgba(0,255,0,100)', 'Lymphocyte': 'rgba(255,0,0,100)'} 2023-04-04 20:22:54,118 - INFO - luna.common.utils - -> Set line_colors (<class 'dict'>) = {'Other': 'rgb(0,255,0)', 'Lymphocyte': 'rgb(255,0,0)'} 2023-04-04 20:22:54,120 - INFO - luna.common.utils - -> Set annotation_name (<class 'str'>) = stardist_polygon_segmentations 2023-04-04 20:22:54,121 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 123.svs 2023-04-04 20:22:54,123 - INFO - luna.common.utils - -> Set output_dir (<class 'str'>) = ../dsa_annotations/stardist_polygon 2023-04-04 20:22:54,124 - INFO - luna.common.utils - -> Set input (<class 'str'>) = ../dsa_input/test_object_classification.geojson 2023-04-04 20:22:54,127 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:22:54,129 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:22:54,130 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:54,130 - INFO - luna.common.utils - Starting transform::stardist_polygon_main 2023-04-04 20:22:54,130 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:54,138 - INFO - luna.common.utils - Code block 'transform::stardist_polygon_main' took: 0.0055424359743483365s 2023-04-04 20:22:54,139 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:54,139 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:54,139 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:54,144 - INFO - luna.common.utils - Done.
# check json annotation
!head ../dsa_annotations/stardist_polygon/stardist_polygon_segmentations_123.json
{"description": "", "elements": [{"fillColor": "rgba(0,255,0,100)", "lineColor": "rgb(0,255,0)", "lineWidth": 2, "type": "polyline", "closed": true, "points": [[61781.95, 929.31, 0], [61771.77, 932.48, 0], [61763.49, 938.38, 0], [61757.63, 946.76, 0], [61756.68, 949.76, 0], [61756.34, 957.75, 0], [61756.81, 960.34, 0], [61759.75, 967.25, 0], [61761.4, 969.48, 0], [61766.69, 973.96, 0], [61774.61, 976.99, 0], [61776.99, 977.25, 0], [61787.6, 976.28, 0], [61793.96, 974.36, 0], [61803.92, 972.54, 0], [61812.41, 969.1, 0], [61819.84, 962.2, 0], [61821.52, 958.67, 0], [61822.29, 950.5, 0], [61821.42, 947.99, 0], [61816.19, 940.43, 0], [61810.58, 936.37, 0], [61803.19, 933.06, 0], [61793.31, 929.64, 0], [61781.95, 929.31, 0]], "label": {"value": "Other"}}], "name": "stardist_polygon_segmentations"}
# push annotation to DSA
!dsa_upload http://girder:8080/api/v1 \
--collection_name 'TCGA collection' \
--image_filename 123.svs \
--annotation_filepath ../dsa_annotations/stardist_polygon/stardist_polygon_segmentations_123.json \
--username admin \
--password password1
2023-04-04 20:22:55,897 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:22:55,899 - INFO - luna.common.utils - Started CLI Runner wtih <function upload_annotation_to_dsa at 0x7f5f30a001f0> 2023-04-04 20:22:55,901 - INFO - luna.common.utils - Validating params... 2023-04-04 20:22:55,903 - INFO - luna.common.utils - -> Set annotation_filepath (<class 'str'>) = ../dsa_annotations/stardist_polygon/stardist_polygon_segmentations_123.json 2023-04-04 20:22:55,904 - INFO - luna.common.utils - -> Set collection_name (<class 'str'>) = TCGA collection 2023-04-04 20:22:55,906 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 123.svs 2023-04-04 20:22:55,907 - INFO - luna.common.utils - -> Set dsa_endpoint (<class 'str'>) = http://girder:8080/api/v1 2023-04-04 20:22:55,909 - INFO - luna.common.utils - -> Set username (<class 'str'>) = ***** 2023-04-04 20:22:55,910 - INFO - luna.common.utils - -> Set password (<class 'str'>) = ***** 2023-04-04 20:22:55,912 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:22:55,913 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:22:55,915 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:55,915 - INFO - luna.common.utils - Starting transform::upload_annotation_to_dsa 2023-04-04 20:22:55,915 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:56,169 - INFO - luna.pathology.dsa.dsa_api_handler - Successfully connected to DSA 2023-04-04 20:22:56,195 - INFO - luna.pathology.dsa.dsa_api_handler - Found collection id=642b13a033dd668f85bbc1ee for collection=TCGA collection 2023-04-04 20:22:56,204 - WARNING - luna.pathology.dsa.dsa_api_handler - Image file 123.svs not found 2023-04-04 20:22:56,207 - INFO - luna.common.utils - Code block 'transform::upload_annotation_to_dsa' took: 0.28980520798359066s 2023-04-04 20:22:56,208 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:56,208 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:56,208 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:56,210 - INFO - luna.common.utils - Done.
This is a screenshot form HistomicsUI, the high-magnification viewer. You can zoom in and view your annotation results with the desired opacity. As specified in dsa_configs/stardist_polygon_config.yaml
, the red objects are classified as lymphocytes and the green cells are "other" cells.
Upload Stardist cell detection results¶
Here we use cellular detection results generated from Stardist. The x,y coordinates of the cells in the input TSV file will be visualized as a point, as opposed to a more complex polygon that we saw in the previous step with stardist-polygon. You'll notice that the point annotation is faster to upload compared to the polygon represenation of the cells.
We also set fill color alpha value to 0 makes annotation upload faster.
# generate DSA annotation
!dsa stardist-cell \
../dsa_input/test_object_detection.tsv \
--output_dir ../dsa_annotations/stardist_cell \
--annotation_name stardist_cell_segmentations \
--image_filename 123.svs \
--line_colors '{"Other": "rgb(0,255,0)", "Lymphocyte": "rgb(255,0,0)"}' \
--fill_colors '{"Other": "rgba(0,255,0,100)", "Lymphocyte": "rgba(255,0,0,100)"}'
2023-04-04 20:22:58,206 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:22:58,208 - INFO - luna.common.utils - Started CLI Runner wtih <function stardist_cell_main at 0x7f6aa9851c10> 2023-04-04 20:22:58,210 - INFO - luna.common.utils - Validating params... 2023-04-04 20:22:58,212 - INFO - luna.common.utils - -> Set fill_colors (<class 'dict'>) = {'Other': 'rgba(0,255,0,100)', 'Lymphocyte': 'rgba(255,0,0,100)'} 2023-04-04 20:22:58,214 - INFO - luna.common.utils - -> Set line_colors (<class 'dict'>) = {'Other': 'rgb(0,255,0)', 'Lymphocyte': 'rgb(255,0,0)'} 2023-04-04 20:22:58,215 - INFO - luna.common.utils - -> Set annotation_name (<class 'str'>) = stardist_cell_segmentations 2023-04-04 20:22:58,216 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 123.svs 2023-04-04 20:22:58,218 - INFO - luna.common.utils - -> Set output_dir (<class 'str'>) = ../dsa_annotations/stardist_cell 2023-04-04 20:22:58,219 - INFO - luna.common.utils - -> Set input (<class 'str'>) = ../dsa_input/test_object_detection.tsv 2023-04-04 20:22:58,222 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:22:58,223 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:22:58,224 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:58,224 - INFO - luna.common.utils - Starting transform::stardist_cell_main 2023-04-04 20:22:58,224 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:58,235 - INFO - luna.common.utils - Code block 'transform::stardist_cell_main' took: 0.008503869990818202s 2023-04-04 20:22:58,236 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:58,236 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:22:58,236 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:22:58,241 - INFO - luna.common.utils - Done.
# check json annotation
!head ../dsa_annotations/stardist_cell/stardist_cell_segmentations_123.json
{"description": "", "elements": [{"fillColor": "rgba(0,255,0,100)", "lineColor": "rgb(0,255,0)", "lineWidth": 2, "type": "point", "center": [61788.06625424067, 953.4224705647575, 0], "label": {"value": "Other"}}, {"fillColor": "rgba(0,255,0,100)", "lineColor": "rgb(0,255,0)", "lineWidth": 2, "type": "point", "center": [63033.92536419876, 957.214128916384, 0], "label": {"value": "Other"}}, {"fillColor": "rgba(0,255,0,100)", "lineColor": "rgb(0,255,0)", "lineWidth": 2, "type": "point", "center": [64150.069846338054, 957.3538215924966, 0], "label": {"value": "Other"}}], "name": "stardist_cell_segmentations"}
# push annotation to DSA
!dsa_upload http://girder:8080/api/v1 \
--collection_name 'TCGA collection' \
--image_filename 123.svs \
--annotation_filepath ../dsa_annotations/stardist_cell/stardist_cell_segmentations_123.json \
--username admin \
--password password1
2023-04-04 20:23:00,004 - INFO - root - Initalized logger, log file at: luna.log 2023-04-04 20:23:00,006 - INFO - luna.common.utils - Started CLI Runner wtih <function upload_annotation_to_dsa at 0x7fcb7982f1f0> 2023-04-04 20:23:00,008 - INFO - luna.common.utils - Validating params... 2023-04-04 20:23:00,009 - INFO - luna.common.utils - -> Set annotation_filepath (<class 'str'>) = ../dsa_annotations/stardist_cell/stardist_cell_segmentations_123.json 2023-04-04 20:23:00,011 - INFO - luna.common.utils - -> Set collection_name (<class 'str'>) = TCGA collection 2023-04-04 20:23:00,013 - INFO - luna.common.utils - -> Set image_filename (<class 'str'>) = 123.svs 2023-04-04 20:23:00,014 - INFO - luna.common.utils - -> Set dsa_endpoint (<class 'str'>) = http://girder:8080/api/v1 2023-04-04 20:23:00,016 - INFO - luna.common.utils - -> Set username (<class 'str'>) = ***** 2023-04-04 20:23:00,017 - INFO - luna.common.utils - -> Set password (<class 'str'>) = ***** 2023-04-04 20:23:00,019 - INFO - luna.common.utils - Expanding inputs... 2023-04-04 20:23:00,021 - INFO - luna.common.utils - Full segment key set: {} 2023-04-04 20:23:00,022 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:23:00,022 - INFO - luna.common.utils - Starting transform::upload_annotation_to_dsa 2023-04-04 20:23:00,022 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:23:00,267 - INFO - luna.pathology.dsa.dsa_api_handler - Successfully connected to DSA 2023-04-04 20:23:00,294 - INFO - luna.pathology.dsa.dsa_api_handler - Found collection id=642b13a033dd668f85bbc1ee for collection=TCGA collection 2023-04-04 20:23:00,302 - WARNING - luna.pathology.dsa.dsa_api_handler - Image file 123.svs not found 2023-04-04 20:23:00,304 - INFO - luna.common.utils - Code block 'transform::upload_annotation_to_dsa' took: 0.2807252639904618s 2023-04-04 20:23:00,306 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:23:00,306 - INFO - luna.common.utils - Done with transform, running post-transform functions... 2023-04-04 20:23:00,306 - INFO - luna.common.utils - ------------------------------------------------------------ 2023-04-04 20:23:00,308 - INFO - luna.common.utils - Done.
Below is another screenshot from HistomicsUI, from the link printed above. The results are the same as stardist-polygon visualization. Notice the cells are captured more minimally as circles, and not polygons. For rapid prototyping, stardist-cell offers faster annotation upload speed compared to stardist-polygon.
Congratulations! Now you can visualize your annotations and results on DSA platform.