ValidateOpDetSimulation.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 from __future__ import print_function
3 from past.builtins import execfile
4 from builtins import map
5 from builtins import range
6 import sys, os
7 
8 startup = False
9 if sys.argv[0] and "PYTHONSTARTUP" in os.environ:
10  startup = True
11 
12 from optparse import OptionParser
13 
14 usage = "usage: %prog -n <nominal file> -t <test file> [-o <dir>] [-s] [-d] [-e 0,1] [--opdets=0,1] "
15 parser = OptionParser(usage=usage)
16 parser.add_option("-n", "--nominal", dest="nominalfile", help="Nominal hist file", metavar="F")
17 parser.add_option("-t", "--test", dest="testfile", help="Test hist file", metavar="F")
18 parser.add_option("-o", "--outdir", dest="dir", help="Directory to output plots", default="plots")
19 parser.add_option("-s", "--sim", dest="sim", help="Make simulation plots", default=False, action="store_true")
20 parser.add_option("-d", "--digi", dest="digi", help="Make digitizer plots", default=False, action="store_true")
21 parser.add_option("-e", "--events", dest="events", help="List of events to draw an individual opdet, comma-separated")
22 parser.add_option( "--opdets", dest="opdets", help="List of opdets to draw, comma-separated", default="0")
23 parser.add_option( "--wide", dest="wide", help="Make widely binned plots (for uBooNE)")
24 
25 (options, args) = parser.parse_args()
26 
27 if not (options.nominalfile and options.testfile):
28  print("Both nominal file (-n) and test file (-t) required.")
29  sys.exit(1)
30 
31 if not (options.sim or options.digi or options.event):
32  print("No plots to make. Specify at least one of --sim, --digi, or --events=M,N,O.")
33  sys.exit(1)
34 
35 if not os.path.exists(options.dir):
36  os.makedirs(options.dir)
37 
38 # Load libraries after parsing arguments
39 
40 if startup:
41  execfile(os.environ["PYTHONSTARTUP"])
42 
43 from ROOT import *
44 from HandyFuncs import VerticalRange, GetHists, pbloop
45 from collections import defaultdict
46 
47 # Load the files
48 files = {}
49 versions = [ "nominal", "test" ]
50 colors = { "nominal":kBlue, "test":kRed }
51 N = versions[0]
52 T = versions[1]
53 
54 files[N] = TFile(options.nominalfile)
55 files[T] = TFile(options.testfile)
56 
57 c = {}
58 
59 
60 ############################
61 # Compare simulation plots #
62 ############################
63 
64 if options.sim:
65  if options.wide:
66  plotinfo = [ ("CountAll", "OpDetEvents", 100, 0, 100000),
67  ("CountAll", "OpDets", 100, 0, 5000) ]
68  else:
69  plotinfo = [ ("CountAll", "OpDetEvents", 100, 0, 4500),
70  ("CountAll", "OpDets", 100, 0, 500) ]
71  for var, treename, nbins, xmin, xmax in plotinfo:
72  trees = {}
73  for v in versions:
74  trees[v] = files[v].Get("pmtresponse/"+treename)
75 
76  c1 = TCanvas("_".join(["c",var,treename]),"_".join(["c",var,treename]))
77  dopt = "hist"
78  hists = {}
79  for v in versions:
80  hists[v] = TH1D("h"+v,v, nbins, xmin, xmax)
81  hists[v].SetLineColor(colors[v])
82  if "same" in dopt: hists[v].SetLineColor(2)
83  trees[v].Draw(var+">>h"+v, "", dopt)
84  if "same" not in dopt: dopt+="same"
85  print(v, var, hists[v].Integral())
86 
87  VerticalRange(GetHists(c1), ignoreError=True)
88  c1.Print(os.path.join(options.dir, "g4_{0}_by_{1}.png".format(treename, var)))
89  c[var,treename] = c1
90 
91 
92 ###########################
93 # Compare digitizer plots #
94 ###########################
95 
96 nom_channel_map = { 0:0, 1:0, 2:0,
97  3:1, 4:1, 5:1,
98  6:2, 7:2,
99  8:3, 9:3, 10:3,
100  11:4, 12:4, 13:4,
101  14:5, 15:5, 16:5,
102  17:6, 18:6, 19:6,
103  20:7, 21:7, 22:7 }
104 
105 
106 if options.digi:
107 
108  hists = { "per_Event":{},
109  "per_Channel":{}, "by_Channel":{}, "by_Channel_cnt":{},
110  "per_OpDet":{}, "by_OpDet":{}, "by_OpDet_cnt":{},
111  }
112 
113  for name in hists:
114  c[name] = TCanvas("c"+name, "c"+name)
115 
116  dopt = "hist"
117 
118  for v in versions:
119  eventintegral = defaultdict(int)
120  opdetintegral = defaultdict(int)
121 
122  hists["per_Event"][v] = TH1D("hperevent" +v, "ADCs Per Event", 100, 0, 4e4)
123  hists["per_Channel"][v] = TH1D("hperchannel" +v, "ADCs Per Channel", 100, 0, 3e3)
124  hists["by_Channel"][v] = TH1D("hbychannel" +v, "ADCs by Channel Number", 96, 0, 96)
125  hists["by_Channel_cnt"][v] = TH1D("hbychannelcnt" +v, "Count by Channel Number", 96, 0, 96)
126  hists["per_OpDet"][v] = TH1D("hperopdet" +v, "ADCs Per OpDet", 100, 0, 5000)
127  hists["by_OpDet"][v] = TH1D("hbyopdet" +v, "ADCs by OpDet Number", 8, 0, 8)
128  hists["by_OpDet_cnt"][v] = TH1D("hbyopdetcnt" +v, "Count by OpDet Number", 8, 0, 8)
129 
130  for name in hists:
131  hists[name][v].SetLineColor(colors[v])
132 
133 
134  tdir = files[v].Get("opdigiana")
135  keys = list(tdir.GetListOfKeys())
136  for rootkey in pbloop(keys, v+":"):
137  hist = tdir.Get(rootkey.GetName())
138 
139  event = int(rootkey.GetName().split("_")[1])
140  channel = int(rootkey.GetName().split("_")[3])
141  integral = hist.Integral()
142  if v == T: opdet = int(channel//12)
143  else: opdet = nom_channel_map[channel]
144 
145  eventintegral[event] += integral
146  hists["per_Channel"][v].Fill(integral)
147  hists["by_Channel"][v].Fill(channel, integral)
148  if integral > 0: hists["by_Channel_cnt"][v].Fill(channel)
149  opdetintegral[opdet,event] += integral
150  hists["by_OpDet"][v].Fill(opdet, integral)
151  if integral > 0: hists["by_OpDet_cnt"][v].Fill(opdet)
152 
153  for val in eventintegral.values():
154  if val > 4e4: print("Overflow: ",val)
155  hists["per_Event"][v].Fill(val)
156  for val in opdetintegral.values():
157  hists["per_OpDet"][v].Fill(val)
158 
159  for name in hists:
160  c[name].cd()
161  hists[name][v].Draw(dopt)
162 
163  if "same" not in dopt: dopt+="same"
164 
165  for name in hists:
166  c[name].cd()
167  if name == "per_Channel":
168  VerticalRange(GetHists(c[name]), ignoreError = True, absMin = 0.5)
169  c[name].SetLogy()
170  else:
171  VerticalRange(GetHists(c[name]), ignoreError = True)
172  c[name].Update()
173  c[name].Print(os.path.join(options.dir, "ADC_"+name+".png"))
174 
175 
176 
177 
178 if options.events:
179  events = list(map(int, options.events.split(",")))
180  opdets = list(map(int, options.opdets.split(",")))
181  for event, opdet in [ (e,o) for e in events for o in opdets ]:
182  channels = { N:[], T:[] }
183  for (c,o) in nom_channel_map.items():
184  if o == opdet:
185  channels[N].append(c)
186  channels[T] = list(range(o*12,(o+1)*12))
187 
188  hists = {}
189  trees = {}
190  for v in versions:
191  trees[v] = files[v].Get("pmtresponse/OpDets")
192  trees[v].GetEntry(8*(event-1)+opdet)
193 
194  tdir = files[v].Get("opdigiana")
195  for c in channels[v]:
196  htemp = tdir.Get("Event_{0:d}_OpDet_{1:d}_Pulse_0".format(event, c))
197  print(v, event, c, htemp.Integral())
198  if v not in hists:
199  hists[v] = htemp.Clone("h"+v)
200  hists[v].SetLineColor(colors[v])
201  hists[v].GetXaxis().SetRangeUser(0, 8000)
202  else:
203  hists[v].Add(htemp)
204 
205  ratio = {}
206  for v in versions:
207  ratio[v] = hists[v].Clone("hratio"+v)
208  ratio[v].Divide(hists[N])
209 
210  c1 = TCanvas("c1_event{0:d}_opdet{1:d}".format(event, opdet),"c_event{0:d}_opdet{1:d}")
211  dopt = ""
212  for v in versions:
213  hists[v].Draw(dopt)
214  print(v, hists[v].Integral(), hists[v].Integral()/trees[v].CountAll)
215  if "same" not in dopt: dopt += "same"
216  c1.Print(os.path.join(options.dir,"waveform_event{0:d}_opdet{1:d}.png".format(event, opdet)))
217 
218  c1 = TCanvas("c2_event{0:d}_opdet{1:d}".format(event, opdet),"c_event{0:d}_opdet{1:d}")
219  dopt = ""
220  for v in versions:
221  ratio[v].Draw(dopt)
222  if "same" not in dopt: dopt += "same"
223  c2.Print(os.path.join(options.dir,"waveform_event{0:d}_opdet{1:d}_ratio.png".format(event, opdet)))
224 
225  c[c1.GetName()] = c1
226  c[c2.GetName()] = c2
227 
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
Definition: qstring.cpp:11496
def GetHists(c1)
Definition: HandyFuncs.py:31
def VerticalRange(hists, xrange=(0, 0), ratio=False, forceOne=True, ignoreError=False, maxerr=0.25, absMax=-999, absMin=-999, buffer=0.05)
Definition: HandyFuncs.py:36
void Draw(const char *plot, const char *title)
Definition: gXSecComp.cxx:580
void split(std::string const &s, char c, OutIter dest)
Definition: split.h:35
def pbloop(iterable, name="Entries")
Definition: HandyFuncs.py:209
bool Update(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, PFPStruct &pfp, bool prt)
Definition: PFPUtils.cxx:1056