Calculate and Visualize K-function Statistics¶
from pathlib import Path
import getpass
import pandas as pd
import numpy as np
from ruamel.yaml import YAML
from typing import Any
from IPython.display import Image
Configuration¶
Set global variables that define the slide file we'll be working on, and the directory where our results will be wriiten.
In this example, we'll download a publically available slide from the Kitware
site to a local directory, named with the slide ID. The results of each step will written to separate subdirectories of that folder.
USER = getpass.getuser()
SLIDE_URL = "https://data.kitware.com/api/v1/item/61bcaf8f4acac99f42e95620/download"
SLIDE_ID = "01OV008-308ad404-7079-4ff8-8232-12ee2e"
SLIDE_DIR = f"/gpfs/mskmind_ess/{USER}/tmp/slides/{SLIDE_ID}"
SLIDE = f"{SLIDE_DIR}/{SLIDE_ID}.svs"
WORKDIR = SLIDE_DIR
Download the slide¶
! mkdir -p {SLIDE_DIR}
! [[ -f {SLIDE} ]] || wget -O {SLIDE} --no-check-certificate {SLIDE_URL}
!ls -l {SLIDE}
-rw-r--r-- 1 pollardw pollardw 237047223 Aug 8 13:11 /gpfs/mskmind_ess/pollardw/tmp/slides/01OV008-308ad404-7079-4ff8-8232-12ee2e/01OV008-308ad404-7079-4ff8-8232-12ee2e.svs
from tiffslide import TiffSlide
assert Path(SLIDE).exists()
TiffSlide(Path(SLIDE).open('rb')).dimensions
(53760, 54840)
Dask¶
Luna uses Dask to parallelize many calculations. It's not strictly necessary, but it's helpful to have Dask cluster up before running Luna.
If you set the environment variable LUNA_DASK_SCHEDULER
to the ip:port
address of the Dask scheduler, Luna will use that cluster.
Otherwise, Luna will spin up an ephemeral LocalCluster.
!echo "Dask scheduler:" $LUNA_DASK_SCHEDULER
Dask scheduler: tcp://10.254.130.14:8786
Metadata file¶
Every stage of this processing pipeline writes its output files to its own subfolder of the working directory. A metadata.yml
file is written to each of these, as well, summarizing the parameters of the calculation, along with the input and output files.
This function reads the metadata.yml
file from the given directory and returns a dict representing that metadata. We'll use this to get the output file name for each step.
def read_metadata(dir: str) -> dict[str, Any]:
yaml = YAML(typ="safe")
return yaml.load((Path(dir) / "metadata.yml").read_text())
First, run stardist cell detection + cell measurements¶
- a cell expansion size of
8 um
40 cores
for speedup- we are using a
BRIGHTFIELD_H_DAB
image
from luna.pathology.cli.run_stardist_cell_detection import stardist_simple
STARDIST_DIR = f"{WORKDIR}/stardist_v3"
Path(STARDIST_DIR).mkdir(exist_ok=True)
stardist_simple(
SLIDE,
cell_expansion_size = 8,
image_type = "BRIGHTFIELD_H_DAB",
output_urlpath = STARDIST_DIR,
num_cores = 40,
)
2023-08-24 13:56:14.903 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple_main:120 - Launching QuPath via mskmind/qupath-stardist:current ... 2023-08-24 13:56:14.904 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple_main:121 - volumes=/tmp/tmpqo2l260b/1032a8ab7ba7e154fd346525dd77d4fbddd627ee8664847907250b3f0082c5d4:'/inputs/1032a8ab7ba7e154fd346525dd77d4fbddd627ee8664847907250b3f0082c5d4', /tmp/tmpqo2l260b/1032a8ab7ba7e154fd346525dd77d4fbddd627ee8664847907250b3f0082c5d4:'/output_dir' 2023-08-24 13:56:14.905 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple_main:124 - nano_cpus=40000000000 2023-08-24 13:56:14.906 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple_main:125 - image='mskmind/qupath-stardist:current' 2023-08-24 13:56:14.906 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple_main:126 - command=QuPath script --image /inputs/1032a8ab7ba7e154fd346525dd77d4fbddd627ee8664847907250b3f0082c5d4 --args [cellSize=8,imageType=BRIGHTFIELD_H_DAB,] /scripts/stardist_simple.groovy
Aug 24, 2023 5:56:16 PM java.util.prefs.FileSystemPreferences$1 run INFO: Created user preferences directory. 17:56:16.544 [main] [INFO ] qupath.lib.common.ThreadTools - Setting parallelism to 39 17:56:16.550 [main] [INFO ] qupath.lib.gui.prefs.PathPrefs - Setting default Locale to en_US 17:56:16.551 [main] [INFO ] qupath.lib.gui.prefs.PathPrefs - Setting Locale for FORMAT to en_US 17:56:16.551 [main] [INFO ] qupath.lib.gui.prefs.PathPrefs - Setting Locale for DISPLAY to en_US 17:56:16.577 [main] [INFO ] qupath.ScriptCommand - Setting tile cache size to 16384.00 MB (25.0% max memory) 17:56:16.669 [main] [INFO ] qupath.lib.scripting.QP - Initializing type adapters 17:56:17.878 [main] [INFO ] q.l.i.s.o.OpenslideServerBuilder - OpenSlide version 3.4.1 17:56:18.450 [main] [INFO ] q.l.i.s.b.BioFormatsServerOptions - Setting max Bio-Formats readers to 32 17:56:18.981 [main] [WARN ] q.l.i.s.ImageServerMetadata$ImageResolutionLevel - Calculated downsample values differ for x & y for level 4: x=71.48936170212765 and y=71.40625 - will use value 71.44780585106383 17:56:20.881 [main] [INFO ] stardist_simple - opts=[cellSize:8, imageType:BRIGHTFIELD_H_DAB] 17:56:20.953 [main] [INFO ] stardist_simple - Stains=Color deconvolution stains: Hematoxylin: 0.651 0.701 0.29, DAB: 0.269 0.568 0.778, Residual: 0.633 -0.713 0.302 17:56:21.055 [main] [INFO ] stardist_simple - Running detection... 17:56:33.375 [ForkJoinPool.commonPool-worker-5] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:33.816 [ForkJoinPool.commonPool-worker-36] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:36.429 [ForkJoinPool.commonPool-worker-12] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:38.364 [ForkJoinPool.commonPool-worker-29] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:39.728 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:41.480 [ForkJoinPool.commonPool-worker-10] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:42.869 [ForkJoinPool.commonPool-worker-9] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:43.720 [ForkJoinPool.commonPool-worker-20] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:44.394 [main] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:45.104 [ForkJoinPool.commonPool-worker-37] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:47.889 [ForkJoinPool.commonPool-worker-16] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:48.337 [ForkJoinPool.commonPool-worker-29] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:49.380 [ForkJoinPool.commonPool-worker-3] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:50.429 [ForkJoinPool.commonPool-worker-21] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:51.658 [ForkJoinPool.commonPool-worker-38] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:52.753 [ForkJoinPool.commonPool-worker-23] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:54.151 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 10 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:55.173 [ForkJoinPool.commonPool-worker-33] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:55.811 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:55.910 [ForkJoinPool.commonPool-worker-34] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:56:57.695 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:56:59.229 [ForkJoinPool.commonPool-worker-25] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:01.133 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:02.238 [ForkJoinPool.commonPool-worker-4] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:03.153 [ForkJoinPool.commonPool-worker-3] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:03.397 [ForkJoinPool.commonPool-worker-39] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:05.415 [ForkJoinPool.commonPool-worker-15] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:06.069 [ForkJoinPool.commonPool-worker-31] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:06.799 [ForkJoinPool.commonPool-worker-12] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:06.844 [ForkJoinPool.commonPool-worker-37] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:06.878 [ForkJoinPool.commonPool-worker-16] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:08.407 [ForkJoinPool.commonPool-worker-11] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:10.692 [ForkJoinPool.commonPool-worker-28] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:12.981 [ForkJoinPool.commonPool-worker-9] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:13.805 [ForkJoinPool.commonPool-worker-20] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:14.712 [ForkJoinPool.commonPool-worker-32] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 10 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:15.397 [ForkJoinPool.commonPool-worker-10] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:17.341 [ForkJoinPool.commonPool-worker-34] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:19.012 [ForkJoinPool.commonPool-worker-25] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:20.333 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:21.583 [ForkJoinPool.commonPool-worker-29] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:22.382 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:22.987 [ForkJoinPool.commonPool-worker-11] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:23.596 [ForkJoinPool.commonPool-worker-12] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:23.709 [ForkJoinPool.commonPool-worker-28] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 6 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:25.010 [ForkJoinPool.commonPool-worker-24] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:25.504 [ForkJoinPool.commonPool-worker-19] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:26.393 [ForkJoinPool.commonPool-worker-31] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:27.802 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:28.305 [ForkJoinPool.commonPool-worker-5] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:31.396 [ForkJoinPool.commonPool-worker-25] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:31.771 [ForkJoinPool.commonPool-worker-4] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:34.540 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:35.323 [ForkJoinPool.commonPool-worker-38] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:36.231 [ForkJoinPool.commonPool-worker-22] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:38.229 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:38.826 [ForkJoinPool.commonPool-worker-35] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:40.182 [ForkJoinPool.commonPool-worker-15] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:40.546 [ForkJoinPool.commonPool-worker-20] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:41.305 [ForkJoinPool.commonPool-worker-5] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:41.449 [ForkJoinPool.commonPool-worker-33] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:49.769 [ForkJoinPool.commonPool-worker-13] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:49.783 [ForkJoinPool.commonPool-worker-28] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:51.200 [ForkJoinPool.commonPool-worker-20] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:52.306 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:52.876 [ForkJoinPool.commonPool-worker-15] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:53.372 [ForkJoinPool.commonPool-worker-32] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:57:54.207 [ForkJoinPool.commonPool-worker-6] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:54.361 [ForkJoinPool.commonPool-worker-8] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:57:56.050 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:01.078 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:02.172 [ForkJoinPool.commonPool-worker-4] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:03.031 [ForkJoinPool.commonPool-worker-24] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:03.208 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:04.080 [ForkJoinPool.commonPool-worker-30] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:04.384 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:06.123 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:07.076 [ForkJoinPool.commonPool-worker-28] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 13 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:10.524 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:12.861 [ForkJoinPool.commonPool-worker-27] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:15.124 [ForkJoinPool.commonPool-worker-36] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:15.577 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:16.924 [ForkJoinPool.commonPool-worker-8] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:17.927 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:18.305 [ForkJoinPool.commonPool-worker-32] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:20.666 [ForkJoinPool.commonPool-worker-20] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:21.115 [ForkJoinPool.commonPool-worker-37] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:21.929 [ForkJoinPool.commonPool-worker-11] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:26.771 [ForkJoinPool.commonPool-worker-39] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:27.142 [ForkJoinPool.commonPool-worker-31] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:28.543 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 6 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:29.348 [ForkJoinPool.commonPool-worker-1] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:29.349 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:29.751 [ForkJoinPool.commonPool-worker-30] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:30.364 [ForkJoinPool.commonPool-worker-13] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:35.099 [ForkJoinPool.commonPool-worker-12] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:36.947 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:37.628 [ForkJoinPool.commonPool-worker-29] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:39.388 [ForkJoinPool.commonPool-worker-8] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:39.694 [ForkJoinPool.commonPool-worker-36] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:40.757 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:41.853 [ForkJoinPool.commonPool-worker-32] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:47.380 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:48.978 [ForkJoinPool.commonPool-worker-39] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:50.588 [ForkJoinPool.commonPool-worker-32] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:50.764 [ForkJoinPool.commonPool-worker-1] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:51.901 [ForkJoinPool.commonPool-worker-19] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:58:56.377 [ForkJoinPool.commonPool-worker-20] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:58:57.121 [ForkJoinPool.commonPool-worker-6] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:01.366 [ForkJoinPool.commonPool-worker-8] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:02.395 [ForkJoinPool.commonPool-worker-9] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:03.362 [ForkJoinPool.commonPool-worker-35] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:05.796 [ForkJoinPool.commonPool-worker-10] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:06.361 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:09.701 [ForkJoinPool.commonPool-worker-28] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:11.892 [ForkJoinPool.commonPool-worker-13] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:12.699 [ForkJoinPool.commonPool-worker-4] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:14.037 [ForkJoinPool.commonPool-worker-31] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 7 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:15.094 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:15.470 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:17.463 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:17.624 [ForkJoinPool.commonPool-worker-23] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:19.273 [ForkJoinPool.commonPool-worker-37] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:19.375 [ForkJoinPool.commonPool-worker-27] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:19.512 [ForkJoinPool.commonPool-worker-22] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:21.962 [ForkJoinPool.commonPool-worker-10] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:23.506 [ForkJoinPool.commonPool-worker-29] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:25.265 [ForkJoinPool.commonPool-worker-6] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:27.021 [ForkJoinPool.commonPool-worker-27] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:29.792 [ForkJoinPool.commonPool-worker-21] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:29.949 [ForkJoinPool.commonPool-worker-37] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:30.794 [ForkJoinPool.commonPool-worker-34] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:32.568 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:33.623 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:35.228 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:38.137 [ForkJoinPool.commonPool-worker-28] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:39.291 [ForkJoinPool.commonPool-worker-24] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:39.522 [ForkJoinPool.commonPool-worker-1] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:39.865 [ForkJoinPool.commonPool-worker-34] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:45.389 [ForkJoinPool.commonPool-worker-25] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 7 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:46.931 [ForkJoinPool.commonPool-worker-5] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:48.946 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:53.353 [ForkJoinPool.commonPool-worker-10] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:55.076 [ForkJoinPool.commonPool-worker-1] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:57.069 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:57.742 [ForkJoinPool.commonPool-worker-21] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 17:59:58.214 [ForkJoinPool.commonPool-worker-4] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 11 nuclei due to error in resolving overlaps (0% of all skipped) 17:59:58.377 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:01.055 [ForkJoinPool.commonPool-worker-24] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:06.415 [ForkJoinPool.commonPool-worker-10] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:06.642 [ForkJoinPool.commonPool-worker-12] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:06.679 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 4 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:07.886 [ForkJoinPool.commonPool-worker-38] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 5 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:14.402 [ForkJoinPool.commonPool-worker-19] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:15.710 [ForkJoinPool.commonPool-worker-32] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:15.890 [ForkJoinPool.commonPool-worker-8] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:15.896 [ForkJoinPool.commonPool-worker-27] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 3 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:17.705 [ForkJoinPool.commonPool-worker-4] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 7 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:18.374 [ForkJoinPool.commonPool-worker-24] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:19.441 [ForkJoinPool.commonPool-worker-2] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:19.757 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:22.369 [ForkJoinPool.commonPool-worker-19] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:24.219 [ForkJoinPool.commonPool-worker-18] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:24.820 [ForkJoinPool.commonPool-worker-14] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:24.986 [ForkJoinPool.commonPool-worker-39] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:25.138 [ForkJoinPool.commonPool-worker-15] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:27.613 [ForkJoinPool.commonPool-worker-17] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:27.785 [ForkJoinPool.commonPool-worker-30] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:29.694 [ForkJoinPool.commonPool-worker-33] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:30.337 [ForkJoinPool.commonPool-worker-26] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:32.446 [ForkJoinPool.commonPool-worker-24] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:00:32.828 [ForkJoinPool.commonPool-worker-31] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 1 nucleus due to error in resolving overlaps (0% of all skipped) 18:00:37.588 [ForkJoinPool.commonPool-worker-33] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 2 nuclei due to error in resolving overlaps (0% of all skipped) 18:01:29.888 [main] [WARN ] qupath.ext.stardist.StarDist2D - Skipped 19 nuclei due to error in resolving overlaps (0.5% of all skipped) 18:06:33.607 [main] [INFO ] stardist_simple - Filtering detections Nucleus: Area µm^2 <= 10 or >= 200 ... 18:06:35.782 [main] [INFO ] stardist_simple - Started writing cell object data... 18:07:15.488 [main] [INFO ] stardist_simple - Started writing cell object geojson... 18:10:31.020 [main] [INFO ] stardist_simple - Done
2023-08-24 14:10:44.528 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple:67 - generated cell data: 2023-08-24 14:10:44.530 | INFO | luna.pathology.cli.run_stardist_cell_detection:stardist_simple:68 - Image \ cell_id cell-0 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-1 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-2 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-3 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-4 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... ... ... cell-726396 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-726397 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-726398 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-726399 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... cell-726400 1032a8ab7ba7e154fd346525dd77d4fbddd627ee866484... Object ID Name Class \ cell_id cell-0 b43d6127-6beb-4379-b77f-31d2e4bcc657 PathCellObject NaN cell-1 c8f6c62a-dac8-4043-98e2-f7261eb1e24e PathCellObject NaN cell-2 a26e77c8-0ac0-4ae3-8953-6b9252ba385f PathCellObject NaN cell-3 9a48bfc5-99ce-4e93-b01e-81f3a5e92b7a PathCellObject NaN cell-4 cd1440fd-62bf-45a1-a731-ed3cf053dd5b PathCellObject NaN ... ... ... ... cell-726396 a7e10b7a-565f-431a-af79-dd29f15987ab PathCellObject NaN cell-726397 c9843ae3-7a76-4db5-95a9-8a14a863d293 PathCellObject NaN cell-726398 ea153b20-8476-468d-aeb7-d965612487f6 PathCellObject NaN cell-726399 8b0bfe3e-c382-47a6-b576-47c38a150461 PathCellObject NaN cell-726400 a5aac359-becb-405d-97bd-2d9c31ae9f45 PathCellObject NaN Parent ROI x_coord y_coord \ cell_id cell-0 PathAnnotationObject Polygon 8775.3 1375.1 cell-1 PathAnnotationObject Polygon 8961.7 1373.2 cell-2 PathAnnotationObject Polygon 8877.8 1375.1 cell-3 PathAnnotationObject Polygon 8804.5 1374.7 cell-4 PathAnnotationObject Polygon 8750.7 1374.8 ... ... ... ... ... cell-726396 PathAnnotationObject Polygon 2209.2 12341.6 cell-726397 PathAnnotationObject Polygon 2245.0 12342.2 cell-726398 PathAnnotationObject Polygon 2155.3 12342.0 cell-726399 PathAnnotationObject Polygon 2187.4 12342.2 cell-726400 PathAnnotationObject Polygon 2267.6 12342.7 Detection probability Nucleus: Area µm^2 ... \ cell_id ... cell-0 0.5542 10.6223 ... cell-1 0.8864 16.4438 ... cell-2 0.7865 18.8679 ... cell-3 0.2502 12.5845 ... cell-4 0.4294 24.3945 ... ... ... ... ... cell-726396 0.5134 10.3359 ... cell-726397 0.5606 10.7447 ... cell-726398 0.9003 14.3887 ... cell-726399 0.6922 11.7472 ... cell-726400 0.4705 12.7017 ... DAB: Membrane: Mean DAB: Membrane: Median DAB: Membrane: Min \ cell_id cell-0 0.0893 0.0827 0.0213 cell-1 0.0949 0.0817 0.0279 cell-2 0.0964 0.0783 0.0148 cell-3 0.0648 0.0594 0.0175 cell-4 0.0802 0.0723 0.0225 ... ... ... ... cell-726396 0.2037 0.1934 0.1169 cell-726397 0.1674 0.1591 0.0632 cell-726398 0.0754 0.0349 0.0085 cell-726399 0.1951 0.1888 0.0740 cell-726400 0.1482 0.1455 0.0721 DAB: Membrane: Max DAB: Membrane: Std.Dev. DAB: Cell: Mean \ cell_id cell-0 0.1909 0.0404 0.1038 cell-1 0.2237 0.0534 0.1213 cell-2 0.3391 0.0551 0.1259 cell-3 0.1455 0.0254 0.0671 cell-4 0.1970 0.0392 0.0865 ... ... ... ... cell-726396 0.4600 0.0706 0.2081 cell-726397 0.3666 0.0789 0.1755 cell-726398 0.3376 0.0823 0.0769 cell-726399 0.4335 0.0859 0.2157 cell-726400 0.2597 0.0534 0.1613 DAB: Cell: Median DAB: Cell: Min DAB: Cell: Max \ cell_id cell-0 0.0994 0.0201 0.3027 cell-1 0.1273 0.0279 0.2284 cell-2 0.1027 -0.0353 0.4410 cell-3 0.0600 -0.0052 0.1821 cell-4 0.0825 -0.0172 0.2069 ... ... ... ... cell-726396 0.1953 0.0804 0.4600 cell-726397 0.1726 0.0599 0.3666 cell-726398 0.0362 0.0077 0.3376 cell-726399 0.2025 0.0740 0.4335 cell-726400 0.1634 0.0721 0.2597 DAB: Cell: Std.Dev. cell_id cell-0 0.0471 cell-1 0.0546 cell-2 0.0768 cell-3 0.0320 cell-4 0.0423 ... ... cell-726396 0.0671 cell-726397 0.0680 cell-726398 0.0758 cell-726399 0.0845 cell-726400 0.0499 [726401 rows x 62 columns] 2023-08-24 14:12:17.312 | INFO | luna.pathology.common.utils:fix_geojson_file:648 - cell_detections.geojson looks like valid GeoJSON 2023-08-24 14:12:22.411 | DEBUG | luna.common.utils:wrapper:146 - stardist_simple ran in 969.08s
If we look at the output directory, we can see that QuPath has written .geojson
and .tsv
files for the identified cells, in addition to the .parquet
file from luna.
!ls -l {STARDIST_DIR}
total 3983041 -rw-r--r-- 1 pollardw pollardw 117753516 Aug 24 14:10 01OV008-308ad404-7079-4ff8-8232-12ee2e_cell_objects.parquet -rw-r--r-- 1 root root 3569281096 Aug 24 14:10 cell_detections.geojson -rw-r--r-- 1 root root 391564517 Aug 24 14:07 cell_detections.tsv -rw-r--r-- 1 pollardw pollardw 930 Aug 24 14:12 metadata.yml
stardist = read_metadata(STARDIST_DIR)
cell_objects_file = stardist.get("cell_objects")
df = pd.read_parquet(cell_objects_file)
df.columns
Index(['Image', 'Object ID', 'Name', 'Class', 'Parent', 'ROI', 'x_coord', 'y_coord', 'Detection probability', 'Nucleus: Area µm^2', 'Nucleus: Length µm', 'Nucleus: Circularity', 'Nucleus: Solidity', 'Nucleus: Max diameter µm', 'Nucleus: Min diameter µm', 'Cell: Area µm^2', 'Cell: Length µm', 'Cell: Circularity', 'Cell: Solidity', 'Cell: Max diameter µm', 'Cell: Min diameter µm', 'Nucleus/Cell area ratio', 'Hematoxylin: Nucleus: Mean', 'Hematoxylin: Nucleus: Median', 'Hematoxylin: Nucleus: Min', 'Hematoxylin: Nucleus: Max', 'Hematoxylin: Nucleus: Std.Dev.', 'Hematoxylin: Cytoplasm: Mean', 'Hematoxylin: Cytoplasm: Median', 'Hematoxylin: Cytoplasm: Min', 'Hematoxylin: Cytoplasm: Max', 'Hematoxylin: Cytoplasm: Std.Dev.', 'Hematoxylin: Membrane: Mean', 'Hematoxylin: Membrane: Median', 'Hematoxylin: Membrane: Min', 'Hematoxylin: Membrane: Max', 'Hematoxylin: Membrane: Std.Dev.', 'Hematoxylin: Cell: Mean', 'Hematoxylin: Cell: Median', 'Hematoxylin: Cell: Min', 'Hematoxylin: Cell: Max', 'Hematoxylin: Cell: Std.Dev.', 'DAB: Nucleus: Mean', 'DAB: Nucleus: Median', 'DAB: Nucleus: Min', 'DAB: Nucleus: Max', 'DAB: Nucleus: Std.Dev.', 'DAB: Cytoplasm: Mean', 'DAB: Cytoplasm: Median', 'DAB: Cytoplasm: Min', 'DAB: Cytoplasm: Max', 'DAB: Cytoplasm: Std.Dev.', 'DAB: Membrane: Mean', 'DAB: Membrane: Median', 'DAB: Membrane: Min', 'DAB: Membrane: Max', 'DAB: Membrane: Std.Dev.', 'DAB: Cell: Mean', 'DAB: Cell: Median', 'DAB: Cell: Min', 'DAB: Cell: Max', 'DAB: Cell: Std.Dev.'], dtype='object')
Calculate K-function statistics¶
We will use...
- a sliding window of size 1000 with a stride of 300,
- a radius of 160 um, for
- the nucleus-size values determined by Stardist.
from luna.pathology.cli.extract_kfunction_statistics import cli as extract_kfunction_cli
KFUNCT_DIR = f"{WORKDIR}/kfunct_v3"
Path(KFUNCT_DIR).mkdir(exist_ok=True)
extract_kfunction_cli(
input_cell_objects_urlpath = cell_objects_file,
tile_size = 1000,
intensity_label = 'Nucleus: Area µm^2',
tile_stride = 300,
radius = 160,
output_urlpath = KFUNCT_DIR,
)
2023-08-24 14:12:24.791 | INFO | luna.pathology.cli.extract_kfunction_statistics:extract_kfunction:112 - Submitting tasks...
0%| | 0/1332 [00:00<?, ?it/s]
2023-08-24 14:13:27.065 | INFO | luna.pathology.cli.extract_kfunction_statistics:extract_kfunction:134 - Waiting for all tasks to complete... 2023-08-24 14:13:27.396 | INFO | luna.pathology.cli.extract_kfunction_statistics:extract_kfunction:157 - Generated k-function feature data: 2023-08-24 14:13:27.397 | INFO | luna.pathology.cli.extract_kfunction_statistics:extract_kfunction:158 - x_coord y_coord xy_extent tile_size tile_units \ address x1345_y1373 1345 1373 1000 1000 um x1345_y1673 1345 1673 1000 1000 um x1345_y1973 1345 1973 1000 1000 um x1345_y2273 1345 2273 1000 1000 um x1345_y2573 1345 2573 1000 1000 um ... ... ... ... ... ... x11845_y7673 11845 7673 1000 1000 um x11845_y7973 11845 7973 1000 1000 um x11845_y8273 11845 8273 1000 1000 um x11845_y8573 11845 8573 1000 1000 um x11845_y8873 11845 8873 1000 1000 um ikfunction_r160_stainNucleus_Area_µm^2 \ address x1345_y1373 56.457229 x1345_y1673 51.470150 x1345_y1973 31.423920 x1345_y2273 20.607933 x1345_y2573 14.636333 ... ... x11845_y7673 11350.075525 x11845_y7973 10747.787163 x11845_y8273 8669.435009 x11845_y8573 8605.517783 x11845_y8873 2077.048000 ikfunction_r160_stainNucleus_Area_µm^2_norm address x1345_y1373 0.002070 x1345_y1673 0.001887 x1345_y1973 0.001152 x1345_y2273 0.000755 x1345_y2573 0.000537 ... ... x11845_y7673 0.416089 x11845_y7973 0.394009 x11845_y8273 0.317818 x11845_y8573 0.315474 x11845_y8873 0.076144 [1177 rows x 7 columns] 2023-08-24 14:13:27.528 | DEBUG | luna.common.utils:wrapper:146 - cli ran in 63.69s
kfunct = read_metadata(KFUNCT_DIR)
slide_tiles_file = kfunct.get("slide_tiles")
pd.read_parquet(slide_tiles_file).columns
Index(['x_coord', 'y_coord', 'xy_extent', 'tile_size', 'tile_units', 'ikfunction_r160_stainNucleus_Area_µm^2', 'ikfunction_r160_stainNucleus_Area_µm^2_norm'], dtype='object')
from luna.pathology.cli.extract_tile_statistics import cli as tile_statistics_cli
TILE_STATS_DIR = f"{WORKDIR}/tile_stats_v3"
Path(TILE_STATS_DIR).mkdir(exist_ok=True)
tile_statistics_cli(
tiles_urlpath = slide_tiles_file,
output_urlpath = TILE_STATS_DIR,
)
2023-08-24 14:13:27.585 | INFO | luna.pathology.cli.extract_tile_statistics:cli:49 - ikfunction_r160_stainNucleus_Area_µm^2_nobs \ 0 1177 ikfunction_r160_stainNucleus_Area_µm^2_mean \ 0 14091.776865 ikfunction_r160_stainNucleus_Area_µm^2_variance \ 0 5.433299e+07 ikfunction_r160_stainNucleus_Area_µm^2_skewness \ 0 -0.412446 ikfunction_r160_stainNucleus_Area_µm^2_kurtosis \ 0 -0.587154 ikfunction_r160_stainNucleus_Area_µm^2_pct0 \ 0 13.815175 ikfunction_r160_stainNucleus_Area_µm^2_pct25 \ 0 10175.257486 ikfunction_r160_stainNucleus_Area_µm^2_pct50 \ 0 14649.920499 ikfunction_r160_stainNucleus_Area_µm^2_pct75 \ 0 19898.098372 ikfunction_r160_stainNucleus_Area_µm^2_pct100 \ 0 27278.014507 ikfunction_r160_stainNucleus_Area_µm^2_norm_nobs \ 0 1177 ikfunction_r160_stainNucleus_Area_µm^2_norm_mean \ 0 0.516598 ikfunction_r160_stainNucleus_Area_µm^2_norm_variance \ 0 0.073019 ikfunction_r160_stainNucleus_Area_µm^2_norm_skewness \ 0 -0.412446 ikfunction_r160_stainNucleus_Area_µm^2_norm_kurtosis \ 0 -0.587154 ikfunction_r160_stainNucleus_Area_µm^2_norm_pct0 \ 0 0.000506 ikfunction_r160_stainNucleus_Area_µm^2_norm_pct25 \ 0 0.37302 ikfunction_r160_stainNucleus_Area_µm^2_norm_pct50 \ 0 0.53706 ikfunction_r160_stainNucleus_Area_µm^2_norm_pct75 \ 0 0.729456 ikfunction_r160_stainNucleus_Area_µm^2_norm_pct100 0 1.0 2023-08-24 14:13:27.598 | DEBUG | luna.common.utils:wrapper:146 - cli ran in 0.03s
Index(['ikfunction_r160_stainNucleus_Area_µm^2', 'ikfunction_r160_stainNucleus_Area_µm^2_norm'], dtype='object')
tile_stats = read_metadata(TILE_STATS_DIR)
feature_data_file = tile_stats.get("feature_data")
pd.read_parquet(feature_data_file).T
0 | |
---|---|
ikfunction_r160_stainNucleus_Area_µm^2_nobs | 1.177000e+03 |
ikfunction_r160_stainNucleus_Area_µm^2_mean | 1.409178e+04 |
ikfunction_r160_stainNucleus_Area_µm^2_variance | 5.433299e+07 |
ikfunction_r160_stainNucleus_Area_µm^2_skewness | -4.124457e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_kurtosis | -5.871537e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_pct0 | 1.381517e+01 |
ikfunction_r160_stainNucleus_Area_µm^2_pct25 | 1.017526e+04 |
ikfunction_r160_stainNucleus_Area_µm^2_pct50 | 1.464992e+04 |
ikfunction_r160_stainNucleus_Area_µm^2_pct75 | 1.989810e+04 |
ikfunction_r160_stainNucleus_Area_µm^2_pct100 | 2.727801e+04 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_nobs | 1.177000e+03 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_mean | 5.165983e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_variance | 7.301937e-02 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_skewness | -4.124457e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_kurtosis | -5.871537e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_pct0 | 5.064582e-04 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_pct25 | 3.730205e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_pct50 | 5.370596e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_pct75 | 7.294555e-01 |
ikfunction_r160_stainNucleus_Area_µm^2_norm_pct100 | 1.000000e+00 |
pd.read_parquet(slide_tiles_file).columns
Index(['x_coord', 'y_coord', 'xy_extent', 'tile_size', 'tile_units', 'ikfunction_r160_stainNucleus_Area_µm^2', 'ikfunction_r160_stainNucleus_Area_µm^2_norm'], dtype='object')
from luna.pathology.cli.visualize_tile_labels_png import cli as visualize_tile_labels_cli
KFUNCT_VIZ_DIR = f"{WORKDIR}/kfunct_viz_v3"
Path(KFUNCT_VIZ_DIR).mkdir(exist_ok=True)
visualize_tile_labels_cli(
slide_urlpath = SLIDE,
tiles_urlpath = slide_tiles_file,
plot_labels = ["ikfunction_r160_stainNucleus_Area_µm^2_norm"],
requested_magnification = 1,
mpp_units = True,
output_urlpath = KFUNCT_VIZ_DIR,
)
2023-08-24 14:13:28.317 | DEBUG | luna.common.utils:wrapper:146 - get_downscaled_thumbnail ran in 0.5s 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1177/1177 [00:01<00:00, 1174.96it/s] 2023-08-24 14:13:29.719 | INFO | luna.pathology.cli.visualize_tile_labels_png:cli:79 - Saved ikfunction_r160_stainNucleus_Area_µm^2_norm visualization at /gpfs/mskmind_ess/pollardw/tmp/slides/01OV008-308ad404-7079-4ff8-8232-12ee2e/kfunct_viz_v3/tile_scores_and_labels_visualization_ikfunction_r160_stainNucleus_Area_µm^2_norm.png 2023-08-24 14:13:29.724 | DEBUG | luna.common.utils:wrapper:146 - cli ran in 2.03s
kfunct_viz = read_metadata(KFUNCT_VIZ_DIR)
image_files = list(kfunct_viz['images'].values())
image_files
['/gpfs/mskmind_ess/pollardw/tmp/slides/01OV008-308ad404-7079-4ff8-8232-12ee2e/kfunct_viz_v3/tile_scores_and_labels_visualization_ikfunction_r160_stainNucleus_Area_µm^2_norm.png']
Image(image_files[0])
Done¶