Skip to main content

croma

PyPI version Documentation Code style: Black License

croma measures how much a pathology foundation model's representation is driven by biology rather than by non-biological technical variation -- staining, scanning, tissue preparation -- across centers.

Metric Name What it does
RI Robustness Index Counts favourable vs. unfavourable neighbours
MaRI Margin-aware Robustness Index Weights that same evidence by feature distance
CRoMa Cross-confounder Robustness Margin A signed margin, with tail-aware reporting

RI was introduced in the PathoROB study. croma provides a clean re-implementation of it, adds MaRI as its margin-aware extension, and introduces CRoMa, which overcomes limitations of both.

📖 Documentation

Install

pip install croma

The core package depends only on numpy, pandas, scikit-learn and tqdm. It never loads a model or reads an image -- you bring the embeddings. Add the paper-reproduction utilities with pip install "croma[repro]".

Quickstart

You need a manifest CSV with one row per sample, and an embeddings array of shape (N, D) whose row i is the embedding of manifest row i. Don't normalize them -- croma L2-normalizes internally and compares neighbours by cosine distance.

import numpy as np
import pandas as pd
from croma import CRoMa, MaRI, RI

manifest = pd.read_csv("manifest.csv")
features = np.load("embeddings.npy")

common = dict(confounder_column="center", evaluation_design="paired_2x2")

ri = RI.compute(features, manifest, k_candidates=[5, 11, 21], **common)
mari = MaRI.compute(features, manifest, k_candidates=[5, 11, 21], **common)
croma = CRoMa.compute(features, manifest, **common)

print(f"RI    {ri.value:.3f}  (k={ri.k}, undefined {ri.undefined_frac:.1%})")
print(f"MaRI  {mari.value:.3f}  (tau={mari.tau:.4f})")
print(f"CRoMa {croma.value:+.3f}  (lower-tail mean {croma.ltm_alpha:+.3f})")

Reading the numbers

RI and MaRI live in [0, 1]; above 0.5, biological evidence outweighs confounder evidence. CRoMa lives in (-1, 1) and is neutral at 0, positive when biology dominates.

Three habits will keep you out of trouble:

  1. Always read undefined_frac next to RI and MaRI. Samples with no informative neighbour in their top k are excluded from the score, so a high RI over a thin support is not a strong result.
  2. Never pin tau. It defaults to None, which resolves it per model on the scale of that model's own neighbour distances. One fixed tau shared across models sharpens the margin for some and flattens it for others -- exactly the distortion MaRI exists to remove. See Choosing tau.
  3. Read the tail, not just the mean. croma.ltm_alpha is the mean of the worst 10% of samples. Pooled scores hide brittle subgroups.

Also in the docs

  • Evaluation designs -- paired_2x2 controls what is compared and reports occurrence-level outputs; dataset_wide gives one number over the whole cohort at sample level. Includes the manifest contract and minimal valid examples for each.
  • CLI -- the same three metrics from the shell, over a .npy that already exists.
  • Benchmarking -- the multi-model pipeline that produced the paper's numbers, split into embed / compute / render steps under scripts/.

Citing

The paper describing MaRI and CRoMa is in preparation. Until it is out, please cite this repository — use the Cite this repository button, or CITATION.cff directly — along with the PathoROB study that introduced the Robustness Index.

License

Apache 2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

croma-0.1.0.tar.gz (1.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

croma-0.1.0-py3-none-any.whl (59.1 kB view details)

Uploaded Python 3

File details

Details for the file croma-0.1.0.tar.gz.

File metadata

  • Download URL: croma-0.1.0.tar.gz
  • Upload date:
  • Size: 1.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for croma-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7b397c84abbe3bb3d1c68e4f7eb7968457d46b75927a905ac3f337b4a344ba8f
MD5 3301613c3e238409e2bbd06ca74b1f38
BLAKE2b-256 c9a6d9c3f27c9c67ddba57af4755a74027e18f4a43ae3f900448599eabe64876

See more details on using hashes here.

File details

Details for the file croma-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: croma-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 59.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for croma-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 563467b7760d60ec61ee414339d4c354585fc00592be6c3a0fb751b3ddf8e5d2
MD5 38a5180597d6362e148a5d12c1b5b52f
BLAKE2b-256 eb39f3830ec5c61392a6abccf5e39077a2fac7b87ede1b263fff7bb9770a4dad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page