29 from time
import sleep
30 from array
import array
32 from ROOT
import TStyle, TCanvas, TColor, TGraph, TGraphErrors
33 from ROOT
import TH1D, TH2D, TProfile, TFile, TF1
34 from ROOT
import gROOT
42 print(
"Failed to import 'larbatch_posix' or 'fhicl' modules")
43 print(
"Setup 'fhiclpy' first:\n\tsetup fhiclpy vV_VV_VV -q QQQ:QQQQ")
55 sys.argv = myargv[0:1]
56 if 'TERM' in os.environ:
57 del os.environ[
'TERM']
58 ROOT.gErrorIgnoreLevel = ROOT.kError
61 detector =
"experiment"
87 sum_weights = rr_hypoXWgt + ratio_hypoXWgt
88 hypo_x = (rr_hypoX*rr_hypoXWgt + ratio_hypoX*ratio_hypoXWgt) / sum_weights
89 hypo_x_err = np.sqrt(sum_weights) / sum_weights
95 kMinEntriesInProjection = 100
97 bin = metric_h2.GetYaxis().FindBin(metric_value);
98 bins = metric_h2.GetNbinsY();
100 metric_hypoXWgt = 0.;
102 while 0 < bin-bin_buff
or bin+bin_buff <= bins :
103 low_bin = bin-bin_buff
if 0 < bin-bin_buff
else 0
104 high_bin = bin+bin_buff
if bin+bin_buff <= bins
else -1
105 metric_px = metric_h2.ProjectionX(
"metric_px", low_bin, high_bin);
106 if metric_px.GetEntries() > kMinEntriesInProjection :
107 metric_hypoX = metric_px.GetRandom();
108 metric_rmsX = metric_px.GetRMS();
109 if metric_rmsX < fXBinWidth:
110 print(f
"metric_h2 projected on metric_value: {metric_value}, bin: {bin}, "
111 f
"bin_buff: {bin_buff}; has {metric_px.GetEntries()} entries.")
112 print(f
"metric_hypoX: {metric_hypoX}, metric_rmsX: {metric_rmsX}")
114 metric_hypoXWgt = 1/(metric_rmsX*metric_rmsX);
115 return (metric_hypoX, metric_hypoXWgt);
120 def y_bias(y_skew, hypo_x, y_bias_slope):
121 if detector ==
"sbnd":
122 return y_skew * hypo_x * hypo_x * y_bias_slope
123 elif detector ==
"icarus":
124 return y_skew * hypo_x * y_bias_slope
127 def z_bias(z_skew, hypo_x, z_bias_slope):
128 if detector ==
"sbnd":
129 return z_skew * hypo_x * z_bias_slope;
130 elif detector ==
"icarus":
131 return z_skew * hypo_x * z_bias_slope;
135 drift_distance = pset.DriftDistance
137 xbin_width = drift_distance/x_bins
138 half_bin_width = xbin_width/2.
139 y_bias_slope = pset.YBiasSlope
140 z_bias_slope = pset.ZBiasSlope
142 xvals = np.arange(half_bin_width, drift_distance, xbin_width)
143 xerrs = np.array([half_bin_width] * len(xvals))
144 dist_to_anode_bins = x_bins
145 dist_to_anode_low = 0.
146 dist_to_anode_up = drift_distance
147 if detector ==
"sbnd":
150 elif detector ==
"icarus":
151 if pset.Cryostat == 0:
154 if pset.Cryostat == 1:
158 profile_bins = x_bins
161 dy_spreads = [
None] * x_bins
162 dy_means = [
None] * x_bins
163 dy_h2 = TH2D(
"dy_h2",
"#Delta y",
164 dist_to_anode_bins, dist_to_anode_low, dist_to_anode_up,
165 pset.dy_bins, pset.dy_low, pset.dy_up)
166 dy_h2.GetXaxis().SetTitle(
"distance from anode (cm)")
167 dy_h2.GetYaxis().SetTitle(
"y_flash - y_TPC (cm)")
168 dy_prof = TProfile(
"dy_prof",
"Profile of dy_spreads in #Delta y",
169 profile_bins, dist_to_anode_low, dist_to_anode_up,
170 pset.dy_low*2, pset.dy_up*2, profile_option)
171 dy_prof.GetXaxis().SetTitle(
"distance from anode (cm)")
172 dy_prof.GetYaxis().SetTitle(
"y_flash - y_TPC (cm)")
173 dy_h1 = TH1D(
"dy_h1",
"",
174 profile_bins, dist_to_anode_low, dist_to_anode_up)
175 dy_h1.GetXaxis().SetTitle(
"distance from anode (cm)")
176 dy_h1.GetYaxis().SetTitle(
"y_flash - y_TPC (cm)")
178 dz_spreads = [
None] * x_bins
179 dz_means = [
None] * x_bins
180 dz_h2 = TH2D(
"dz_h2",
"#Delta z",
181 dist_to_anode_bins, dist_to_anode_low, dist_to_anode_up,
182 pset.dz_bins, pset.dz_low, pset.dz_up)
183 dz_h2.GetXaxis().SetTitle(
"distance from anode (cm)")
184 dz_h2.GetYaxis().SetTitle(
"z_flash - z_TPC (cm)")
185 dz_prof = TProfile(
"dz_prof",
"Profile of dz_spreads in #Delta z",
186 profile_bins, dist_to_anode_low, dist_to_anode_up,
187 pset.dz_low*2.5, pset.dz_up*2.5, profile_option)
188 dz_prof.GetXaxis().SetTitle(
"distance from anode (cm)")
189 dz_prof.GetYaxis().SetTitle(
"z_flash - z_TPC (cm)")
190 dz_h1 = TH1D(
"dz_h1",
"",
191 profile_bins, dist_to_anode_low, dist_to_anode_up)
192 dz_h1.GetXaxis().SetTitle(
"distance from anode (cm)")
193 dz_h1.GetYaxis().SetTitle(
"z_flash - z_TPC (cm)")
195 rr_spreads = [
None] * x_bins
196 rr_means = [
None] * x_bins
197 rr_h2 = TH2D(
"rr_h2",
"PE Spread",
198 dist_to_anode_bins, dist_to_anode_low, dist_to_anode_up,
199 pset.rr_bins, pset.rr_low, pset.rr_up)
200 rr_h2.GetXaxis().SetTitle(
"distance from anode (cm)")
201 rr_h2.GetYaxis().SetTitle(
"spread (cm)")
202 rr_prof = TProfile(
"rr_prof",
"Profile of PE Spread",
203 profile_bins, dist_to_anode_low, dist_to_anode_up,
204 pset.rr_low, pset.rr_up, profile_option)
205 rr_prof.GetXaxis().SetTitle(
"distance from anode (cm)")
206 rr_prof.GetYaxis().SetTitle(
"spread (cm)")
207 rr_h1 = TH1D(
"rr_h1",
"",
208 profile_bins, dist_to_anode_low, dist_to_anode_up)
209 rr_h1.GetXaxis().SetTitle(
"distance from anode (cm)")
210 rr_h1.GetYaxis().SetTitle(
"spread (cm)")
212 ratio_spreads = [
None] * x_bins
213 ratio_means = [
None] * x_bins
214 ratio_h2 = TH2D(
"ratio_h2",
"PE Ratio",
215 dist_to_anode_bins, dist_to_anode_low, dist_to_anode_up,
216 pset.ratio_bins, pset.ratio_low, pset.ratio_up)
217 ratio_h2.GetXaxis().SetTitle(
"distance from anode (cm)")
218 ratio_h2.GetYaxis().SetTitle(
"ratio")
219 ratio_prof = TProfile(
"ratio_prof",
"Profile of PE Ratio",
220 profile_bins, dist_to_anode_low, dist_to_anode_up,
221 pset.ratio_low, pset.ratio_up, profile_option)
222 ratio_prof.GetXaxis().SetTitle(
"distance from anode (cm)")
223 ratio_prof.GetYaxis().SetTitle(
"ratio")
224 ratio_h1 = TH1D(
"ratio_h1",
"",
225 profile_bins, dist_to_anode_low, dist_to_anode_up)
226 ratio_h1.GetXaxis().SetTitle(
"distance from anode (cm)")
227 ratio_h1.GetYaxis().SetTitle(
"ratio")
229 unfolded_score_scatter = TH2D(
"unfolded_score_scatter",
"Scatter plot of match scores",
230 2*dist_to_anode_bins, x_gl_low, x_gl_up,
231 pset.score_hist_bins, pset.score_hist_low, pset.score_hist_up*(3./5.))
232 unfolded_score_scatter.GetXaxis().SetTitle(
"X global (cm)")
233 unfolded_score_scatter.GetYaxis().SetTitle(
"match score (arbitrary)")
234 oldunfolded_score_scatter = TH2D(
"oldunfolded_score_scatter",
"Scatter plot of match scores, old metrics",
235 2*dist_to_anode_bins, x_gl_low, x_gl_up,
236 pset.score_hist_bins, pset.score_hist_low, pset.score_hist_up*(3./5.))
237 oldunfolded_score_scatter.GetXaxis().SetTitle(
"X global (cm)")
238 oldunfolded_score_scatter.GetYaxis().SetTitle(
"match score (arbitrary)")
239 match_score_scatter = TH2D(
"match_score_scatter",
"Scatter plot of match scores",
240 dist_to_anode_bins, dist_to_anode_low, dist_to_anode_up,
241 pset.score_hist_bins, pset.score_hist_low, pset.score_hist_up*(3./5.))
242 match_score_scatter.GetXaxis().SetTitle(
"distance from anode (cm)")
243 match_score_scatter.GetYaxis().SetTitle(
"match score (arbitrary)")
244 match_score_h1 = TH1D(
"match_score",
"Match Score",
245 pset.score_hist_bins, pset.score_hist_low, pset.score_hist_up)
246 match_score_h1.GetXaxis().SetTitle(
"match score (arbitrary)")
249 for e
in nuslice_tree:
250 if e.slices > e.true_nus:
continue
252 rr_h2.Fill(qX, e.flash_rr)
253 rr_prof.Fill(qX, e.flash_rr)
254 ratio_h2.Fill(qX, e.flash_ratio)
255 ratio_prof.Fill(qX, e.flash_ratio)
257 for e
in nuslice_tree:
258 if e.slices > e.true_nus:
continue
261 corr_flash_y = e.flash_yb -
y_bias(e.y_skew, hypo_x, y_bias_slope)
262 corr_flash_z = e.flash_zb -
z_bias(e.z_skew, hypo_x, z_bias_slope)
264 dy_h2.Fill(qX, corr_flash_y - e.charge_y)
265 dy_prof.Fill(qX, corr_flash_y - e.charge_y)
266 dz_h2.Fill(qX, corr_flash_z - e.charge_z)
267 dz_prof.Fill(qX, corr_flash_z - e.charge_z)
271 for ib
in list(range(0, profile_bins)):
273 dy_h1.SetBinContent(ibp, dy_prof.GetBinContent(ibp))
274 dy_h1.SetBinError(ibp, dy_prof.GetBinError(ibp))
275 dy_means[int(ib)] = dy_prof.GetBinContent(ibp)
276 dy_spreads[int(ib)] = dy_prof.GetBinError(ibp)
277 dz_h1.SetBinContent(ibp, dz_prof.GetBinContent(ibp))
278 dz_h1.SetBinError(ibp, dz_prof.GetBinError(ibp))
279 dz_means[int(ib)] = dz_prof.GetBinContent(ibp)
280 dz_spreads[int(ib)] = dz_prof.GetBinError(ibp)
281 rr_h1.SetBinContent(ibp, rr_prof.GetBinContent(ibp))
282 rr_h1.SetBinError(ibp, rr_prof.GetBinError(ibp))
283 rr_means[int(ib)] = rr_prof.GetBinContent(ibp)
284 rr_spreads[int(ib)] = rr_prof.GetBinError(ibp)
285 ratio_h1.SetBinContent(ibp, ratio_prof.GetBinContent(ibp))
286 ratio_h1.SetBinError(ibp, ratio_prof.GetBinError(ibp))
287 ratio_means[int(ib)] = ratio_prof.GetBinContent(ibp)
288 ratio_spreads[int(ib)] = ratio_prof.GetBinError(ibp)
290 for e
in nuslice_tree:
291 if e.slices > e.true_nus:
continue
295 isl = int(qX/xbin_width)
297 if dy_spreads[isl] <= 1.e-8:
298 print(
"Warning zero spread.\n",
299 f
"qX: {qX}. isl: {isl}. dy_spreads[isl]: {dy_spreads[isl]} ")
300 dy_spreads[isl] = dy_spreads[isl+1]
301 if dz_spreads[isl] <= 1.e-8:
302 print(
"Warning zero spread.\n",
303 f
"qX: {qX}. isl: {isl}. dz_spreads[isl]: {dz_spreads[isl]} ")
304 dz_spreads[isl] = dz_spreads[isl+1]
305 if rr_spreads[isl] <= 1.e-8:
306 print(
"Warning zero spread.\n",
307 f
"qX: {qX}. isl: {isl}. rr_spreads[isl]: {rr_spreads[isl]} ")
308 rr_spreads[isl] = rr_spreads[isl+1]
309 if ratio_spreads[isl] <= 1.e-8:
310 print(
"Warning zero spread.\n",
311 f
"qX: {qX}. isl: {isl}. ratio_spreads[isl]: {ratio_spreads[isl]} ")
312 ratio_spreads[isl] = ratio_spreads[isl+1]
315 corr_flash_y = e.flash_yb -
y_bias(e.y_skew, hypo_x, y_bias_slope)
316 corr_flash_z = e.flash_zb -
z_bias(e.z_skew, hypo_x, z_bias_slope)
318 score +=
abs(
abs(corr_flash_y-e.charge_y) - dy_means[isl])/dy_spreads[isl]
319 score +=
abs(
abs(corr_flash_z-e.charge_z) - dz_means[isl])/dz_spreads[isl]
320 score +=
abs(e.flash_rr-rr_means[isl])/rr_spreads[isl]
321 if (detector ==
"sbnd" and pset.UseUncoatedPMT)
or \
322 (detector ==
"icarus" and pset.UseOppVolMetric) :
323 score +=
abs(e.flash_ratio-ratio_means[isl])/ratio_spreads[isl]
325 oldunfolded_score_scatter.Fill(qXGl, e.score)
326 unfolded_score_scatter.Fill(qXGl, score)
327 match_score_scatter.Fill(qX, score)
328 match_score_h1.Fill(score)
330 metrics_filename =
'fm_metrics_' + detector +
'.root'
331 hfile = gROOT.FindObject(metrics_filename)
334 hfile = TFile(metrics_filename,
'RECREATE',
335 'Simple flash matching metrics for ' + detector.upper())
348 fitname_suffix = [
"_h",
"_m",
"_l"]
350 for e,suf
in zip(errors, fitname_suffix):
351 yvals = [a + e*b
for a, b
in zip(rr_means, rr_spreads)]
352 graph = TGraph(x_bins,
353 array(
'f', xvals), array(
'f', yvals))
354 name =
"rr_fit" + suf
355 print(
"Fitting: ", name)
356 f = TF1(name, pset.rr_TF1_fit)
359 rr_fit_funcs.append(f)
364 for e,suf
in zip(errors, fitname_suffix):
365 yvals = [a + e*b
for a, b
in zip(ratio_means, ratio_spreads)]
366 graph = TGraph(x_bins,
367 array(
'f', xvals), array(
'f', yvals))
368 name =
"ratio_fit" + suf
369 print(
"Fitting: ", name)
370 f = TF1(name, pset.ratio_TF1_fit)
373 ratio_fit_funcs.append(f)
374 match_score_scatter.Write()
375 oldunfolded_score_scatter.Write()
376 unfolded_score_scatter.Write()
377 match_score_h1.Write()
380 canv = TCanvas(
"canv")
383 crosses = TGraphErrors(x_bins,
384 array(
'f', xvals), array(
'f', dy_means),
385 array(
'f', xerrs), array(
'f', dy_spreads))
386 crosses.SetLineColor(ROOT.kAzure+9)
387 crosses.SetLineWidth(3)
388 crosses.Draw(
"Psame")
393 crosses = TGraphErrors(x_bins,
394 array(
'f', xvals), array(
'f', dz_means),
395 array(
'f', xerrs), array(
'f', dz_spreads))
396 crosses.SetLineColor(ROOT.kAzure+9)
397 crosses.SetLineWidth(3)
398 crosses.Draw(
"Psame")
403 crosses = TGraphErrors(x_bins,
404 array(
'f', xvals), array(
'f', rr_means),
405 array(
'f', xerrs), array(
'f', rr_spreads))
406 crosses.SetLineColor(ROOT.kAzure+9)
407 crosses.SetLineWidth(3)
408 crosses.Draw(
"Psame")
409 for f
in rr_fit_funcs:
410 f.SetLineColor(ROOT.kOrange+7)
411 f.DrawF1(0., drift_distance,
"lsame")
416 crosses = TGraphErrors(x_bins,
417 array(
'f', xvals), array(
'f', ratio_means),
418 array(
'f', xerrs), array(
'f', ratio_spreads))
419 crosses.SetLineColor(ROOT.kAzure+9)
420 crosses.SetLineWidth(3)
421 crosses.Draw(
"Psame")
422 for f
in ratio_fit_funcs:
423 f.SetLineColor(ROOT.kOrange+7)
424 f.DrawF1(0., drift_distance,
"lsame")
425 canv.Print(
"ratio.pdf")
428 oldunfolded_score_scatter.Draw()
429 canv.Print(
"oldunfolded_score_scatter.pdf")
432 unfolded_score_scatter.Draw()
433 canv.Print(
"unfolded_score_scatter.pdf")
436 match_score_scatter.Draw()
437 canv.Print(
"match_score_scatter.pdf")
440 match_score_h1.Draw()
441 canv.Print(
"match_score.pdf")
449 parser = argparse.ArgumentParser(prog=
'generate_simple_weighted_template.py')
450 parser.add_argument(
'file')
454 group = parser.add_mutually_exclusive_group(required=
True)
455 group.add_argument(
'--sbnd', action=
'store_true', help=
'Generate metrics for SBND')
456 group.add_argument(
'--icarus', action=
'store_true', help=
'Generate metrics for ICARUS')
457 args = parser.parse_args()
465 print(
"Generate metrics for SBND")
467 print(
"Generate metrics for ICARUS")
469 if not larbatch_posix.exists(args.file):
470 print(
'Input file %s does not exist.' % args.file)
473 print(
'\nOpening %s' % args.file)
474 rootfile = TFile.Open(args.file)
475 if not rootfile.IsOpen()
or rootfile.IsZombie():
476 print(
'Failed to open %s' % args.file)
480 fcl_params = fhicl.make_pset(
'flashmatch_sbnd.fcl')
481 pset =
dotDict(fcl_params[
'sbnd_simple_flashmatch'])
483 dir = rootfile.Get(args.file+
":/fmatch")
484 nuslice_tree = dir.Get(
"nuslicetree")
487 fcl_params = fhicl.make_pset(
'flashmatch_simple_icarus.fcl')
489 pset =
dotDict(fcl_params[
'icarus_simple_flashmatch_0'])
491 dir = rootfile.Get(args.file+
":/fmatchCryo0")
492 nuslice_tree = dir.Get(
"nuslicetree")
498 if __name__ ==
'__main__':
do one_file $F done echo for F in find $TOP name CMakeLists txt print
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.