EGS Brachy
An egs++ user code for rapid brachytherapy calculations
Loading...
Searching...
No Matches
utils.py
Go to the documentation of this file.
1import math
2import re
3
4REG_DOSE_UNC_RE = "\s+(\d)+\s+\d+\s+\d+\..*?\s+(.*?)\s+\+/-\s+(.*?)%\s+(.*?)\s+\+/-\s+(.*?)%"
5
6
7def extract_all_doses(egslst):
8 """return all regions and doses from egslst file. This may
9 include doses from more than one phantom"""
10
11 # regex to match scientific notation +[+-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)
12 sci_not = r"[+-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)"
13
14 r = re.compile(r"""\s+(\d+) # region number
15 \s+\d+ # medium number
16 \s+{sci_not}\‍({sci_not}\‍)\s+\+\/\-\s+\d+\.\d+% # volume, correction and error
17 \s+({sci_not})\s+\+\/\-\s+(\d+\.\d+)% # tlen dose and unc
18 \s+\‍(.*\‍)
19 \s+({sci_not})\s+\+\/\-\s+(\d+\.\d+)% # edep dose and unc
20 """.format(sci_not=sci_not), re.X)
21
22 return sorted(r.findall(egslst))
23
24def values_close(a, b, max_percent_diff=0.001):
25 if a == 0:
26 return values_close_abs(a, b, max_percent_diff)
27 return abs((a-b)/a) < max_percent_diff
28
29
30def values_close_abs(a, b, max_diff=0.001):
31 return abs(a-b) < max_diff
32
33def read_csv_spectrum(fname):
34 f = open(fname, "r")
35 header = f.readline()
36 energies = []
37 counts = []
38 unc = []
39
40 for line in f.readlines():
41 e, c, u = list(map(float, line.strip().split(",")))
42 energies.append(e)
43 counts.append(c)
44 unc.append(u)
45
46 return energies, counts, unc
47
48
49def doses_approx_equal(d1, d1_unc, d2, d2_unc, max_percent_diff=None, compare_unc=True, max_unc_percent_diff=None):
50 if max_percent_diff is None:
51 max_percent_diff = max(d1_unc, d2_unc)
52
53 if max_unc_percent_diff is None:
54 max_unc_percent_diff = 0.005
55
56 vc = values_close(d1, d2, max_percent_diff)
57 if compare_unc:
58 uc = values_close_abs(d1_unc, d2_unc, max_unc_percent_diff)
59 else:
60 uc = True
61
62 return vc and uc
63
64
65def read3ddose(fname):
66
67 with open(fname, 'r') as f:
68 dat = f.readlines()
69
70 nx, ny, nz = list(map(int, dat[0].strip().split()))
71 xbounds = list(map(float, dat[1].strip().split()))
72 ybounds = list(map(float, dat[2].strip().split()))
73 zbounds = list(map(float, dat[3].strip().split()))
74 doses = list(map(float, dat[4].strip().split()))
75 uncs = list(map(float, dat[5].strip().split()))
76
77 return {
78 'nx': nx,
79 'ny': ny,
80 'nz': nz,
81 'xbounds': xbounds,
82 'ybounds': ybounds,
83 'zbounds': zbounds,
84 'doses': doses,
85 'uncs': uncs,
86 }
87
88
89def compare_3ddose_files(f1, f2, max_percent_diff=None):
90
91 d1 = read3ddose(f1)
92 d2 = read3ddose(f2)
93
94 bounds_keys = ('xbounds', 'ybounds', 'zbounds',)
95 for k in bounds_keys:
96 bounds_close = all([values_close(b1,b2) for b1,b2 in zip(d1[k], d2[k])])
97 if not bounds_close:
98 print((k, " are different"))
99 return False
100
101 doses_and_uncs = list(zip(d1['doses'], d1['uncs'], d2['doses'], d2['uncs']))
102 dose_diffs = [abs((a-b)/a) for a,_,b,_ in doses_and_uncs]
103
104 doses_close = all([doses_approx_equal(d1, d1u, d2, d2u, max_percent_diff=max_percent_diff, compare_unc=False)
105 for d1, d1u, d2, d2u in doses_and_uncs])
106
107 return doses_close
108
values_close_abs(a, b, max_diff=0.001)
Definition utils.py:30