Metadata-Version: 2.4
Name: pycerr
Version: 2.0.0
Summary: A Computational Environment for Radiological Research
Author-email: "Aditya P. Apte" <aptea@mskcc.org>, Aditi Iyer <iyera@mskcc.org>, Eve LoCastro <locastre@mskcc.org>, "Joseph O. Deasy" <deasyj@mskcc.org>
Project-URL: Homepage, https://github.com/cerr/pyCERR
Project-URL: Bug Tracker, https://github.com/cerr/pyCERR/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: scipy
Requires-Dist: pydicom
Requires-Dist: python-dateutil
Requires-Dist: h5py
Requires-Dist: pandas
Requires-Dist: SimpleITK
Requires-Dist: nibabel
Requires-Dist: scikit-learn
Requires-Dist: scikit-image
Requires-Dist: PyWavelets
Requires-Dist: shapelysmooth
Requires-Dist: matplotlib>=3.5
Requires-Dist: ipywidgets
Requires-Dist: surface-distance
Requires-Dist: itk-strain
Requires-Dist: PyQt5
Requires-Dist: pyvista
Requires-Dist: pyvistaqt
Provides-Extra: napari
Requires-Dist: napari[all]; extra == "napari"
Requires-Dist: napari-animation; extra == "napari"
Dynamic: license-file

# pyCERR - A Python-based Computational Environment for Radiological Research

pyCERR provides convenient data structure for imaging metadata and their associations. Utilities are provided to to extract, transform, organize metadata and visualize results of image processing for image and dosimetry features, image processing for AI model training and inference.

## Features

All data for a patient lives in a single `PlanC` container — scans, structures
(segmentations), dose, treatment plans (beams) and deformations — defined in
`cerr.plan_container`. Around it, pyCERR provides:

**Data import / export**
- DICOM import of CT/MR/PT/US/NM scans plus RTSTRUCT, RTDOSE and RTPLAN — `pc.loadDcmDir`
- NIfTI import/export of scans, segmentations and dose — `pc.loadNiiScan` / `loadNiiStructure` / `loadNiiDose`, `.saveNii`
- Full-`PlanC` HDF5 serialization — `pc.saveToH5` / `pc.loadFromH5`
- DICOM RTSTRUCT export — `cerr.dcm_export.rtstruct_iod`

**Segmentation & contours**
- Lazy polygon → binary-mask rasterization — `cerr.contour.rasterseg.getStrMask`
- Import label maps / binary masks as structures — `cerr.dataclasses.structure.importStructureMask`

**Radiomics (IBSI-compliant)**
- Scalar features: morphology, first-order, GLCM / GLRLM / GLSZM / GLDZM / NGTDM / NGLDM (IBSI-1)
- Convolutional texture / filter-response maps: mean, LoG, Laws, Gabor, wavelet (IBSI-2)
- `cerr.radiomics.ibsi1.computeScalarFeatures`, configured via JSON settings

**Dosimetry & outcomes**
- Dose–volume histograms and metrics (Dx, Vx, MOHx, MOCx, mean dose) — `cerr.dvh`
- Radiotherapy outcome models (NTCP/TCP: LKB, logistic, Cox, Appelt) — `cerr.roe`
- IMRT planning / beamlet (influence-matrix) dose calculation — `cerr.imrtp`

**Image processing**
- Deformable image registration via plastimatch / ANTs — `cerr.registration`
- Resampling, intensity preprocessing and masking — `cerr.utils`
- Semi-quantitative DCE-MRI features — `cerr.mri_metrics`
- Helpers for AI model training / inference pipelines — `cerr.utils.ai_pipeline`

**Visualization** — three interchangeable viewers driven by the same `planC`
(napari 2D/3D, a PyQt5 CERR-style desktop GUI, and a Jupyter/Colab notebook
viewer); see [visualize scan, dose and segmentation](#visualize-scan-dose-and-segmentation) below.

## Documentation

- **Example notebooks** (grouped by topic): https://github.com/cerr/pyCERR-Notebooks
- **API reference** — https://pycerr.readthedocs.io (built from `docs/`; build locally with `cd docs && make html`)
- **Desktop GUI scripting API** — [`cerr/viewer/API_pycerr_gui.md`](https://github.com/cerr/pyCERR/blob/main/cerr/viewer/API_pycerr_gui.md)
- **Test suite & coverage** — [`tests/README.md`](https://github.com/cerr/pyCERR/blob/main/tests/README.md)

## Install Miniconda and Git
It is recommended to install CERR in an isolated environment such as Anaconda or VENV from GitHub repository. Please refer to 
1. https://docs.conda.io/projects/miniconda/en/latest/miniconda-install.html for installing Miniconda and 
2. https://git-scm.com/downloads for installing Git on your system.

## Install pyCERR

Launch Miniconda terminal, create a Conda environment with Python 3.8 and install CERR. Note that CERR requires Python version >= 3.8 to use Napari Viewer.
````
conda create -y --name pycerr python=3.11
conda activate pycerr
pip install "pyCERR[napari] @ git+https://github.com/cerr/pyCERR"
````    
The above steps will install CERR under testcerr/Lib/site-packages. 

Install Jupyter Lab or Notebook to try out example notebooks.
````
pip install jupyterlab
````

## Example Notebooks
Example notebooks are hosted at https://github.com/cerr/pyCERR-Notebooks/ . Clone this repository to use notebooks as a starting point.
````
git clone https://github.com/cerr/pyCERR-Notebooks.git
````

## Example snippets

Run python from the above Anaconda environment and try out the following code samples.

### Import modules for planC and viewer
    import numpy as np
    from cerr import plan_container as pc
    from cerr.viewer import pycerr_napari        # napari API (pycerr_napari.showNapari, ...)

### Read DICOM directory contents to planC
    dcmDir = r"\\path\to\Data\dicom\directory"
    planC = pc.loadDcmDir(dcmDir)
    
### Read NifTi scan to planC
    scanNiiFileName = r"\\path\to\Data\scan.nii.gz"
    planC = pc.loadNiiScan(scanNiiFileName, imageType = "CT SCAN")

### Read NifTi scan in a specified orientation to planC
    planC = pc.loadNiiScan(scanNiiFileName, imageType = "CT SCAN", direction='HFS')

### Read NifTi scan and append to an existing planC
    planC = pc.loadNiiScan(scanNiiFileName, imageType = "CT SCAN", direction='HFS', planC)
    
### Read NifTi segmentation to planC
    structNiiFileName = r"\\path\to\Data\structure.nii.gz"
    assocScanNum = 0
    labelDict = {1: 'GTV_P', 2: 'GTV_N'}
    planC = pc.loadNiiStructure(niiFileName, assocScanNum, planC, labelDict)

### Export Structures to DICOM
    from cerr.dcm_export import rtstruct_iod

    structDcmFileName = r"\\path\to\Data\structure.dcm"
    structNums = [0,2,3]
    exportOpts = {'seriesDescription': "Exported by pyCERR"}
    rtstruct_iod.create(structNums,structDcmFileName,planC,exportOpts)

### Export Scan, Structure and Dose to NifTi
    scanNiiFileName = r"\\path\to\Data\scan.nii.gz"
    scanNum = 0
    planC.scan[scanNum].saveNii(scanNiiFileName)
    
    structNiiFileName = r"\\path\to\Data\structure.nii.gz"
    structNum = 0
    planC.structure[structNum].saveNii(structNiiFileName, planC)    
    
    doseNiiFileName = r"\\path\to\Data\dose.nii.gz"
    doseNum = 0
    planC.dose[doseNum].saveNii(doseNiiFileName)
    

### visualize scan, dose and segmentation
pyCERR ships three interchangeable viewers under the `cerr.viewer` sub-package,
all driven by the same `planC`:

| Viewer | Module | Best for |
|--------|--------|----------|
| napari 2D/3D | `cerr.viewer.pycerr_napari` (`showNapari`) | quick interactive review, 3D rendering |
| PyQt5 desktop | `cerr.viewer.pycerr_gui` (`show`) | CERR-style slice viewer: contouring, registration QA, IMRTP/ROE, scripting API |
| notebook | `cerr.viewer.pycerr_nbviewer` (`showNB`) | Jupyter / JupyterLab / VS Code / Google Colab |


#### PyQt5 desktop viewer
    from cerr.viewer import pycerr_gui
    viewer = pycerr_gui.show(planC)            # opens the CERR-style desktop GUI
    # ... or launch empty and drag-and-drop a DICOM directory / NIfTI file in.
    # The viewer exposes a scripting API (set_scan/set_dose/goto_structure,
    # registration-QA setup, DVH export, save_screenshot, ...); see
    # cerr/viewer/API_pycerr_gui.md for the full reference.

#### Notebook viewer (Jupyter / Colab)
    from cerr.viewer import pycerr_nbviewer
    viewer = pycerr_nbviewer.showNB(planC, scan_nums=[0], struct_nums=strNumList,
                                     dose_nums=[0])

#### napari viewer
    from cerr.viewer import pycerr_napari
    scanNumList = [0]
    doseNumList = [0]
    numStructs = len(planC.structure)
    strNumList = np.arange(numStructs)
    displayMode = '2d' # '2d' or '3d'
    vectDict = {}
    viewer, scan_layer, struct_layer, dose_lyer, dvf_layer = \
                   pycerr_napari.showNapari(planC, scan_nums=scanNumList, struct_nums=strNumList,\
    	       dose_nums=doseNumList, vectors_dict=vectDict, displayMode = '2d')

### Compute DVH-based metrics
    from cerr import dvh
    structNum = 0
    doseNum = 0
    dosesV, volsV, isErr = dvh.getDVH(structNum, doseNum, planC)
    binWidth = 0.025
    doseBinsV,volHistV = dvh.doseHist(dosesV, volsV, binWidth)
    percent = 70
    dvh.MOHx(doseBinsV,volHistV,percent)
