Skip to content

Commit 72be39b

Browse files
committed
ENH: Fit WEPL to angle standard deviation in pctweplfit
1 parent 1279523 commit 72be39b

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

applications/pctweplfit/pctweplfit.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def add_detector(name, translation, attach_to_phantom=False):
116116
'EventID',
117117
'TrackID',
118118
'Position',
119+
'Direction',
119120
'PreGlobalTime',
120121
'KineticEnergy'
121122
]
@@ -138,10 +139,11 @@ def add_detector(name, translation, attach_to_phantom=False):
138139
sim.run()
139140

140141

141-
def process_phantom_length(phantom_length, output, path_type, number_of_detectors, tofs, wepls, elosses, verbose):
142+
def process_phantom_length(phantom_length, output, path_type, number_of_detectors, tofs, wepls, elosses, angles, verbose):
142143
tofs_phantom_length = []
143144
wepls_phantom_length = []
144145
elosses_phantom_length = []
146+
angles_phantom_length = []
145147

146148
data = uproot.concatenate(f'{output}/l{int(phantom_length)}_*.root', library='np')
147149
pv(verbose, "Loaded", len(data['EventID']), "events for phantom length", phantom_length)
@@ -163,15 +165,20 @@ def process_phantom_length(phantom_length, output, path_type, number_of_detector
163165
if path_type != 'phantom_length' and number_of_hits < number_of_detectors + 2 and phantom_length > 0.:
164166
continue
165167

168+
us = data['Position_X'][event_mask]
169+
vs = data['Position_Y'][event_mask]
170+
ws = data['Position_Z'][event_mask]
171+
dus = data['Direction_X'][event_mask]
172+
dvs = data['Direction_Y'][event_mask]
173+
dws = data['Direction_Z'][event_mask]
174+
166175
times = data['PreGlobalTime'][event_mask]
176+
167177
tof = times[-1] - times[0]
168178

169179
if phantom_length == 0.:
170180
wepl = 0.
171181
else:
172-
us = data['Position_X'][event_mask]
173-
vs = data['Position_Y'][event_mask]
174-
ws = data['Position_Z'][event_mask]
175182
if path_type == 'phantom_length':
176183
# Length of the phantom
177184
wepl = phantom_length
@@ -189,13 +196,24 @@ def process_phantom_length(phantom_length, output, path_type, number_of_detector
189196

190197
eloss = data['KineticEnergy'][event_mask][0] - data['KineticEnergy'][event_mask][-1]
191198

199+
d_in_uw = np.array([dus[0],dws[0]])
200+
d_in_vw = np.array([dvs[0],dws[0]])
201+
d_out_uw = np.array([dus[-1],dws[-1]])
202+
d_out_vw = np.array([dvs[-1],dws[-1]])
203+
angle = [
204+
np.arccos(np.minimum(1., d_in_uw @ d_out_uw / (np.sqrt(d_in_uw @ d_in_uw) * np.sqrt(d_out_uw @ d_out_uw)))),
205+
np.arccos(np.minimum(1., d_in_vw @ d_out_vw / (np.sqrt(d_in_vw @ d_in_vw) * np.sqrt(d_out_vw @ d_out_vw))))
206+
]
207+
192208
tofs_phantom_length.append(tof)
193209
wepls_phantom_length.append(wepl)
194210
elosses_phantom_length.append(eloss)
211+
angles_phantom_length += angle
195212

196213
tofs[phantom_length] = tofs_phantom_length
197214
wepls[phantom_length] = wepls_phantom_length
198215
elosses[phantom_length] = elosses_phantom_length
216+
angles[phantom_length] = angles_phantom_length
199217

200218

201219
def tof_fit(
@@ -214,20 +232,21 @@ def tof_fit(
214232
tofs = manager.dict()
215233
wepls = manager.dict()
216234
elosses = manager.dict()
235+
angles = manager.dict()
217236

218237
results = []
219238
with Pool() as pool:
220239
for phantom_length in phantom_lengths:
221-
result = pool.apply_async(process_phantom_length, (phantom_length, output, path_type, number_of_detectors, tofs, wepls, elosses, verbose))
240+
result = pool.apply_async(process_phantom_length, (phantom_length, output, path_type, number_of_detectors, tofs, wepls, elosses, angles, verbose))
222241
results.append(result)
223242
pool.close()
224243
pool.join()
225244
for result in results:
226245
result.get()
227246

228-
def fit(xs, ys, xlabel, ylabel):
247+
def fit(xs, ys, xlabel, ylabel, xreduction=np.median):
229248

230-
xmedians = [np.median(xs[phantom_length]) for phantom_length in phantom_lengths]
249+
xmedians = [xreduction(xs[phantom_length]) for phantom_length in phantom_lengths]
231250
ymedians = [np.median(ys[phantom_length]) for phantom_length in phantom_lengths]
232251
xpercentile25 = [np.percentile(xs[phantom_length], 25) for phantom_length in phantom_lengths]
233252
xpercentile75 = [np.percentile(xs[phantom_length], 75) for phantom_length in phantom_lengths]
@@ -248,15 +267,14 @@ def fit(xs, ys, xlabel, ylabel):
248267

249268
if display or savefig:
250269
plt.figure()
251-
plt.plot(xmedians, ymedians, '+', label="Medians")
270+
plt.plot(xmedians, ymedians, '+')
252271

253272
tof_xs = np.linspace(np.min(xmedians), np.max(xmedians), 100)
254273
for d, p in ps.items():
255-
plt.plot(tof_xs, np.polyval(p, tof_xs), label=f"Polynomial fit (degree {d})")
274+
plt.plot(tof_xs, np.polyval(p, tof_xs))
256275

257276
plt.xlabel(xlabel)
258277
plt.ylabel(ylabel)
259-
plt.legend()
260278

261279
if savefig:
262280
plt.savefig(f'{output}/{xlabel}_to_{ylabel}_fit.pdf')
@@ -269,6 +287,7 @@ def fit(xs, ys, xlabel, ylabel):
269287

270288
fit(tofs, wepls, 'tof', 'wepl')
271289
fit(elosses, wepls, 'eloss', 'wepl')
290+
fit(angles, wepls, xlabel='angle', ylabel='wepl', xreduction=np.std)
272291

273292

274293
def pctweplfit(

0 commit comments

Comments
 (0)