Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
prerakmody committed Jan 19, 2024
0 parents commit 7a92946
Show file tree
Hide file tree
Showing 11 changed files with 6,838 additions and 0 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Intro
This repository provides python scripts for head-and-neck photon and proton radiotherapy planning (in Raystation). It produces results for the paper - "Large-scale dose evaluation of deep learning organ contours in head-and-neck radiotherapy by leveraging existing plans" (under review).

# Abstract
**Background and Purpose**: Retrospective dose evaluation for organ-at-risk auto-contours has previously used small cohorts due to additional manual effort required for treatment planning on auto-contours. We aim to do this at large scale, by a) proposing and assessing an automated plan optimization workflow that uses existing clinical plan parameters and b) using it for head-and-neck auto-contour dose evaluation.

**Materials and Methods**: Our automated workflow emulates our clinics treatment planning protocol and reuses existing clinical plan optimization parameters. This workflow recreates the original clinical plan (P<sub>OG</sub>) with manual contours (Pmc) and evaluates the dose effect (P<sub>OG</sub> − P<sub>MC</sub>) on 70 photon and 30 proton plans of head-and-neck patients. As a use-case, the same workflow (and parameters) creates a plan using auto-contours (P<sub>AC</sub>) of eight head-and-neck organs-at-risk from a commercial tool and evaluates their dose effect (P<sub>MC</sub> − P<sub>AC</sub>).

**Results**: For plan recreation (P<sub>OG</sub> − P<sub>MC</sub>), our workflow, has a median impact of 0.99% and 1.45%, across dose metrics of auto-contours, for photon and proton, respectively. Computer time of automated planning is 25% (photon) and 42% (proton) of manual
planning time. For auto-contour evaluation (P<sub>MC</sub> − P<sub>AC</sub>), we notice an impact of 2.01% and 2.58% for photon and proton radiotherapy. All evaluations have a median ∆NTCP less than 0.30%.

**Conclusions**: The plan replication capability of our automated program provides a blueprint for other clinics to perform auto-contour dose evaluation with large patient cohorts and minimal skill and resource requirements. Finally, in spite of geometric differences, auto-contours, have a minimal mediandose impact, hence inspiring confidence in their utility and facilitating their clinical adoption.

# Method
<img src='assets/graphical-abstract.jpg'>


# Scripts

## Installation
Within the Raystation python 3.6 environment, run the following command to install the required packages.
```bash
pip install pydicom
```

1. For photons
- [src/hnDosePhotons.py](src/hnDosePhotons.py)

2. For protons
- [src/hnDoseProtons.py](src/hnDoseProtons.py)

3. Other files
- [src/config.py](src/config.py)
- [src/helpers.py](src/helpers.py)
34 changes: 34 additions & 0 deletions assets/eval-template-photon.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
PTV_DL1_DVH;V95%DL1 (%);
PTV_DL1_obj;D0.03cc (%DL1);Dmean (%DL1)
PTV_DL2_DVH;V95%DL2 (%);
PTV_DL2_obj;Dmean (%DL2);D0.03cc (%DL2)
SpinalCord;D0.03cc (cGy);
SpinalCord+3;D0.03cc (cGy);
Brainstem_Surf;D0.03cc (cGy);
Brainstem_Core;D0.03cc (cGy);
OpticChiasm;D0.03cc (cGy);
OpticNrv_L;D0.03cc (cGy);
OpticNrv_R;D0.03cc (cGy);
Eye_L;D0.03cc (cGy);
Eye_R;D0.03cc (cGy);
Brain;D0.03cc (cGy);D2% (cGy)
Pituitary;Dmean (cGy);
Lens_L;D0.03cc (cGy);
Lens_R;D0.03cc (cGy);
Cochlea_L;Dmean (cGy);
Cochlea_R;Dmean (cGy);
Parotid_L;Dmean (cGy);
Parotid_R;Dmean (cGy);
Glnd_Submand_L;Dmean (cGy);
Glnd_Submand_R;Dmean (cGy);
Oral_Cavity;Dmean (cGy);
Musc_Constrict_S;Dmean (cGy);
Musc_Constrict_M;Dmean (cGy);
Musc_Constrict_I;Dmean (cGy);
Cricopharyngeus;Dmean (cGy);
Larynx_SG;Dmean (cGy);
Esophagus;Dmean (cGy);
Glottic_Area;Dmean (cGy);
Bone_Mandible;D2% (cGy);
Bone_Mandible-PTV;D2% (cGy);

92 changes: 92 additions & 0 deletions assets/eval-template-proton-robust.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"CTV_DL1 [D98%>95%]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "CTV_DL1 [D98%>94%]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "CTV_DL2 [D98%>95%]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "CTV_DL2 [D98%>94%]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "CTV_DL2 [D2%<107%]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "SpinalCord_Core [D0.03cc (cGy) < 5000]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "SpinalCord_Core [D0.03cc (cGy) < 5569]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "SpinalCord_Surf [D0.03cc (cGy) < 6000]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "SpinalCord_Surf [D0.03cc (cGy) < 6310]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Brainstem_Core [D0.03cc (cGy) < 5400]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Brainstem_Core [D0.03cc (cGy) < 5870]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Brainstem_Surf [D0.03cc (cGy) < 6000]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Brainstem_Surf [D0.03cc (cGy) < 6310]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Brain-CTV_DL2 [D0.03cc (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Brain-CTV_DL2 [D0.03cc (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Cochlea_L [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Cochlea_R [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Parotid_L [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Parotid_R [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Glnd_Submand_L [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Glnd_Submand_R [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Oral_Cavity [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Musc_Constrict_S [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Musc_Constrict_M [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Musc_Constrict_I [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Cricopharyngeus [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Larynx_SG [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Glottic_Area [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Esophagus [Dmean (cGy)]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
, "Bone_Mandible [D2%<100%]":{
"Passed": -1, "Voxelwise-worst": -1, "NominalDose": -1, "Scenarios": []
}
}
Binary file added assets/graphical-abstract.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions assets/isodose.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="ASCII" standalone="yes"?>
<RayStationScriptTemplates>
<IsodoseTemplate conditionalDoseLevels="DL1">
<Isodose relativeToDoseLevel="DL1" color="64,0,0">115</Isodose>
<Isodose relativeToDoseLevel="DL1" color="128,0,0">110</Isodose>
<Isodose relativeToDoseLevel="DL1" color="255,0,0">107</Isodose>
<Isodose relativeToDoseLevel="DL1" color="255,128,0">105</Isodose>
<Isodose relativeToDoseLevel="DL1" color="0,128,0">100</Isodose>
<Isodose relativeToDoseLevel="DL1" color="0,255,0">95</Isodose>
</IsodoseTemplate>

<IsodoseTemplate conditionalDoseLevels="DL1,DL2">
<Isodose relativeToDoseLevel="DL2" color="255,0,0">107</Isodose>
<Isodose relativeToDoseLevel="DL2" color="255,192,0">100</Isodose>
<Isodose relativeToDoseLevel="DL2" color="255,255,128">95</Isodose>
<Isodose relativeToDoseLevel="DL1" color="255,255,255">107</Isodose>
<Isodose relativeToDoseLevel="DL1" color="0,128,0">100</Isodose>
<Isodose relativeToDoseLevel="DL1" color="0,255,0">95</Isodose>
</IsodoseTemplate>

<IsodoseTemplate conditionalDoseLevels="DL1,DL2,DL3">
<Isodose relativeToDoseLevel="DL3" color="255,0,0">107</Isodose>
<Isodose relativeToDoseLevel="DL3" color="192,0,96">100</Isodose>
<Isodose relativeToDoseLevel="DL3" color="255,128,192">95</Isodose>
<Isodose relativeToDoseLevel="DL2" color="255,255,255">107</Isodose>
<Isodose relativeToDoseLevel="DL2" color="255,192,0">100</Isodose>
<Isodose relativeToDoseLevel="DL2" color="255,255,128">95</Isodose>
<Isodose relativeToDoseLevel="DL1" color="255,255,255">107</Isodose>
<Isodose relativeToDoseLevel="DL1" color="0,128,0">100</Isodose>
<Isodose relativeToDoseLevel="DL1" color="0,255,0">95</Isodose>
</IsodoseTemplate>

<IsodoseTemplate>
<Isodose relativeToDoseLevel="DL1" color="0,0,128">90</Isodose>
<Isodose relativeToDoseLevel="DL1" color="64,64,192">80</Isodose>
<Isodose relativeToDoseLevel="DL1" color="128,128,255">70</Isodose>
<Isodose relativeToDoseLevel="DL1" color="192,192,255">50</Isodose>
<Isodose relativeToDoseLevel="DL1" color="192,192,192">25</Isodose>
</IsodoseTemplate>
</RayStationScriptTemplates>
Loading

0 comments on commit 7a92946

Please sign in to comment.