ctkit
CT image processing for AI and radiomics. Makes CT processing simple and reproducible.
Installation
pip install ctkit
To install pyradiomics and TotalSegmentator:
pip install 'ctkit[all]'
Quick start
import ctkit
ctkit.download("tcga-kirc", "data/tcga_kirc_raw", limit=20)
data = ctkit.Dataset("data/tcga_kirc_raw")
data.filter(min_slices=25).process("tcga-kirc", out_dir="data/processed")
# the tcga-kirc protocol segments the kidneys, so this one needs ctkit[all]
The pipeline
| Step | What it does | Why it matters |
|---|---|---|
filter |
Drop series that fail quality control, keeping a pass/fail table | Localizers, reformats and 4D series are not the acquisition you meant to analyze, and finding that out after processing wastes the expensive part |
check |
Run the same quality control without dropping anything: a result for one series, the whole table for a cohort | The measurements behind every pass and fail, which is what an exclusion criterion has to cite |
orient |
Reorient to canonical RAS | Archives disagree on storage order, so two scans of the same anatomy can arrive mirrored or transposed |
segment |
TotalSegmentator organ masks, merged with any tumor mask | Gives a region of interest when the collection ships without one |
clip |
Clamp to an intensity window (e.g. −200/300 HU) | Spends the dynamic range on the tissue you care about; caps metal artifacts |
resample |
Resample to a fixed voxel size in mm | Until scans share a voxel grid, a millimeter of anatomy is a different number of voxels in each one |
select_slice |
Keep one axial slice: the one with the most mask, or the one you name (2D mode) | How a 3D series becomes a 2D training example |
apply_mask |
Blank outside the ROI, crop to its bounding box | Removes irrelevant anatomy and makes volumes small enough to hold a cohort in memory |
crop_to_content |
Crop to the voxels above a threshold — air, once intensities are clipped | Trims the air around the body when there is no mask to crop to |
standardize_size |
Center-crop/pad to a common array shape | Fixed-size tensors, without rescaling the anatomy |
normalize |
Z-score, per volume or per dataset | Stops a model keying on per-scan intensity offsets |
save |
Write the processed series to disk | Makes the processed dataset available for training and sharing |
process |
Run the whole pipeline, with a saved configuration | Reproducibility and collaboration |
radiomics |
Extract radiomics features | For radiomic analysis. Does not require many steps above. |
Reproducibility
Every run that writes a cohort to disk writes processing_config.yaml next to
it. To reproduce a dataset, or to hand one to a collaborator:
ctkit.Dataset("data/raw").process(
"data/processed/processing_config.yaml", out_dir="rerun"
)
process takes a protocol as a ProcessingConfig, a path to a saved one, or
the name of a collection whose curated protocol to use.
Notebooks
notebooks/quickstart.ipynb walks through the
package end to end: pick a collection, download it, filter it, process it, and
extract features.
notebooks/scanner_confounding.ipynb is
the argument for the pipeline. A cohort is built on two scanners whose patient
populations differ, so the scanner correlates with the label. A classifier
trained on the raw volumes scores 0.89 on held-out data from the same study and
0.58 at another hospital, and on that external set its answers agree with the
scanner 88% of the time — it learned the machine, and internal validation
could not tell. The same classifier on the same scans put through a ctkit
protocol scores 0.96 externally. One ablation per step shows what each is
worth, and what preprocessing cannot fix. Runs in a few minutes, no GPU or
download needed.
Relationship to tcia-radiology-processing
This package grew out of the protocol in
pachterlab/tcia-radiology-processing,
which documents the same pipeline as a step-by-step notebook. That repository
remains the written protocol; ctkit is the library implementation of it.
License
BSD 2-Clause. See LICENSE.
Issues and pull requests welcome.
Metadata
Release files for ctkit 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ctkit-0.1.1.tar.gz | 99.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ctkit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 183.9 kB
Release files / ctkit-0.1.1.tar.gz
| Download URL | ctkit-0.1.1.tar.gz |
|---|---|
| Size | 99.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4d53c185fc8afb0111ff5ad70adc1cb5f60a88b6e3b9b131ff7b3cef6d2a5f9
|
|
BLAKE2b-256 checksum How to use checksums |
8b777aba15cae14d48836a4319cddd16031642ba2baccf2719fee34fb995f8b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.20
|
Release files / ctkit-0.1.1-py3-none-any.whl
| Download URL | ctkit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 84.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3ae1fb8b6c0d570807211f385fc58a0b8b6ffa642bf0c46c45623fb0f7b2c219
|
|
BLAKE2b-256 checksum How to use checksums |
ac493c4ed59b226e2c2f6e699a91b4e66d75c1505afad868a8a2e98fdfe3d6ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.20
|