2 from __future__
import print_function
3 from past.builtins
import execfile
4 from builtins
import range
5 from builtins
import object
16 if sys.argv[0]
and "PYTHONSTARTUP" in os.environ:
19 from optparse
import OptionParser
21 usage =
"usage: %prog -n <nominal file> -t <test file> [-o <dir>] [-s] [-d] [-e 0,1] [--opdets=0,1] " 22 parser = OptionParser(usage=usage)
23 parser.add_option(
"-n",
"--nominal", dest=
"nominalfile", help=
"Nominal flashan file", metavar=
"F")
24 parser.add_option(
"-t",
"--test", dest=
"testfile", help=
"Test flashan file", metavar=
"F")
25 parser.add_option(
"-o",
"--outdir", dest=
"dir", help=
"Directory to output plots", default=
"plots")
26 parser.add_option(
"--flash", dest=
"flash", help=
"Flash-by-flash compare", default=
False, action=
"store_true")
27 parser.add_option(
"--hit", dest=
"hit", help=
"Hit-by-hit compare", default=
False, action=
"store_true")
28 parser.add_option(
"--assoc", dest=
"assoc", help=
"Assosciation-by-assosciation compare", default=
False, action=
"store_true")
29 parser.add_option(
"--plots", dest=
"plots", help=
"Hit and flash comparison plots", default=
False, action=
"store_true")
30 parser.add_option(
"--rootdir", dest=
"rootdir", help=
"TDirectory in root file from analyzer (%default)", default=
"flashana")
32 (options, args) = parser.parse_args()
34 if not (options.nominalfile
and options.testfile):
35 print(
"Both nominal file (-n) and test file (-t) required.")
38 if not (options.flash
or options.hit
or options.assoc
or options.plots):
39 print(
"No plots to make. Specify at least one of --flash, --hit, --assoc, --plots.")
45 execfile(os.environ[
"PYTHONSTARTUP"])
48 from HandyFuncs
import VerticalRange, GetHists, pbloop
49 from collections
import defaultdict
51 import progressbar
as pb
60 return (
abs(right / left - 1.) < tolerance )
61 except ZeroDivisionError:
75 if left.InBeamFrame != right.InBeamFrame: failures += [
'InBeamFrame']
76 if left.OnBeamTime != right.OnBeamTime: failures += [
'OnBeamTime' ]
77 if not ApproxCompare(left.YCenter, right.YCenter, tolerance): failures += [
'YCenter' ]
78 if not ApproxCompare(left.ZCenter, right.ZCenter, tolerance): failures += [
'ZCenter' ]
79 if not ApproxCompare(left.YWidth, right.YWidth, tolerance): failures += [
'YWidth' ]
80 if not ApproxCompare(left.ZWidth, right.ZWidth, tolerance): failures += [
'YWidth' ]
81 if not ApproxCompare(left.FlashTime, right.FlashTime, tolerance): failures += [
'FlashTime' ]
82 if not ApproxCompare(left.FlashFrame,right.FlashFrame,tolerance): failures += [
'Frame' ]
83 if not ApproxCompare(left.AbsTime, right.AbsTime, tolerance): failures += [
'AbsTime' ]
84 if not ApproxCompare(left.TotalPE, right.TotalPE, 0.5): failures += [
'TotalPE' ]
90 if left.EventID != right.EventID: failures += [
'EventID' ]
91 if left.HitFrame != right.HitFrame: failures += [
'HitFrame' ]
92 if left.FlashFrame != right.FlashFrame: failures += [
'FlashFrame' ]
94 if not ApproxCompare(left.HitPeakTime, right.HitPeakTime, tolerance): failures += [
'HitPeakTime' ]
95 if not ApproxCompare(left.HitPE, right.HitPE, tolerance): failures += [
'HitPE' ]
96 if not ApproxCompare(left.FlashTime, right.FlashTime, tolerance): failures += [
'FlashTime' ]
97 if not ApproxCompare(left.FlashPE, right.FlashPE, tolerance): failures += [
'FlashPE' ]
102 tolerance = 0.000000001
103 if left.Frame != right.Frame: failures += [
'Frame' ]
104 if not ApproxCompare(left.PeakTimeAbs, right.PeakTimeAbs, tolerance): failures += [
'PeakTimeAbs' ]
105 if not ApproxCompare(left.PeakTime, right.PeakTime, tolerance): failures += [
'PeakTime' ]
106 if not ApproxCompare(left.Width, right.Width, tolerance): failures += [
'Width' ]
107 if not ApproxCompare(left.Area, right.Area, tolerance): failures += [
'Area' ]
108 if not ApproxCompare(left.Amplitude, right.Amplitude, tolerance): failures += [
'Amplitude' ]
109 if not ApproxCompare(left.PE, right.PE, tolerance): failures += [
'PE' ]
110 if not ApproxCompare(left.FastToTotal, right.FastToTotal, tolerance): failures += [
'FastToTotal' ]
136 if not isinstance(other, Flash):
137 return NotImplemented
138 return self.
AbsTime < other.AbsTime
141 if not isinstance(other, Flash):
142 return NotImplemented
143 return self.
AbsTime <= other.AbsTime
146 if not isinstance(other, Flash):
147 return NotImplemented
148 return self.
AbsTime > other.AbsTime
151 if not isinstance(other, Flash):
152 return NotImplemented
153 return self.
AbsTime >= other.AbsTime
157 if not isinstance(other, Flash):
158 return NotImplemented
160 if self.
EventID != other.EventID:
return False 163 if "AbsTime" in failures
or "FlashTime" in failures:
return False 165 if len(failures) > 3:
171 result = self.
__eq__(other)
172 if result
is NotImplemented:
177 return "t={0.AbsTime:9.3f} q={0.TotalPE:7.2f} FlashID={0.FlashID:2} Frame={0.FlashFrame:1}".
format(self)
197 if not isinstance(other, Assoc):
198 return NotImplemented
206 if not isinstance(other, Assoc):
207 return NotImplemented
215 if not isinstance(other, Assoc):
216 return NotImplemented
217 return not (self <= other)
220 if not isinstance(other, Assoc):
221 return NotImplemented
222 return not (self < other)
225 if not isinstance(other, Assoc):
226 return NotImplemented
227 if self.
EventID != other.EventID:
return False 228 if self.
OpChannel != other.OpChannel:
return False 230 if "HitPeakTimeAbs" in failures \
231 or "HitPeakTime" in failures \
232 or "PE" in failures :
return False 236 result = self.
__eq__(other)
237 if result
is NotImplemented:
242 return "{0.OpChannel:2d} t={0.HitPeakTimeAbs:8.3f}/{0.FlashTimeAbs:8.3f} q={0.HitPE:7.2f}/{0.FlashPE:7.2f} frame={0.HitFrame:1}/{0.FlashFrame:1}".
format(self)
263 if not isinstance(other, Hit):
264 return NotImplemented
268 if not isinstance(other, Hit):
269 return NotImplemented
273 if not isinstance(other, Hit):
274 return NotImplemented
278 if not isinstance(other, Hit):
279 return NotImplemented
283 if not isinstance(other, Hit):
284 return NotImplemented
285 if self.
EventID != other.EventID:
return False 286 if self.
OpChannel != other.OpChannel:
return False 288 if "PeakTimeAbs" in failures \
289 or "PeakTime" in failures:
return False 290 if len(failures) > 0:
return False 294 result = self.
__eq__(other)
295 if result
is NotImplemented:
309 versions = [
"nominal",
"test" ]
314 files[S] = TFile(options.nominalfile)
315 files[R] = TFile(options.testfile)
321 hittrees[v] = files[v].Get(options.rootdir+
"/PerOpHitTree")
322 flashtrees[v] = files[v].Get(options.rootdir+
"/PerFlashTree")
323 assoctrees[v] = files[v].Get(options.rootdir+
"/FlashHitMatchTree")
337 for e
in range(flashtrees[v].GetEntries()):
338 flashtrees[v].GetEntry(e)
339 if flashtrees[v].EventID
not in all:
340 all[flashtrees[v].EventID] = defaultdict(list)
341 all[flashtrees[v].EventID][v].append(
Flash(flashtrees[v]))
343 for EventID
in sorted(all.keys()):
345 all[EventID][v].sort()
346 print(EventID,
":", len(all[EventID][S]), len(all[EventID][R]))
348 onlies = copy.deepcopy(all)
350 for E
in sorted(all.keys()):
359 for iR
in range(len(onlies[E][R])):
360 if onlies[E][S][iS] == onlies[E][R][iR]:
361 matches.append( { S: onlies[E][S].pop( iS ),
362 R: onlies[E][R].pop( iR ) } )
367 if iS >= len(onlies[E][S]):
371 print(
" matches", len(matches))
373 print(
" only", v, len(onlies[E][v]))
376 if len(onlies[E][v]):
378 for flsh
in onlies[E][v]:
380 print(
" ",flsh.PrintStr())
387 print(
" ", S+
":", flsh[S].PrintStr(),
" ", R+
":", flsh[R].PrintStr(),
" ".join(failures_here))
401 for e
in pbloop(list(range(hittrees[v].GetEntries()))):
402 hittrees[v].GetEntry(e)
403 if hittrees[v].EventID
not in onlies:
404 onlies[hittrees[v].EventID]= defaultdict(list)
405 onlies[hittrees[v].EventID][v].append(
Hit(hittrees[v]))
407 for EventID
in sorted(onlies.keys()):
409 onlies[EventID][v].sort()
410 print(EventID,
":", len(onlies[EventID][S]), len(onlies[EventID][R]))
413 for E
in sorted(onlies.keys()):
420 maxval = len(onlies[E][S])
421 widgets = [
'Entries: ',pb.Value(),
'/', pb.Total(),
' ', pb.Percentage(),
' ',
422 pb.Bar(marker=
'=',left=
'[',right=
']'),
424 pbar = pb.ProgressBar(widgets=widgets, maxval=maxval, term_width=100)
427 pbar.update(maxval-len(onlies[E][S]))
430 for iR
in range(len(onlies[E][R])):
431 if onlies[E][S][iS] == onlies[E][R][iR]:
432 matches.append( { S: onlies[E][S].pop( iS ),
433 R: onlies[E][R].pop( iR ) } )
438 if iS >= len(onlies[E][S]):
444 print(
" matches", len(matches))
446 print(
" only", v, len(onlies[E][v]))
449 if len(onlies[E][v]):
451 for flsh
in onlies[E][v]:
452 print(
" ",flsh.PrintStr())
471 for e
in pbloop(list(range(assoctrees[v].GetEntries()))):
472 assoctrees[v].GetEntry(e)
473 if assoctrees[v].EventID
not in onlies:
474 onlies[assoctrees[v].EventID] = defaultdict(list)
475 onlies[assoctrees[v].EventID][v].append(
Assoc(assoctrees[v]))
477 for EventID
in sorted(onlies.keys()):
479 onlies[EventID][v].sort()
480 print(EventID,
":", len(onlies[EventID][S]), len(onlies[EventID][R]))
483 for E
in sorted(onlies.keys()):
489 print(
"Unmatched lengths", S, len(onlies[E][S]), R, len(onlies[E][R]))
490 maxval = len(onlies[E][S])
491 widgets = [
'Event %i: '%E,pb.Value(),
'/', pb.Total(),
' ', pb.Percentage(),
' ',
492 pb.Bar(marker=
'=',left=
'[',right=
']'),
494 pbar = pb.ProgressBar(widgets=widgets, maxval=maxval, term_width=100)
496 while onlies[E][S]
and onlies[E][R]:
497 pbar.update(maxval-len(onlies[E][S]))
498 if onlies[E][S][0] == onlies[E][R][0]:
499 matches.append( { S: onlies[E][S].pop( 0 ),
500 R: onlies[E][R].pop( 0 ) } )
501 elif onlies[E][S][0] < onlies[E][R][0]:
502 matches.append( { S: onlies[E][S].pop( 0 ) } )
503 elif onlies[E][S][0] > onlies[E][R][0]:
504 matches.append( { R: onlies[E][R].pop( 0 ) } )
506 matches.append( { S: onlies[E][S].pop( 0 ) } )
507 matches.append( { R: onlies[E][R].pop( 0 ) } )
510 print(
"matched lengths ", S, len(onlies[E][S]), R, len(onlies[E][R]))
513 matches.append( { S: onlies[E][S].pop( 0 ) } )
515 matches.append( { R: onlies[E][R].pop( 0 ) } )
549 if S
in hit: print(S+
":", hit[S].PrintStr(), end=
' ')
550 else: print(
"{0:65}".
format(
""), end=
' ')
552 if R
in hit: print(
" ", R+
":", hit[R].PrintStr(), end=
' ')
553 else: print(
"{0:65}".
format(
""), end=
' ')
555 if S
in hit
and R
in hit:
557 print(
" ".join(failures_here))
575 if not os.path.exists(options.dir):
576 os.makedirs(options.dir)
578 color = { S:kBlack, R:kRed }
586 c1 = TCanvas(
"c1",
"c1")
588 for var, name, select
in [ (
"EventID",
"EventID",
""),
589 (
"OpChannel",
"OpChannel",
""),
590 (
"PeakTimeAbs",
"PeakTimeAbs",
""),
591 (
"PeakTime",
"PeakTime",
""),
592 (
"Frame",
"Frame",
""),
593 (
"Width",
"Width",
"Width<1"),
594 (
"TMath::Log10(Area)",
"Area",
""),
595 (
"TMath::Log10(Amplitude)",
"Amplitude",
""),
596 (
"TMath::Log10(PE)",
"PE",
""),
597 (
"FastToTotal",
"FastToTotal",
"")]:
599 hittrees[S].
Draw(
"{0}>>h{1}{2:d}({3:d})".
format(var,name,1,nbins), select,
"hist")
600 hittrees[R].
Draw(
"{0}>>h{1}{2:d}({3:d})".
format(var,name,2,nbins), select, hstyle+
"same")
601 h1 = gROOT.FindObject(
"h"+name+
"1")
602 h2 = gROOT.FindObject(
"h"+name+
"2")
603 h1.SetLineColor(color[S])
604 h2.SetLineColor(color[R])
606 h2.SetMarkerColor(color[R])
607 h2.SetMarkerStyle(mstyle)
608 c1.Print(os.path.join(options.dir,
"perhit_"+name+
".png"))
610 hRatio = h2.Clone(
"hRatio")
616 l1 = TLine(gPad.GetUxmin(), 1, gPad.GetUxmax(), 1)
618 l1.SetLineColor(kBlack)
621 c1.Print(os.path.join(options.dir,
"perhit_"+name+
"_ratio.png"))
624 for var, name, select
in [(
"EventID",
"EventID",
""),
625 (
"FlashID",
"FlashID",
""),
626 (
"YCenter",
"YCenter",
""),
627 (
"ZCenter",
"ZCenter",
""),
628 (
"YWidth",
"YWidth",
""),
629 (
"ZWidth",
"ZWidth",
""),
630 (
"FlashTime",
"FlashTime",
""),
631 (
"AbsTime",
"AbsTime",
""),
632 (
"InBeamFrame",
"InBeamFrame",
""),
633 (
"OnBeamTime",
"OnBeamTime",
""),
634 (
"TMath::Log10(TotalPE)",
"TotalPE",
"") ]:
636 flashtrees[S].
Draw(
"{0}>>h{1}{2:d}({3:d})".
format(var,name,1,nbins), select,
"hist")
637 flashtrees[R].
Draw(
"{0}>>h{1}{2:d}({3:d})".
format(var,name,2,nbins), select, hstyle+
"same")
638 h1 = gROOT.FindObject(
"h"+name+
"1")
639 h2 = gROOT.FindObject(
"h"+name+
"2")
640 h1.SetLineColor(color[S])
641 h2.SetLineColor(color[R])
642 h2.SetLineStyle(lstyle)
643 h2.SetMarkerColor(color[R])
644 h2.SetMarkerStyle(mstyle)
645 c1.Print(os.path.join(options.dir,
"perflash_"+name+
".png"))
647 hRatio = h2.Clone(
"hRatio")
651 VerticalRange([hRatio], ratio=
True, forceOne=
True, ignoreError=
True)
653 l1 = TLine(gPad.GetUxmin(), 1, gPad.GetUxmax(), 1)
656 l1.SetLineColor(kBlack)
658 c1.Print(os.path.join(options.dir,
"perflash_"+name+
"_ratio.png"))
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
def ListFailures(left, right)
def ApproxCompare(left, right, tolerance=0.001)
Define utility functions #.
def ListFailuresHit(left, right)
def VerticalRange(hists, xrange=(0, 0), ratio=False, forceOne=True, ignoreError=False, maxerr=0.25, absMax=-999, absMin=-999, buffer=0.05)
void Draw(const char *plot, const char *title)
def ListFailuresFlash(left, right)
def pbloop(iterable, name="Entries")
def CountFailures(left, right)
def ListFailuresAssoc(left, right)