@@ -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
201219def 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
274293def pctweplfit (
0 commit comments