Skip to content

Commit

Permalink
V1.0.2: Updated optimization and clinical criteria json config files …
Browse files Browse the repository at this point in the history
…to make them more mature and adapted code according to it
  • Loading branch information
gourav3017 committed Nov 27, 2023
1 parent 4b8e5f3 commit 744146f
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 165 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="./images/PortPy_logo.png" width="40%" height="40%">
</p>

![Version](https://img.shields.io/static/v1?label=latest&message=v1.0.1&color=darkgreen)
![Version](https://img.shields.io/static/v1?label=latest&message=v1.0.2&color=darkgreen)
[![Total Downloads](https://static.pepy.tech/personalized-badge/portpy?period=total&units=international_system&left_color=grey&right_color=blue&left_text=total%20downloads)](https://pepy.tech/project/portpy?&left_text=totalusers)

# What is PortPy?
Expand Down
2 changes: 1 addition & 1 deletion portpy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "1.0.1"
__version__ = "1.0.2"

from portpy import photon
32 changes: 16 additions & 16 deletions portpy/config_files/clinical_criteria/Default/Lung_2Gy_30Fx.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"num_of_fractions": 30,
"criteria": [
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "GTV"
},
Expand All @@ -15,7 +15,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "PTV"
},
Expand All @@ -25,7 +25,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "ESOPHAGUS"
},
Expand All @@ -34,7 +34,7 @@
}
},
{
"name": "mean_dose",
"type": "mean_dose",
"parameters": {
"structure_name": "ESOPHAGUS"
},
Expand All @@ -44,7 +44,7 @@
}
},
{
"name": "dose_volume_V",
"type": "dose_volume_V",
"parameters": {
"structure_name": "ESOPHAGUS",
"dose_gy": 60
Expand All @@ -54,7 +54,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "HEART"
},
Expand All @@ -63,7 +63,7 @@
}
},
{
"name": "mean_dose",
"type": "mean_dose",
"parameters": {
"structure_name": "HEART"
},
Expand All @@ -73,7 +73,7 @@
}
},
{
"name": "dose_volume_V",
"type": "dose_volume_V",
"parameters": {
"structure_name": "HEART",
"dose_gy": 30
Expand All @@ -83,7 +83,7 @@
}
},
{
"name": "dose_volume_V",
"type": "dose_volume_V",
"parameters": {
"structure_name": "HEART",
"dose_gy": 30
Expand All @@ -93,7 +93,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "LUNG_L"
},
Expand All @@ -102,7 +102,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "LUNG_R"
},
Expand All @@ -111,7 +111,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "CORD"
},
Expand All @@ -121,7 +121,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "SKIN"
},
Expand All @@ -130,7 +130,7 @@
}
},
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"structure_name": "LUNGS_NOT_GTV",
"structure_def": "(LUNG_L | LUNG_R) - GTV"
Expand All @@ -140,7 +140,7 @@
}
},
{
"name": "mean_dose",
"type": "mean_dose",
"parameters": {
"structure_name": "LUNGS_NOT_GTV",
"structure_def": "(LUNG_L | LUNG_R) - GTV"
Expand All @@ -151,7 +151,7 @@
}
},
{
"name": "dose_volume_V",
"type": "dose_volume_V",
"parameters": {
"structure_name": "LUNGS_NOT_GTV",
"structure_def": "(LUNG_L | LUNG_R) - GTV",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
"prescription_gy": 60,
"objective_functions": [
{
"type": "quadratic-overdose",
"type": "quadratic-overdose",
"structure_name": "PTV",
"weight": 10000,
"dose_gy": "prescription_gy"
},
{
"type": "linear-overdose",
"structure_name": "CORD",
"weight": 100,
"dose_gy": 50
},
{
"type": "quadratic-underdose",
"structure_name": "PTV",
Expand Down Expand Up @@ -81,30 +87,55 @@
],
"constraints":[
{
"type": "max",
"type": "max_dose",
"parameters": {
"structure_name": "RIND_0",
"upper_limit": "1.1*prescription_gy"
},
"structure_def": "(PTV+5) - PTV"
},
"constraints": {
"limit_dose_gy": "1.1*prescription_gy"
}
},
{
"type": "max",
"type": "max_dose",
"parameters": {
"structure_name": "RIND_1",
"upper_limit": "1.05*prescription_gy"
},
"structure_def": "(PTV+10) - (PTV + 5)"
},
"constraints": {
"limit_dose_gy": "1.05*prescription_gy"
}
},
{
"type": "max",
"type": "max_dose",
"parameters": {
"structure_name": "RIND_2",
"upper_limit": "0.9*prescription_gy"
},
"structure_def": "(PTV+30) - (PTV + 10)"
},
"constraints": {
"limit_dose_gy": "0.9*prescription_gy"
}
},
{
"type": "max",
"type": "max_dose",
"parameters": {
"structure_name": "RIND_3",
"upper_limit": "0.85*prescription_gy"
},
"structure_def": "(PTV+50) - (PTV + 30)"
},
"constraints": {
"limit_dose_gy": "0.85*prescription_gy"
}
},
{
"type": "max",
"type": "max_dose",
"parameters": {
"structure_name": "RIND_4",
"upper_limit": "0.75*prescription_gy"
}
"structure_def": "(PTV + inf) - (PTV + 50)"
},
"constraints": {
"limit_dose_gy": "0.75*prescription_gy"
}
}
]

}
76 changes: 43 additions & 33 deletions portpy/photon/clinical_criteria.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ClinicalCriteria:
"num_of_fractions": 30,
"criteria": [
{
"name": "max_dose",
"type": "max_dose",
"parameters": {
"struct": "GTV"
}}
Expand Down Expand Up @@ -54,75 +54,85 @@ def get_num_of_fractions(self) -> float:
"""
return self.clinical_criteria_dict['num_of_fractions']

def add_criterion(self, criterion: str, parameters: dict, constraints: dict) -> None:
def add_criterion(self, type: str, parameters: dict, constraints: dict) -> None:
"""
Add criterion to the clinical criteria dictionary
:param criterion: criterion name. e.g. max_dose
:param type: criterion name. e.g. max_dose
:param parameters: parameters dictionary e.g. parameters = {'struct':'PTV'}
:param constraints: constraints dictionary e.g. constraints = {'limit_dose_gy':66, 'goal_dose_gy':60}
:return: add the criteria to clinical criteria dictionary
"""

self.clinical_criteria_dict['criteria'].append({'name': criterion})
self.clinical_criteria_dict['criteria'].append({'type': type})
self.clinical_criteria_dict['criteria'][-1]['parameters'] = parameters
self.clinical_criteria_dict['criteria'][-1]['constraints'] = constraints

def modify_criterion(self, criterion: str, parameters: dict, constraints: dict) -> None:
"""
Modify the criterion in clinical criteria dictionary
:param criterion: criterion name. e.g. max_dose
:param parameters: parameters dictionary e.g. parameters = {'struct':'PTV'}
:param constraints: constraints dictionary e.g. constraints = {'limit_dose_gy':66, 'goal_dose_gy':60}
:return: add the criteria to clinical criteria dictionary
"""
criteria = self.clinical_criteria_dict['criteria']
ind = [criteria[i]['name'] for i in range(len(criteria)) if criteria[i]['name'] == criterion and
criteria[i]['parameters'] == parameters]
if len(ind) > 0:

criteria[ind[0]]['constraints'] = constraints
else:
raise Exception('No criteria for name {} and parameters {}'.format(criterion, parameters))

@staticmethod
def create_criterion(criterion: str, parameters: dict, constraints: dict):
def create_criterion(type: str, parameters: dict, constraints: dict):
"""
Create criterion and return list
:param criterion: criterion name. e.g. max_dose
:param type: criterion name. e.g. max_dose
:param parameters: parameters dictionary e.g. parameters = {'struct':'PTV'}
:param constraints: constraints dictionary e.g. constraints = {'limit_dose_gy':66, 'goal_dose_gy':60}
:return: add the criteria to clinical criteria dictionary
"""

criterion = [{'name': criterion, 'parameters': parameters, 'constraints': constraints}]
criterion = [{'type': type, 'parameters': parameters, 'constraints': constraints}]
return criterion

def get_criteria(self, name: str = None) -> List[dict]:
def get_criteria(self, type: str = None) -> List[dict]:
"""
Returns all the clinical criteria
:return:
"""
all_criteria = []
if name is None:
if type is None:
all_criteria = self.clinical_criteria_dict['criteria']
elif name == 'max_dose':
elif type == 'max_dose':
criteria = self.clinical_criteria_dict['criteria']
ind = [i for i in range(len(criteria)) if criteria[i]['name'] == name]
ind = [i for i in range(len(criteria)) if criteria[i]['type'] == type]
if len(ind) > 0:
all_criteria = [criteria[i] for i in ind]
elif name == 'mean_dose':
elif type == 'mean_dose':
criteria = self.clinical_criteria_dict['criteria']
ind = [i for i in range(len(criteria)) if criteria[i]['name'] == name]
ind = [i for i in range(len(criteria)) if criteria[i]['type'] == type]
if len(ind) > 0:
all_criteria = [criteria[i] for i in ind]

if isinstance(all_criteria, dict):
all_criteria = [all_criteria]
return all_criteria

def check_criterion_exists(self, criterion, return_ind:bool = False):
criterion_exist = False
criterion_ind = None
for ind, crit in enumerate(self.clinical_criteria_dict['criteria']):
if (crit['type'] == criterion['type']) and crit['parameters'] == criterion['parameters']:
for constraint in crit['constraints']:
if constraint == criterion['constraints']:
criterion_exist = True
criterion_ind = ind
if return_ind:
return criterion_exist,criterion_ind
else:
return criterion_exist

def modify_criterion(self, criterion):
"""
Modify the criterion the clinical criteria
"""
criterion_found = False
for ind, crit in enumerate(self.clinical_criteria_dict['criteria']):
if (crit['type'] == criterion['type']) and crit['parameters'] == criterion['parameters']:
for constraint in crit['constraints']:
if constraint == criterion['constraints']:
self.clinical_criteria_dict['criteria'][ind]['constraints'][constraint] = criterion['constraints']
criterion_found = True
if not criterion_found:
raise Warning('No criteria for {}'.format(criterion))
Loading

0 comments on commit 744146f

Please sign in to comment.