RIDER inventory & preflight — scripts/rider_preflight.py (9-stage: scan, classify CT/SEG, group acquisitions, select reconstructions, pair repeats, resolve SEG refs, evaluate geometry, assess usability) |
DICOM object classification; Study/Series grouping; reconstruction selection; test–retest pairing |
1, 2 |
Real patient-level data handling; the data boundary in practice |
DICOM metadata inspection — rider_preflight.py (Series/Study/FoR UIDs, kernel, kVp, SliceThickness, ImageType, PixelSpacing, IOP/IPP) |
The DICOM hierarchy & identifiers; kernel/thickness as variables |
1 |
The contract (metadata) you must read before the payload (pixels) |
CT/SEG linkage — rider_preflight.py build_seg_meta() / resolve_seg_references(); seg_decode_resample.py decode_seg_file() / build_source_mask_on_ct_grid() |
Source-image references; per-frame functional groups; segment identity |
2 |
How a SEG names its source CT and why matching is by SOP UID, not assumption |
Geometry validation — seg_decode_resample.py compute_slice_normal(), build_affine(), project_position(), orientations_equivalent(), spacings_equivalent(), positions_equivalent(); load_ct_volume_explicit() |
Direction cosines; slice normal; geometric ordering; EXACT_GRID vs RESAMPLED |
2 |
The whole Part A/B of Ch. 2, implemented and tested |
HU conversion — seg_decode_resample.py load_ct_volume_explicit() (pixel*slope+intercept); rider_radiomics_extraction.py clip_intensities() (clip [-1000,+400]) |
RescaleSlope/Intercept; working in physical HU |
1, 3 |
Never use stored pixels as HU; clip before features |
Mask transfer & resampling — seg_decode_resample.py resample_mask_inverse_nn(), compute_source_mask_clipping(), classify_transfer_pair(), verify_determinism(); rider_radiomics_extraction.py resample_image_isotropic() (BSpline→1mm), resample_mask_nn(), affine_to_sitk_geometry() |
Linear vs nearest-neighbour; inverse NN; determinism; SimpleITK bridge |
2 |
Masks resample differently from images; same shape ≠ same space |
PyRadiomics extraction — rider_radiomics_extraction.py extract_joint_entropy(), run_extraction(); configs/pyradiomics_params.yaml (binWidth 25, original, 3D, label 1) |
The radiomics pipeline; pinned preprocessing; GLCM Joint Entropy |
3 |
One feature, done end-to-end reproducibly — the Ch. 3 exercise |
Determinism / independent-process comparison — rider_radiomics_extraction.py check_determinism; compare_radiomics_runs.py |
Reproducibility of the numbers before any statistics |
3, 4 |
A feature table must be bitwise-reproducible across runs |
Visual QC in 3D Slicer — tools/slicer/open_qc_bundle.py (2×3 layout, lung window); scripts/visual_qc/* (qc_bundle.py, export_rider_qc.py, generate_report.py, record_review.py, aggregate_qc_reviews.py); schemas/visual-qc-bundle-v1.schema.json |
Visual QC as real, auditable geometry/overlay verification |
2, 3 |
See the geometry concepts in a viewer; record a defensible verdict |
Dependency / environment validation — scripts/dependency_compute_smoke.py (numpy/pandas/pydicom/PyRadiomics/SimpleITK; sklearn MICE; CatBoost CPU/GPU; lifelines CoxPH+C-index; CTGAN; TabDDPM upstream; PyTorch diffusion primitives) |
A reproducible compute stack; tabular + survival tooling |
4 |
Strong tabular baselines and survival models are first-class, not afterthoughts |
Clinical tabular loader & missingness — scripts/clinical_loader.py (NSCLC frozen fields, per-field missingness); results/metrics/nsclc-radiomics-clinical-profile.json |
Survival/tabular data; missingness as a variable |
4 |
The clinical baseline imaging must beat; honest missingness handling |