Skip to main content

OmiCoreTumorDetector

Tumour-region mapping for colorectal cancer H&E histopathology.

omicore-tumordetector-crc-he-v0.1 takes an H&E image of colon tissue and returns a per-tile tumour probability map, a binary tumour mask, and polygon annotations that open directly in QuPath.

⚠️ RESEARCH USE ONLY. Not a medical device. Not cleared or approved by any regulatory authority. Must not be used for diagnosis or clinical decisions.

Validation 5 Visium HD colorectal sections, independent of all training data
Tumour sections 27.7% – 48.5% of tissue called tumour
Normal controls 0.08% and 1.82%; zero tumour regions exported
Molecular agreement AUROC 0.9855 vs Visium HD transcriptomics (Cancer_P1)

Full write-up: OmiCoreTumorDetector_preprint.pdf · MODEL_CARD.md · FINDINGS.md


1. Install

pip install omicoretumordetector

Or install the latest code straight from GitHub:

pip install "git+https://github.com/OmiCore-Japan/omicoretumordetector.git"

Or clone it for development:

git clone https://github.com/OmiCore-Japan/omicoretumordetector.git
cd omicoretumordetector
pip install -e .

PyTorch

pip installs a default PyTorch build. Check it sees your GPU:

python -c "import torch; print(torch.__version__, torch.cuda.is_available())"

If it prints False but you have an NVIDIA GPU, install a CUDA build:

pip install --force-reinstall torch --index-url https://download.pytorch.org/whl/cu128

RTX 50-series (Blackwell, e.g. 5070/5080/5090) must use cu128 or newer. The default cu121 wheels do not support compute capability sm_120 and will fail at runtime. This is the most common installation problem.

CPU works but is slow: a 13,000 × 13,000 px section takes minutes on CPU versus about 50 s on one RTX 5080.


2. Get the model weights

Weights are ~400 MB and exceed GitHub's 100 MB per-file limit, so they are release assets, not files in this repository.

They download automatically the first time you load the model — you do not normally need to do anything:

from omicoretumordetector import TumorDetector
det = TumorDetector.from_pretrained()   # downloads ~300 MB once, then cached

Cached in ~/.cache/omicoretumordetector/ (override with OMICORETUMORDETECTOR_HOME). Downloads are SHA-256 verified.

omicoretumordetector models        # list weights and show what is cached
omicoretumordetector clear-cache   # delete them
Offline or air-gapped machines

Download the four .pt files from the Releases page on a connected machine, copy them across, then place them in the cache directory:

mkdir -p ~/.cache/omicoretumordetector
cp omicore-tumordetector-crc-he-*.pt ~/.cache/omicoretumordetector/
omicoretumordetector models        # should now show [cached]

Or point the package at any URL or local mirror:

export OMICORETUMORDETECTOR_WEIGHTS_URL="file:///data/omicoretumordetector-weights"

3. Use it

Python

from omicoretumordetector import TumorDetector

det = TumorDetector.from_pretrained("omicore-tumordetector-crc-he-v0.1")

# mpp = microns per pixel of YOUR image.
# The model expects 0.5; other values are rescaled automatically.
res = det.predict("colon_section.tiff", mpp=0.5)

print(f"tumour area  : {res['tumor_fraction']:.1%}")
print(f"tissue tiles : {res['n_tissue_tiles']:,}")

mask = det.tumor_mask(res, threshold=0.4)                    # HxW uint8
det.to_geojson(res, "tumor_regions.geojson", threshold=0.4)  # open in QuPath

Command line

omicoretumordetector predict slide.tiff --mpp 0.5 -o results/
omicoretumordetector predict *.tiff --mpp 0.25 --stride 112 --save-heatmap -o results/

Examples

python examples/quickstart.py  my_section.tiff 0.5
python examples/batch_and_plot.py  ./my_sections/  0.5   # writes PNG overlays

4. Getting mpp right — read this

mpp (microns per pixel) is the one parameter you must supply correctly. Passing the wrong value feeds the model tissue at the wrong magnification and results degrade silently — no error, just poor output.

your image pass
already 0.5 µm/px mpp=0.5
40× scan, typical mpp=0.25
20× scan, typical mpp=0.5
Visium HD he_mpp0.5.tiff mpp=0.5

Find it in your slide metadata (openslide mpp-x, or the scanner's export settings). If your image is smaller than one 224 px tile after rescaling, the package raises an error naming mpp rather than returning an empty result.


5. Output

Nine tissue classes — ADI BACK DEB LYM MUC MUS NORM STR TUM — where TUM is colorectal adenocarcinoma epithelium and NORM is normal colon mucosa.

key meaning
p_tumor tumour probability per 224 px tile
prob all nine class probabilities, (rows, cols, 9)
tissue tiles containing tissue (glass is skipped)
tumor_fraction fraction of tissue tiles above 0.5
xs, ys, scale tile geometry and the factor back to source pixels

det.tissue_composition(res) returns the fraction of tissue assigned to each class — useful as a sanity check (a colorectal tumour section should be rich in TUM and STR).

GeoJSON coordinates are in your input image's pixel space, so annotations line up when loaded over the original slide.


6. Choosing a threshold

Default 0.4. Do not assume it transfers to your scanner.

A model's probability calibration shifts between stain domains. We measured a single model whose AUROC was unchanged on new slides while its recall at the conventional 0.5 threshold collapsed from 0.92 to 0.48 — the ranking was intact, the threshold was simply wrong. It looked highly precise while discarding half the tumour.

If you have any labelled tissue, sweep the threshold on it. If you have none, start at 0.4, inspect the overlays, and adjust: lower catches more tumour, higher is more conservative.

threshold="auto" calibrates from the slide's own distribution, but it assumes tumour is present and fabricates regions on tumour-free tissue (it called 39% of a lung section colorectal tumour). It is gated behind TumorDetector(..., allow_auto_threshold=True) and must not be used to decide whether a slide has tumour.


7. Limitations — please read before using results

  • Regions, not cells. Boundaries resolve at 224 px (112 µm), so a called region contains stroma, immune and vascular cells alongside malignant glands. Use stride=112 for finer edges at ~4× the compute. This model supports "localises tumour-enriched regions"; it does not support "identifies malignant cells".
  • Validation is small. Three tumour and two normal sections from one cohort, with matched transcriptomics for one. That is feasibility, not generalisation across patients, scanners or histological variants.
  • Colorectal only. Lung and prostate were negative controls and produced 8.9% and 1.7% spurious tumour area; other organs are unsupported.
  • Untested tissue types: adenoma, dysplasia, inflammation, ulceration, necrosis, mucinous variants, treated tissue.
  • The internal validation figure (99.8%) is optimistic — NCT-CRC-HE-100K carries no patient IDs, so a random split likely shares patients. Quote the held-out cohorts instead.

8. Repository contents

omicoretumordetector/          the installable package
  api.py               TumorDetector: predict, tumor_mask, to_geojson
  inference.py         sliding-window tiling
  stain.py             Macenko normalisation
  ensemble.py          probability averaging
  weights.py           weight resolution, download, checksum
  cli.py               `omicoretumordetector` command
examples/              runnable scripts
tests/                 pytest suite (runs without weights)
training/              full training + evaluation code, reproduces everything
docs/                  per-section result figures
scripts/               helper to stage locally trained weights
OmiCoreTumorDetector_preprint.pdf  manuscript, 4 multipanel figures
CRC_tumour_detection_report.pdf    per-section performance report
MODEL_CARD.md          intended use, training data, metrics, failure modes
FINDINGS.md            development log: what worked, what was rejected, bugs found
NOTICE                 dataset attribution (CC-BY-4.0 requirements)

Reproduce the whole study (needs the public datasets, ~30 GB):

bash training/run_experiments.sh

9. Troubleshooting

symptom cause and fix
CUDA error / no kernel image on RTX 50-series install the cu128 PyTorch build (§1)
404 when downloading weights no release published yet; see PUBLISHING.md, or stage weights manually (§2)
checksum mismatch partial download; omicoretumordetector clear-cache and retry
Tumour found everywhere mpp likely wrong, or threshold too low
Nothing found on an obvious tumour mpp likely wrong, or calibration shift — lower the threshold and inspect (§6)
image is NxN px ... smaller than one tile mpp wrong for this image
Very slow running on CPU; check torch.cuda.is_available()

10. Citation and licence

Code is Apache-2.0. Weights are derivative works of CC-BY-4.0 datasets — if you use them you must also credit Kather et al. (2018, 2016) and, for the segmentation model, Shi et al. (2022). Full attribution in NOTICE; citation metadata in CITATION.cff.

Metadata

Release files for omicoretumordetector 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for omicoretumordetector 0.1.0
File Size Uploaded Provenance
omicoretumordetector-0.1.0.tar.gz 27.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for omicoretumordetector 0.1.0
File Interpreter ABI Platform
omicoretumordetector-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 53.4 kB

Release files / omicoretumordetector-0.1.0.tar.gz

Download URL omicoretumordetector-0.1.0.tar.gz
Size 27.8 kB
Tags Source
SHA-256 checksum
How to use checksums
393ea9af17de6abdf03bb0aa94991ee95d4bff45a18d350e92955a71e2ae1922
BLAKE2b-256 checksum
How to use checksums
5a5798b72ec357904646b8f2e1060177c5ddde81e60aa9e25d8a46a7c2f00d1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / omicoretumordetector-0.1.0-py3-none-any.whl

Download URL omicoretumordetector-0.1.0-py3-none-any.whl
Size 25.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab7a93ae884e814ff29008905a3e82cc9ef5e40e7aaf210d27535434114840cc
BLAKE2b-256 checksum
How to use checksums
0d5f242aca33dbbb7e7a3ca216c6e106071b4078d979467b31bd3cea5e5d38a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Security for omicoretumordetector 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page