In [1]:
import linecache
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import os
from ftplib import FTP
import charts
from IPython.display import display, clear_output
from IPython.html import widgets
import random
In [2]:
pts_pinn = []
dir_name=os.getcwd()
dir_pinn = str(dir_name + '\DVHpinn')
for root, dirs, files in os.walk(dir_pinn):
for file in files:
pts_pinn.append(file)
pts_cyber = []
dir_cyber = str(dir_name + '\DVHcyber')
for root, dirs, files in os.walk(dir_cyber):
for file in files:
pts_cyber.append(file)
pts_brachy = []
dir_brachy = str(dir_name + '\DVHbrachy')
for root, dirs, files in os.walk(dir_brachy):
for file in files:
pts_brachy.append(file)
pts_onc = []
dir_name=os.getcwd()
dir_onc = str(dir_name + '\DVHoncentra')
for root, dirs, files in os.walk(dir_onc):
for file in files:
pts_onc.append(file)
In [9]:
tps={'Pinnacle':[x for x in pts_pinn],'BrachyVision':[x for x in pts_brachy],'Cyberknife':[x for x in pts_cyber],'Oncentra':[x for x in pts_onc]}
import json
with open('tps.json', 'w') as fp:
json.dump(tps, fp)
def print_pts(Patient):
global fineName2
print Patient
fileName2 = str(Patient)
def select_pts(TPS):
global tps_value
patW.options = tps[TPS]
tps_value = str(TPS)
tpsW = widgets.Select(options=tps.keys())
init = tpsW.value
patW = widgets.Select(options=tps[init])
j = widgets.interactive(print_pts, Patient=patW)
i = widgets.interactive(select_pts, TPS=tpsW)
display(i,j)
In [ ]:
In [5]:
def dvh_v_rel(str_idx,dose):
return round(np.interp(dose,total_dvh[str_idx][2],total_dvh[str_idx][3]),2)
def dvh_d_rel(str_idx,vol):
return round(np.interp(vol,total_dvh[str_idx][3][::-1],total_dvh[str_idx][2][::-1]),2)
def dvh_d_abs(str_idx,vol):
rel_vol = vol*100.0 / total_dvh[3][1]
ret = round(dvh_d_rel(str_idx,rel_vol),2)
return ret
def gEUD(dose_cum,vol_cum, a = 1):
if a == 0:
return "Error, 'a' must be non-zero"
elif len(dose_cum) != len(vol_cum):
return "Error different length of dose and volume arrays"
elif vol_cum[-1]>0:
return "Entire volume not covered in dose range"
elif a>100 or a<-100:
return "Error 'a' is out of range"
diff_dose = []
res = 0
diff_vol = -1 * np.diff(vol_cum)
for idx in range(len(dose_cum)-1):
diff_dose.append((dose_cum[idx]+dose_cum[idx+1])/2.0)
for idx in range(len(diff_dose)):
res +=diff_dose[idx]**a * diff_vol[idx]/100.0
res = res**(1.0/a)
return res
In [6]:
structures = []
def line_index(fileName,words):
global dose_idx, last_line_idx
last_line_idx = 0
with open(fileName) as f:
for line_number, line in enumerate(f,1):
word = line.strip()
for word in words:
if line.find(word)>=0:
if tpsW.value == "Cyberknife":
name = line.strip(',').split(',')[8]
structures.append((line_number,name.upper()))
else:
data1, name = line.split (': ')
name = name[:-1]
structures.append((line_number,name.upper()))
if tpsW.value == "Cyberknife":
if line.find("DOSE_PERCENT,VOI_NAME,VOI_VOLUME")>=0:
dose_idx = line_number
if last_line_idx< line_number:
last_line_idx = line_number
if tpsW.value == "Pinnacle":
words2 = ["Roi:"]
dir_plus = dir_pinn
elif tpsW.value == "BrachyVision":
words2 = ["Structure:"]
dir_plus = dir_brachy
elif tpsW.value == "Oncentra":
words2 = ["ROI:"]
dir_plus = dir_onc
elif tpsW.value == "Cyberknife":
words2 = ["VOI,Min (cGy),Mean (cGy),Max (cGy),Cl,nCl,HI,Coverage %"]
dir_plus = dir_cyber
else:
words2 = ["VOI,Min (cGy),Mean (cGy),Max (cGy),Cl,nCl,HI,Coverage %"]
dir_plus = dir_cyber
fileName2 = os.path.join(dir_plus, patW.value)
line_index(fileName2,words2)
In [7]:
total_dvh=[]
if tpsW.value == "Pinnacle":
list_size = structures[1][0]-structures[0][0]-1
for idx in structures:
bin_size = float(linecache.getline(fileName2,structures[0][0]-2).strip(' \t\n\r').split()[2])
start = idx[0]+2
stop = idx[0]+list_size-1
vol_in_cc = float(linecache.getline(fileName2,idx[0]+2).split("\t")[1])
dvh_dose = []
dvh_vol = []
while start < stop:
[dose_bin, vol] = linecache.getline(fileName2,start).strip(' \t\n\r').split()
dose = float((float(dose_bin)-1)*bin_size/100.0)
rel_vol = float(vol)/vol_in_cc*100.0
dvh_dose.append(dose)
dvh_vol.append(rel_vol)
start +=1
total_dvh.append((idx[1],vol_in_cc,dvh_dose,dvh_vol))
elif tpsW.value == "BrachyVision":
list_size = structures[1][0]-structures[0][0]-1
for idx in structures:
start = idx[0]+19
stop = idx[0]+list_size
vol_idx = idx[0]+4
dump, vol_in_cc = linecache.getline(fileName2,vol_idx).split(': ')
vol_in_cc = float(vol_in_cc[:-1])
dvh_dose = []
dvh_vol = []
while start < stop:
line2 = linecache.getline(fileName2,start).strip(' \t\n\r').split()
if len(line2) == 3:
dose = float(line2[0])
rel_dose = float(line2[1])
rel_vol = float(line2[2])
dvh_dose.append(dose)
dvh_vol.append(rel_vol)
start +=1
total_dvh.append((idx[1],vol_in_cc,dvh_dose,dvh_vol))
elif tpsW.value == "Cyberknife":
list_size = structures[-1][0]-structures[0][0]+1
first_ref = structures[0][0]-1
dose_max = float(linecache.getline(fileName2,2).strip(',').split(',')[144])/100.0
start = dose_idx +structures[0][0]-first_ref
vol_in_cc = float(linecache.getline(fileName2,start).strip(",").split(',')[2])/1000.0
for idx in structures:
start = dose_idx +idx[0]-first_ref
vol_in_cc = float(linecache.getline(fileName2,start).strip(",").split(',')[2])/1000.0
dvh_dose = []
dvh_vol = []
while (start <= (last_line_idx - list_size)) and (linecache.getline(fileName2,start)>10):
line2 = linecache.getline(fileName2,start).strip(',\n').split(',')
rel_dose = float(line2[0])
dose = rel_dose*dose_max/100.0
vol = float(line2[2])
rel_vol = vol/(vol_in_cc*10.0)
dvh_dose.append(dose)
dvh_vol.append(rel_vol)
start += list_size
total_dvh.append((idx[1],vol_in_cc,dvh_dose,dvh_vol))
else:
total_dvh.append((None,0.0,[0.0],[0.0]))
In [8]:
dvh_series = []
for idx in range(len(total_dvh)):
s = dict(name=total_dvh[idx][0], data = zip(total_dvh[idx][2],total_dvh[idx][3]))
dvh_series.append(s)
options = {
'title':{'text':'Cumulative DVH'},
'yAxis':{
'title':{'text':'Volume (%)'},
'min':0,
'max':100
},
'xAxis':{
'title':{'text':'Dose (Gy)'}
},
'chart':{'zoomType':'xy'},
'plotOptions':{'spline':{'marker':{'enabled':False}}
}
}
charts.plot(dvh_series, options=options, show='inline', type='spline')
Out[8]:
In [8]:
with open('dvh_cowez.json', 'w') as fp:
json.dump(total_dvh, fp)
In [8]:
volumes = [x[0] for x in total_dvh]
volumes.append("Not Available")
protocols = ["HDR-4x7Gy","PDR-50pulses","PDR-30pulses"]
protocol= widgets.Dropdown(options=protocols,description = "Dose (Gy):")
hr_ctv = widgets.Dropdown(options=volumes, description = "HR-CTV: ")
ir_ctv = widgets.Dropdown(options=volumes, description = "IR-CTV: ")
gtv = widgets.Dropdown(options=volumes, description = "GTV: ")
rectum = widgets.Dropdown(options=volumes, description = "Rectum: ")
bladder = widgets.Dropdown(options=volumes, description = "Bladder: ")
sigmoid = widgets.Dropdown(options=volumes, description = "Sigmoid: ")
small_bowels = widgets.Dropdown(options=volumes, description = "Small Bowels: ")
display(protocol,hr_ctv,ir_ctv,gtv,rectum,bladder,sigmoid,small_bowels)
In [12]:
button = widgets.Button(description="Print Report")
def on_button_clicked(b):
clear_output()
hr_ctv_idx = [x[0] for x in total_dvh].index(hr_ctv.value)
ir_ctv_idx = [x[0] for x in total_dvh].index(ir_ctv.value)
gtv_idx = [x[0] for x in total_dvh].index(gtv.value)
rect_idx = [x[0] for x in total_dvh].index(rectum.value)
blad_idx = [x[0] for x in total_dvh].index(bladder.value)
sig_idx = [x[0] for x in total_dvh].index(sigmoid.value)
sm_bow_idx = [x[0] for x in total_dvh].index(small_bowels.value)
if protocol.value=="HDR-4x7Gy":
presc_dose = 35.0
elif protocol.value ==1:
presc_dose = 35.0
else:
presc_dose = 25.0
print presc_dose*.9
print "Selected structure:",total_dvh[hr_ctv_idx][0]
print "HR-CTV D90%", dvh_d_rel(hr_ctv_idx,90.0)
print "HR-CTV D98%", dvh_d_rel(hr_ctv_idx,98.0)
print "HR-CTV D50%", dvh_d_rel(hr_ctv_idx,50.0)
print
print "Selected structure:",total_dvh[ir_ctv_idx][0]
print "IR-CTV D90%", dvh_d_rel(ir_ctv_idx,90.0)
print "IR-CTV D100%", dvh_d_rel(ir_ctv_idx,98.0)
print "IR-CTV D50%", dvh_d_rel(ir_ctv_idx,50.0)
print
print "Selected structure:",total_dvh[gtv_idx][0]
print "GTV D90%", dvh_d_rel(gtv_idx,90.0)
print "GTV D98%", dvh_d_rel(gtv_idx,98.0)
print "GTV D50%", dvh_d_rel(gtv_idx,50.0)
print
print "Selected structure:",total_dvh[rect_idx][0]
#print "Rectum V15Gy: " , dvh_v_rel(rect_idx,15)
print "Rectum D2cc: " ,dvh_d_abs(rect_idx,2)
print "Rectum D0.1cc: " ,dvh_d_abs(rect_idx,0.1)
print
print "Selected structure:",total_dvh[sig_idx][0]
print "Sigmoid D2cc: " ,dvh_d_abs(sig_idx,2)
print "Sigmoid D0.1cc: " ,dvh_d_abs(sig_idx,0.1)
print
print "Selected structure:",total_dvh[sm_bow_idx][0]
print "Small bowels D2cc: " ,dvh_d_abs(sm_bow_idx,2)
print "Small bowels D0.1cc: " ,dvh_d_abs(sm_bow_idx,0.1)
print
print "Selected structure:",total_dvh[blad_idx][0]
print "Bladder D2cc: " ,dvh_d_abs(blad_idx,2)
print "Bladder D0.1cc: " ,dvh_d_abs(blad_idx,0.1)
button.on_click(on_button_clicked)
display(button)
In [ ]:
protocols={'Brachy':{'PDR':{'pres_dose':'35.0'}},'Breast':[x for x in pts_brachy],'Cervix':[x for x in pts_cyber]}
import json
with open('protocol.json', 'w') as fp:
json.dump(protocols, fp)
def print_protocols(protocol1):
print Patient
def select_pts(TPS):
global tps_value
patW.options = tps[TPS]
tps_value = str(TPS)
protocolsW = widgets.Select(options=protocols.keys())
init = protocolsW.value
patW = widgets.Select(options=tps[init])
j = widgets.interactive(print_pts, Patient=patW)
i = widgets.interactive(select_pts, Pathology=protocolsW)
display(i,j)