Skip to main content

Thymic quantification toolkit

Project description

thymus-quant

This package lets you quantify thymic tissue contained within the thymic region on human CT images. It implements the framework described in Okamura YT et al., Ann Biomed Eng, 2025. http://dx.doi.org/10.1007/s10439-025-03805-z

Main readouts:

  • $A_{TRQ}$: representative HU value of the thymic region of quantification.
  • $V_{TRQ}$: volume of the thymic region of quantification.
  • Estimated Thymic Volume (ETV): estimated thymic tissue volume in mL.
  • Thymic tissue fraction: fraction of thymic tissue in the thymic region, reported as a 0-1 value.

Main APIs:

  • segment_trq
  • quantify
  • analyze
  • analyze_many

Installation

Recommended installation:

pip install "thymus-quant[segmentation]"

If you already have masks or use your own segmentation model and do not need trqseg_v1 inference:

pip install thymus-quant

Model weights are loaded through the Hugging Face cache unless local_files_only or an explicit local mirror is configured. A local TRQseg-v1 mirror may be set with THYQ_TRQSEG_V1_LOCAL_REPO=/path/to/TRQseg-v1.

Minimal Example

import thymus_quant as tq

result = tq.analyze(
    "case.nii.gz",
    method="okamura",
    segmentor="trqseg_v1",
    study_id="case-001",
)

print(result.thymic_tissue_fraction)
print(result.etv_ml)
print(result.qc.status)

thymic_tissue_fraction is the Thymic Tissue Fraction. It is reported as a 0-1 fraction, not as a percentage. etv_ml and trq_volume_ml are in mL.

Reproducible Model Loading

segmentor = tq.load_segmentor(
    "trqseg_v1",
    revision="<immutable-tested-revision>",
    device="auto",
)

device controls where TRQseg-v1 model inference runs. Supported values are "auto", "cpu", and "cuda". "auto" selects CUDA when PyTorch detects an available CUDA device, and otherwise falls back to CPU.

When weights are loaded from Hugging Face, branch/tag/default revisions are resolved to the underlying commit SHA before download and recorded in result metadata. When all selected weights are loaded from a local git mirror, the local mirror's HEAD commit is recorded instead. The result metadata distinguishes requested and resolved revision and records the weight source (local, downloaded, mixed, or none).

Two-Stage Workflow

seg = tq.segment_trq(
    "case.nii.gz",
    segmentor=segmentor,
)

result = tq.quantify(
    seg,
    method="okamura",
)

segmentor is always explicit. Omitting it never selects the heuristic backend.

Existing Mask

Single external mask:

seg = tq.SegmentationResult.from_mask(
    trq_mask=mask,
    ct_hu=ct_hu,
    spacing_mm=(0.7, 0.7, 1.0),
    study_id="case-001",
)

result = tq.quantify(seg, method="okamura")

Okamura member ensemble:

seg = tq.SegmentationResult.from_member_masks(
    member_masks=[mask0, mask1, mask2, mask3, mask4],
    ct_hu=ct_hu,
    spacing_mm=(0.7, 0.7, 1.0),
    study_id="case-001",
    member_ids=["fold-0", "fold-1", "fold-2", "fold-3", "fold-4"],
)

result = tq.quantify(seg, method="okamura")

Inputs

Accepted image inputs for segmentation are NIfTI path-like values and nibabel spatial images. Existing masks can be supplied with NumPy-compatible arrays via SegmentationResult.from_mask or from_member_masks.

Data contract:

  • CT values must be HU.
  • CT arrays must be 3D.
  • Masks must be 3D bool or binary 0/1 arrays.
  • CT and mask shapes must match exactly.
  • spacing_mm is 3 positive finite values in millimeters.
  • spacing_mm is normalized to Python floats and used for voxel-volume calculation. It is not compared against affine/header spacing.
  • External CT/mask inputs are not resampled, cropped, padded, flipped, or permuted. Shape mismatches raise InputValidationError instead of being repaired automatically.
  • Masked CT voxels must contain at least one finite HU value.
  • DICOM directories are not directly supported by the public API.
  • Orientation is recorded from the affine when available. The package does not silently flip or permute axes.
  • Current TRQseg-v1 preprocessing records input/output shapes and assumes the returned mask is on the input grid. Inputs outside the reference preprocessing domain should be treated cautiously until a pinned regression fixture exists.

Segmentor Options

Built-in aliases:

  • trqseg_v1: DeepLabV3-ResNet50 5-member TRQseg-v1 ensemble.
  • heuristic_trq: debug/experimental heuristic only, not a research model.

Supported options include revision pinning, members/fold selection, device, local_files_only, and cache_dir. Unknown segmentor strings are rejected and are not interpreted as arbitrary Hugging Face repository IDs. Empty, duplicate, negative, or out-of-range members are rejected. Model load failure does not fall back to heuristic_trq.

Result Glossary

  • TRQ: thymic region of quantification.
  • A_TRQ: representative TRQ attenuation used by published formulas.
  • V_TRQ: TRQ volume.
  • Thymic Tissue Fraction: fraction of thymic tissue in the TRQ, usually 0-1.
  • ETV: estimated thymic volume, unit mL.
  • thymic_tissue_fraction: summary Thymic Tissue Fraction for the study.
  • etv_ml: summary ETV in mL.
  • trq_volume_ml: summary TRQ volume in mL.

Okamura member fields are per-member values. Summary fields are ensemble aggregates. QC-invalid members can still retain numeric values; check result.status, result.flags, and result.qc.flags before using them.

QC and Errors

Statuses are intentionally simple:

  • ok: no relevant QC flags.
  • check: numeric values may exist but require review.
  • failed: no computable result.
  • not_available: not applicable.

Important flags include invalid_member, all_members_invalid, used_invalid_members, kde_failed, and ensemble_qc_unavailable.

For the Okamura method, a non-unimodal member distribution is marked invalid with multimodal_or_invalid. By default, any invalid member adds invalid_member and makes the study status check. If at least one member passes QC, the summary uses only QC-valid members. If all members fail QC but still have computable numeric values, the summary uses those invalid members, sets all_members_invalid and used_invalid_members, and remains check.

KDE computation failure is not converted to a fake median mode. Missing spacing does not produce a successful result with NaN volume/ETV output. Single-member analysis can return quantification values, but 5-member paper ensemble criteria are not passed and ensemble_qc_unavailable is set.

failed means at least one member/mask was provided, but no computable Okamura value was produced. not_available means the method had no applicable member/mask to evaluate; this should be uncommon when using the public constructors.

Batch processing preserves input order and records errors with input index:

batch = tq.analyze_many(paths, method="okamura", segmentor=segmentor, on_error="record")
errors = batch.errors_to_frame()

on_error values are raise, record, and skip.

Coming soon: Expanded thymic composition analysis workflows.

Recent work by Chaunzwa et al. introduced an enhanced thymic composition analysis framework that builds upon and extends the methodology currently implemented in this package (Chaunzwa et al., medRxiv, 2025: https://doi.org/10.1101/2025.10.27.25338565, https://doi.org/10.1101/2025.10.20.25338395). Support for this framework is planned for a future release.

Project details


Download files

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

Source Distribution

thymus_quant-0.1.0a1.tar.gz (33.1 kB view details)

Uploaded Source

Built Distribution

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

thymus_quant-0.1.0a1-py3-none-any.whl (29.5 kB view details)

Uploaded Python 3

File details

Details for the file thymus_quant-0.1.0a1.tar.gz.

File metadata

  • Download URL: thymus_quant-0.1.0a1.tar.gz
  • Upload date:
  • Size: 33.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for thymus_quant-0.1.0a1.tar.gz
Algorithm Hash digest
SHA256 4e97be6ec05ac51df8c639e1424ef380530d9e35d640c0c11d0d5fea829441f4
MD5 6e912090f9c8706f5ae1cccbe97bd473
BLAKE2b-256 37e6920e6386fc05d5cb0a3c330dda85cfb01a689c440683ed52e8e916120adb

See more details on using hashes here.

File details

Details for the file thymus_quant-0.1.0a1-py3-none-any.whl.

File metadata

  • Download URL: thymus_quant-0.1.0a1-py3-none-any.whl
  • Upload date:
  • Size: 29.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for thymus_quant-0.1.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 769eeb86e36a1a3dde4939dc34760a02c8f797f55c51f1b7bad9e6777fa7aa3a
MD5 55f0944b086202112847d2ea1a49a4ad
BLAKE2b-256 60c82f063a8d11fcbc4e6989d1e8009df59899c9e59e30dd83bc554e752bd2cc

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 Pingdom Monitoring Sentry Error logging StatusPage Status page