Skip to content

Python API

Wookjin Choi edited this page May 28, 2026 · 1 revision

Python API — atomic core

Every CLI command is a thin wrapper around a re-usable Python API. External libraries (e.g. longitudinal CBCT orchestrators) consume the atomic layer directly instead of shelling out.

Atomic functions

from qradiomics.atomic import (
    load_image_and_mask, preprocess_pair,
    build_extractor, run_extractor, extract_features,
    register_pair, resample_to_fixed, histogram_match_hu,
)

# Single atomic unit: one image, one mask -> ~1409 features
image, mask = load_image_and_mask("planCT.nrrd", "Heart-label.nrrd")
cropped_img, cropped_msk = preprocess_pair(image, mask, pad_mm=20, resample_mm=1.0)
extractor = build_extractor(image_types=["Original", "LoG", "Wavelet"])
features = run_extractor(extractor, cropped_img, cropped_msk)

Hierarchical cohort model

qradiomics.data_model mirrors the canonical hierarchy used across the Choi-Lab ecosystem:

Cohort → Patient → TreatmentCourse → Study → ImageSeries / RTStructureSet → ROI
                       (optional)

Diagnostic-only cohorts omit TreatmentCourse and attach Study directly to Patient. flatten_cohort() walks the tree into a list of AtomicUnits — one per (image, mask) pair — which becomes the manifest CSV consumed by qr extract.

from qradiomics.data_model import (
    Cohort, Patient, TreatmentCourse, Study,
    ImageSeries, RTStructureSet, ROI,
    AtomicUnit, Modality, StudyType, save_cohort, load_cohort,
)
from qradiomics.manifest import flatten_cohort, read_manifest, write_manifest

cohort = Cohort(cohort_id="lng-cbct")
patient = Patient(patient_id="P001")
course = TreatmentCourse(course_id="rt1", fractions=30, prescription_dose_gy=60.0)
study = Study(study_id="S-week4", timepoint="week4", relative_day=28)
study.series["CBCT"] = ImageSeries(series_id="CBCT-w4",
    image_path="/data/CBCT_w4.nrrd", modality=Modality.CBCT, image_tag="CBCT-w4")
rs = RTStructureSet(rtstruct_id="rs", referenced_series_uid="...")
rs.rois["GTV"] = ROI(roi_id="GTV", mask_path="/data/GTV-label.nrrd",
                     mask_tag="manual", mask_image_tag="CBCT-w4")
study.structure_sets["rs"] = rs
course.studies[study.study_id] = study
patient.treatment_courses[course.course_id] = course
cohort.patients[patient.patient_id] = patient

units = flatten_cohort(cohort)            # list[AtomicUnit]
write_manifest(units, "manifest.csv")     # canonical 10-column schema
save_cohort(cohort, "cohort.yaml")        # full graph persistence

The manifest is the bridge: the CLI, Nextflow, JeffLungRadiomics, or any external script can consume it without the Python model.

Delta / longitudinal

from qradiomics.delta import DeltaPair, compute_delta, compute_trend
from qradiomics.io.dicom import read_pet_suv

compute_delta produces per-patient A − B feature deltas; compute_trend fits a slope across timepoints.

Shape descriptors

See Shape Analysis for the qradiomics.shape API (AHSN 2014 + spiculation 2021).

Clone this wiki locally