diff --git a/examples/predict_tcga_skcm.ipynb b/examples/predict_tcga_skcm.ipynb index afe339c..7158811 100644 --- a/examples/predict_tcga_skcm.ipynb +++ b/examples/predict_tcga_skcm.ipynb @@ -30,15 +30,20 @@ "tiles with mean pixel above 220, predicts the three genes for each tissue tile, and\n", "overlays the predictions on the H&E.\n", "\n", + "To give a sense of scale, this slide is 99,960 x 65,991 px, which is a 446 x 294\n", + "tile grid: 45,751 candidate tiles from the thumbnail pass, of which 36,392 survive\n", + "the exact background filter and are scored by the model.\n", + "\n", "> The TCGA atlas predictions for melanoma were produced with a DeepSpot-M model\n", "> finetuned on melanoma spatial transcriptomics. This tutorial uses the base\n", "> released model in zero-shot mode, so the values are illustrative and the maps\n", "> will look softer than the finetuned atlas.\n", "\n", - "Install with `pip install deepspotm pyvips matplotlib`. pyvips needs the system\n", - "libvips with OpenSlide support. A GPU is recommended. The model weights are gated on\n", - "the Hugging Face Hub, so request access and log in first with `huggingface-cli login`.\n", - "Note that pyvips must be imported before torch." + "Install with `pip install \"deepspotm[wsi]\" matplotlib`, matching the `wsi` extra\n", + "documented in the README. pyvips needs the system libvips with OpenSlide support.\n", + "A GPU is recommended. The model weights are gated on the Hugging Face Hub, so\n", + "request access and log in first with `huggingface-cli login`. Note that pyvips\n", + "must be imported before torch." ] }, { @@ -107,8 +112,13 @@ " print(\"downloading ~1 GB slide from GDC ...\")\n", " urllib.request.urlretrieve(url, SLIDE_PATH)\n", "\n", + "# Hash in 8 MB chunks; reading the whole ~1 GB slide into memory to checksum it\n", + "# would spike RSS by more than the model itself uses.\n", + "digest = hashlib.md5()\n", "with open(SLIDE_PATH, \"rb\") as fh:\n", - " md5 = hashlib.md5(fh.read()).hexdigest()\n", + " for chunk in iter(lambda: fh.read(8 << 20), b\"\"):\n", + " digest.update(chunk)\n", + "md5 = digest.hexdigest()\n", "assert md5 == SLIDE_MD5, f\"checksum mismatch: {md5}\"\n", "print(\"slide ready:\", SLIDE_PATH)" ]