Skip to content

Commit a00257a

Browse files
author
Sebastian Schäfer
committed
Major bug fixes for dose statistics
1 parent 0caea0d commit a00257a

2 files changed

Lines changed: 80 additions & 49 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Highlights include:
5353
* Line width
5454
- Drag and drop of files
5555
- Center axis deviation correction
56-
- Import of RadCalc (OAR & PDD) and Slicer Line Profile simulation results
56+
- Import of RadCalc OAR and PDD data, RayStation depth doses and dose profiles, and Slicer line profiles
5757
- Import of custom measurements (as numpy .txt files)
5858
- Import of PTW tbaScan (MEPHYSTO mc<sup>2</sup>) measurements
5959
- German and english language support

topasgraphsim/src/functions/dp.py

Lines changed: 79 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,78 +13,109 @@ def calculate_parameters(axis, dose, cax=False):
1313
interpolated_axis = np.linspace(axis[0], axis[-1], len(axis) * 100)
1414
akima_dose_interpolator = interpolate.Akima1DInterpolator(axis, dose)
1515
interpolated_dose = np.flip(akima_dose_interpolator.__call__(interpolated_axis))
16+
max_dose = np.max(interpolated_dose)
1617

17-
# Find the index of the maximum dose
18-
max_dose_index = np.argmax(interpolated_dose)
18+
XL20index = []
19+
XL50index = []
20+
XL80index = []
1921

20-
# Use this index to split the axis and dose arrays
21-
left_interpolated_axis = interpolated_axis[:max_dose_index]
22-
right_interpolated_axis = interpolated_axis[max_dose_index:]
23-
left_interpolated_dose = interpolated_dose[:max_dose_index]
24-
right_interpolated_dose = interpolated_dose[max_dose_index:]
22+
for i, d in enumerate(interpolated_dose):
23+
if XL20index == [] and d > 0.2*max_dose:
24+
XL20index += [d]
25+
XL20index += [interpolated_dose[i-1]]
26+
elif XL50index == [] and d > 0.5*max_dose:
27+
XL50index += [d]
28+
XL50index += [interpolated_dose[i-1]]
29+
elif XL80index == [] and d > 0.8*max_dose:
30+
XL80index += [d]
31+
XL80index += [interpolated_dose[i-1]]
32+
break
2533

26-
# Now use these new arrays to calculate your parameters
27-
XL20 = left_interpolated_axis[(np.abs(left_interpolated_dose - 0.2 * max(dose))).argmin()]
28-
XL50 = left_interpolated_axis[XL50index:=((np.abs(left_interpolated_dose - 0.5 * max(dose))).argmin())]
29-
XL80 = left_interpolated_axis[(np.abs(left_interpolated_dose - 0.8 * max(dose))).argmin()]
30-
XR20 = right_interpolated_axis[(np.abs(right_interpolated_dose - 0.2 * max(dose))).argmin()]
31-
XR50 = right_interpolated_axis[XR50index:=((np.abs(right_interpolated_dose - 0.5 * max(dose))).argmin())]
32-
XR80 = right_interpolated_axis[(np.abs(right_interpolated_dose - 0.8 * max(dose))).argmin()]
34+
XL20 = (np.abs(np.array(XL20index) - 0.2 * max_dose)).argmin()
35+
XL20 = XL20index[XL20]
36+
XL50 = (np.abs(np.array(XL50index) - 0.5 * max_dose)).argmin()
37+
XL50 = XL50index[XL50]
38+
XL80 = (np.abs(np.array(XL80index) - 0.8 * max_dose)).argmin()
39+
XL80 = XL80index[XL80]
40+
41+
XL20index = min(np.where(interpolated_dose==XL20)[0])
42+
XL50index = min(np.where(interpolated_dose==XL50)[0])
43+
XL80index = min(np.where(interpolated_dose==XL80)[0])
44+
XL20 = interpolated_axis[XL20index]
45+
XL50 = interpolated_axis[XL50index]
46+
XL80 = interpolated_axis[XL80index]
47+
48+
XR20index = []
49+
XR50index = []
50+
XR80index = []
51+
52+
for i, d in enumerate(np.flip(interpolated_dose)):
53+
if XR20index == [] and d > 0.2*max_dose:
54+
XR20index += [d]
55+
XR20index += [np.flip(interpolated_dose)[i-1]]
56+
elif XR50index == [] and d > 0.5*max_dose:
57+
XR50index += [d]
58+
XR50index += [np.flip(interpolated_dose)[i-1]]
59+
elif XR80index == [] and d > 0.8*max_dose:
60+
XR80index += [d]
61+
XR80index += [np.flip(interpolated_dose)[i-1]]
62+
break
63+
64+
XR20 = (np.abs(np.array(XR20index) - 0.2 * max_dose)).argmin()
65+
XR20 = XR20index[XR20]
66+
XR50 = (np.abs(np.array(XR50index) - 0.5 * max_dose)).argmin()
67+
XR50 = XR50index[XR50]
68+
XR80 = (np.abs(np.array(XR80index) - 0.8 * max_dose)).argmin()
69+
XR80 = XR80index[XR80]
70+
71+
XR20index = max(np.where(interpolated_dose==XR20)[0])
72+
XR50index = max(np.where(interpolated_dose==XR50)[0])
73+
XR80index = max(np.where(interpolated_dose==XR80)[0])
74+
XR20 = interpolated_axis[XR20index]
75+
XR50 = interpolated_axis[XR50index]
76+
XR80 = interpolated_axis[XR80index]
3377

3478
HWB = round(abs(XR50 - XL50), 3)
3579
CAXdev = (round(XL50 + 0.5 * HWB, 3) + round(XR50 - 0.5 * HWB, 3) )/ 2
3680
#find the index of the axis af the cax_dev value
3781
CAXdevindex = np.abs(interpolated_axis - CAXdev).argmin()
3882
CAXdevpoints = int(abs(CAXdevindex - XL50index)//10)
3983
PlateauDose = np.mean(interpolated_dose[CAXdevindex - CAXdevpoints : CAXdevindex + CAXdevpoints+1])
40-
PlateauRatio = round(PlateauDose / max(dose), 3)
41-
Dose80 = [value for value in dose if value >= 0.8 * max(dose)]
84+
PlateauRatio = round(PlateauDose/max_dose, 3)
85+
86+
Width80 = HWB*0.8
87+
FieldL80 = CAXdev - Width80/2
88+
FieldR80 = CAXdev + Width80/2
89+
Dose80 = interpolated_dose[(np.abs(interpolated_axis - FieldL80)).argmin():(np.abs(interpolated_axis - FieldR80)).argmin()]
4290

4391
if cax == True:
4492
return CAXdev
4593

46-
flat_krieger = round(
47-
max([value for value in dose if value >= 0.95 * max(dose)])
48-
- min([value for value in dose if value >= 0.95 * max(dose)]) / np.max(interpolated_dose),
49-
5,
50-
)
51-
flat_stddev = round(np.std(Dose80), 3)
52-
53-
if len(Dose80) % 2 != 0:
54-
Dose80 = (
55-
Dose80[0 : int(len(Dose80) / 2)]
56-
+ Dose80[int(len(Dose80) / 2) + 1 : len(Dose80)]
57-
)
94+
flat_krieger = round( abs(min(Dose80)-max(Dose80))/max(Dose80),3)
95+
flat_stddev = round(np.std(Dose80/max(Dose80)), 3)
5896

59-
S = round(
60-
max(
61-
[Dose80[i - 1] / Dose80[len(Dose80) - i] for i in range(1, len(Dose80) + 1)]
62-
),
63-
3,
64-
)
97+
S = interpolated_dose[CAXdevindex-len(Dose80)//2:CAXdevindex+len(Dose80)//2]
98+
S = max(np.divide(S, S[::-1]))
99+
S = round(S-1,3)
65100

66-
Lpenumbra = round(abs(XL80 - XL20 + CAXdev), 3)
67-
Rpenumbra = round(abs(XR80 - XR20 + CAXdev), 3)
101+
Rpenumbra = round(abs(XL80 - XL20), 3)
102+
Lpenumbra = round(abs(XR80 - XR20), 3)
68103

69-
XL20index = np.where(interpolated_axis == XL20)[0][0]
70-
XL80index = np.where(interpolated_axis == XL80)[0][0]
71-
XR20index = np.where(interpolated_axis == XR20)[0][0]
72-
XR80index = np.where(interpolated_axis == XR80)[0][0]
73104
try:
74-
Lintegral = round(
105+
Rintegral = round(
75106
abs(
76-
integrate.simps(
77-
interpolated_dose[XL20index:XL80index],
78-
interpolated_axis[XL20index:XL80index],
107+
integrate.simpson(
108+
y=interpolated_dose[XL20index:XL80index]/max_dose,
109+
x=interpolated_axis[XL20index:XL80index],
79110
)
80111
),
81112
3,
82113
)
83-
Rintegral = round(
114+
Lintegral = round(
84115
abs(
85-
integrate.simps(
86-
interpolated_dose[XR80index:XR20index],
87-
interpolated_axis[XR80index:XR20index],
116+
integrate.simpson(
117+
y=interpolated_dose[XR80index:XR20index]/max_dose,
118+
x=interpolated_axis[XR80index:XR20index],
88119
)
89120
),
90121
3,

0 commit comments

Comments
 (0)