Belle II Software  release-08-01-10
top.py
1 #!/usr/bin/env python3
2 
3 
10 
11 '''
12 Validation plots for TOP calibration.
13 '''
14 
15 from prompt import ValidationSettings
16 from ROOT import TFile, TH1F, TGraph, TCanvas, TLegend, gROOT, gStyle, PyConfig
17 from basf2 import B2ERROR
18 import sys
19 
20 
21 settings = ValidationSettings(name='TOP post-tracking calibration',
22  description=__doc__,
23  download_files=[],
24  expert_config=None)
25 
26 
27 def run_validation(job_path, input_data_path, requested_iov, expert_config):
28  '''
29  Makes validation plots
30  :job_path: path to top posttracking calibration output
31  :input_data_path: required argument but not used
32  :requested_iov: required argument but not used
33  :expert_config: required argument but not used
34  '''
35 
36  # input/output file names
37 
38  inputFileName = job_path + '/TOP_validation/0/algorithm_output/TOPCalValidation.root'
39  outputFileName = 'TOPValidation.pdf'
40 
41  # configuration
42 
43  PyConfig.IgnoreCommandLineOptions = True
44  gROOT.SetBatch(True)
45  gROOT.ForceStyle()
46  gStyle.SetOptStat(0)
47  gStyle.SetOptFit(1)
48  gStyle.SetHistMinimumZero(True)
49  gStyle.SetLabelSize(0.05, "X")
50  gStyle.SetLabelSize(0.05, "Y")
51  gStyle.SetTitleSize(0.06, "X")
52  gStyle.SetTitleSize(0.06, "Y")
53  gStyle.SetTitleOffset(0.7, "X")
54  gStyle.SetTitleOffset(0.8, "Y")
55  gStyle.SetGridColor(11)
56 
57  # open input file and create the canvas
58 
59  file_in = TFile.Open(inputFileName)
60  if (not file_in):
61  B2ERROR(inputFileName + ": file not found")
62  return
63  canvas = TCanvas("c1", "c1", 1000, 750)
64 
65  # prepare and fit histograms for channel T0
66 
67  channelT0s = []
68  residuals = []
69  residuals_all = TH1F("residuals_all", "ChannelT0 residuals; residuals [ns]", 200, -1.0, 1.0)
70  h_rms = TH1F("h_rms", "Width of residuals (rms); slot; r.m.s [ps]", 16, 0.5, 16.5)
71  h_core = TH1F("h_core", "Core width of residuals; slot; sigma [ps]", 16, 0.5, 16.5)
72  h_out = TH1F("h_out", "Outlayers (more than 3 sigma); slot; fraction [%]", 16, 0.5, 16.5)
73  for slot in range(1, 17):
74  name = "slot" + '{:0=2d}'.format(slot)
75  h = file_in.Get("channelT0_" + name)
76  channelT0s.append(h)
77  r = TH1F("residuals_" + name, "ChannelT0, " + name + "; residuals [ns]", 200, -1.0, 1.0)
78  residuals.append(r)
79  if not h:
80  continue
81  for i in range(1, h.GetNbinsX() + 1):
82  if h.GetBinError(i) > 0:
83  r.Fill(h.GetBinContent(i))
84  residuals_all.Fill(h.GetBinContent(i))
85  r.Fit("gaus", "Q")
86  residuals_all.Fit("gaus", "Q")
87  h_rms.SetBinContent(slot, r.GetRMS() * 1000)
88  fun = r.GetFunction("gaus")
89  if not fun:
90  continue
91  fun.SetLineWidth(1)
92  h_core.SetBinContent(slot, fun.GetParameter(2) * 1000)
93  mean = fun.GetParameter(1)
94  wid = fun.GetParameter(2)
95  n_all = 0
96  n_in = 0
97  for i in range(1, h.GetNbinsX() + 1):
98  if h.GetBinError(i) == 0:
99  continue
100  n_all += 1
101  if abs(h.GetBinContent(i) - mean) < 3 * wid:
102  n_in += 1
103  if n_all > 0:
104  h_out.SetBinContent(slot, (1 - n_in / n_all) * 100)
105  residuals_all.Fit("gaus", "Q")
106 
107  # open pdf file
108 
109  canvas.Print(outputFileName + "[")
110 
111  # make plots of channelT0 residuals vs. channel
112 
113  canvas.Clear()
114  canvas.Divide(4, 4)
115  graphs = []
116  for i, h in enumerate(channelT0s):
117  canvas.cd(i + 1)
118  if h:
119  h.SetMinimum(-1.0)
120  h.SetMaximum(1.0)
121  h.Draw()
122  g_over = TGraph()
123  g_under = TGraph()
124  for ibin in range(1, h.GetNbinsX() + 1):
125  if h.GetBinContent(ibin) > 1.0:
126  g_over.SetPoint(g_over.GetN(), h.GetBinCenter(ibin), 0.95)
127  elif h.GetBinContent(ibin) < -1.0:
128  g_under.SetPoint(g_under.GetN(), h.GetBinCenter(ibin), -0.95)
129  if g_over.GetN() > 0:
130  g_over.SetMarkerStyle(22)
131  g_over.SetMarkerColor(2)
132  g_over.Draw("P")
133  graphs.append(g_over)
134  if g_under.GetN() > 0:
135  g_under.SetMarkerStyle(23)
136  g_under.SetMarkerColor(2)
137  g_under.Draw("P")
138  graphs.append(g_under)
139  canvas.Print(outputFileName)
140 
141  # make plots of channelT0 residual distirbutions
142 
143  canvas.Clear()
144  canvas.Divide(4, 4)
145  gStyle.SetOptFit(0)
146  gStyle.SetOptStat("oue")
147  W = gStyle.GetStatW()
148  H = gStyle.GetStatH()
149  gStyle.SetStatW(0.4)
150  gStyle.SetStatH(0.3)
151  for i, h in enumerate(residuals):
152  canvas.cd(i + 1)
153  h.Draw()
154  canvas.Print(outputFileName)
155  gStyle.SetStatW(W)
156  gStyle.SetStatH(H)
157 
158  # make summary plots for channelT0
159 
160  canvas.Clear()
161  canvas.Divide(2, 2)
162  gStyle.SetOptFit(111)
163  gStyle.SetOptStat(0)
164  histos = [residuals_all, h_rms, h_core, h_out]
165  for i, h in enumerate(histos):
166  canvas.cd(i + 1)
167  h.Draw()
168  canvas.Print(outputFileName)
169 
170  # prepare commonT0 histogram
171 
172  commonT0 = file_in.Get("commonT0")
173  if commonT0:
174  commonT0.Scale(1000)
175  commonT0.SetYTitle(commonT0.GetYaxis().GetTitle().replace('[ns]', '[ps]'))
176  commonT0.SetMinimum(-100)
177  commonT0.SetMaximum(100)
178  commonT0.Fit("pol0", "Q")
179 
180  # make plots for commonT0
181 
182  canvas.Clear()
183  canvas.Divide(1, 2)
184  canvas.GetPad(2).SetGrid()
185  gStyle.SetHistMinimumZero(False)
186  histos = [commonT0, file_in.Get("runIndex")]
187  for i, h in enumerate(histos):
188  canvas.cd(i + 1)
189  if h:
190  h.SetMarkerStyle(20)
191  h.SetMarkerSize(0.7)
192  h.Draw()
193  canvas.Print(outputFileName)
194  gStyle.SetHistMinimumZero(True)
195 
196  # make plots for moduleT0
197 
198  canvas.Clear()
199  canvas.Divide(4, 4)
200  histos = []
201  for slot in range(1, 17):
202  canvas.cd(slot)
203  h = file_in.Get("moduleT0_slot" + '{:0=2d}'.format(slot))
204  if h:
205  h.Scale(1000)
206  h.SetYTitle(h.GetYaxis().GetTitle().replace('[ns]', '[ps]'))
207  h.SetMinimum(-100)
208  h.SetMaximum(100)
209  h.Fit("pol0", "Q")
210  histos.append(h)
211  canvas.Print(outputFileName)
212 
213  # prepare moduleT0 summary histograms
214 
215  h_offset = TH1F("h_offset", "ModuleT0: fitted offset; slot; p0 [ps]", 16, 0.5, 16.5)
216  h_chi = TH1F("h_chi", "ModuleT0: chi2/ndf; slot; #chi^{2}/ndf", 16, 0.5, 16.5)
217  h_res = TH1F("h_res", "ModuleT0: residuals; residual - p0 [ps]", 200, -100, 100)
218  h_pul = TH1F("h_pul", "ModuleT0: pulls; (residual - p0) / error", 200, -10, 10)
219  for i, h in enumerate(histos):
220  if not h:
221  continue
222  fun = h.GetFunction("pol0")
223  if not fun:
224  continue
225  p0 = fun.GetParameter(0)
226  err = fun.GetParError(0)
227  h_offset.SetBinContent(i + 1, p0)
228  h_offset.SetBinError(i + 1, err)
229  h_chi.SetBinContent(i + 1, fun.GetChisquare() / max(fun.GetNDF(), 1))
230  for ibin in range(1, h.GetNbinsX() + 1):
231  err = h.GetBinError(ibin)
232  if err > 0:
233  h_res.Fill(h.GetBinContent(ibin) - p0)
234  h_pul.Fill((h.GetBinContent(ibin) - p0) / err)
235 
236  # plot moduleT0 summary histograms
237 
238  canvas.Clear()
239  canvas.Divide(2, 2)
240  histos = [h_offset, h_chi, h_res, h_pul]
241  h_offset.SetStats(False)
242  h_chi.SetStats(False)
243  gStyle.SetOptStat("rme")
244  for i, h in enumerate(histos):
245  canvas.cd(i + 1)
246  h.Draw()
247  canvas.Print(outputFileName)
248  gStyle.SetOptStat(0)
249 
250  # plot fractions of active and active-and-calibrated channels
251 
252  canvas.Clear()
253  canvas.Divide(4, 4)
254  legends = []
255  for slot in range(1, 17):
256  canvas.cd(slot)
257  name = "slot" + '{:0=2d}'.format(slot)
258  histos = [file_in.Get("numActive_" + name), file_in.Get("numActiveCalibrated_" + name)]
259  legend = TLegend(0.1, 0.1, 0.7, 0.3)
260  legends.append(legend)
261  opt = ''
262  for i, h in enumerate(histos):
263  if h:
264  h.SetMinimum(0.0)
265  h.SetMaximum(1.05)
266  text = h.GetTitle().split(',')[0]
267  h.SetTitle(name)
268  h.SetLineColor(i+1)
269  h.Draw(opt)
270  opt = 'same'
271  legend.AddEntry(h, text)
272  if legend.GetNRows() > 0:
273  legend.Draw("same")
274  canvas.Print(outputFileName)
275 
276  # plot fractions of time base and channelT0 calibrated channels
277 
278  canvas.Clear()
279  canvas.Divide(4, 4)
280  legends = []
281  for slot in range(1, 17):
282  canvas.cd(slot)
283  name = "slot" + '{:0=2d}'.format(slot)
284  histos = [file_in.Get("numTBCalibrated_" + name), file_in.Get("numT0Calibrated_" + name)]
285  legend = TLegend(0.1, 0.1, 0.7, 0.3)
286  legends.append(legend)
287  opt = ''
288  for i, h in enumerate(histos):
289  if h:
290  h.SetMinimum(0.0)
291  h.SetMaximum(1.05)
292  text = h.GetTitle().split(',')[0]
293  h.SetTitle(name)
294  h.SetLineColor(i+1)
295  h.Draw(opt)
296  opt = 'same'
297  legend.AddEntry(h, text)
298  if legend.GetNRows() > 0:
299  legend.Draw("same")
300  canvas.Print(outputFileName)
301 
302  # plot threshold efficiencies
303 
304  canvas.Clear()
305  canvas.Divide(4, 4)
306  legends = []
307  for slot in range(1, 17):
308  canvas.cd(slot)
309  name = "slot" + '{:0=2d}'.format(slot)
310  h = file_in.Get("thrEffi_slot" + '{:0=2d}'.format(slot))
311  legend = TLegend(0.1, 0.1, 0.7, 0.3)
312  legends.append(legend)
313  if h:
314  h.SetMinimum(0.0)
315  h.SetMaximum(1.0)
316  text = h.GetTitle().split(',')[0]
317  h.SetTitle(name)
318  h.Draw()
319  legend.AddEntry(h, text)
320  legend.Draw("same")
321  canvas.Print(outputFileName)
322 
323  # plot BS13d asic shifts
324 
325  canvas.Clear()
326  canvas.Divide(2, 2)
327  for cb in range(4):
328  canvas.cd(cb + 1)
329  canvas.GetPad(cb + 1).SetGrid()
330  h = file_in.Get("asicShifts_" + str(cb))
331  if h:
332  h.SetMinimum(-50.0)
333  h.SetMaximum(50.0)
334  h.Draw()
335  canvas.Print(outputFileName)
336 
337  # plot offsets
338 
339  canvas.Clear()
340  canvas.Divide(2, 2)
341  offsets = [file_in.Get("svdOffset"), file_in.Get("cdcOffset")]
342  sigmas = [file_in.Get("svdSigma"), file_in.Get("cdcSigma")]
343  components = ['SVD', 'CDC']
344  colors = [4, 2]
345 
346  canvas.cd(1)
347  hmin = 0
348  hmax = 0
349  for h in offsets:
350  if h:
351  hmin = min(hmin, h.GetMinimum())
352  hmax = max(hmax, h.GetMaximum())
353  hmin = round(hmin, 0) - 1
354  hmax = round(hmax, 0) + 1
355  for i, h in enumerate(offsets):
356  if h:
357  h.SetMinimum(hmin)
358  h.SetMaximum(hmax)
359  h.SetMarkerStyle(24)
360  h.SetMarkerColor(colors[i])
361  h.SetLineColor(colors[i])
362  first = True
363  legend1 = TLegend()
364  for i, h in enumerate(offsets):
365  if not h or not sigmas[i] or sigmas[i].Integral() == 0:
366  continue
367  if first:
368  h.Draw()
369  first = False
370  else:
371  h.Draw("same")
372  legend1.AddEntry(h, components[i])
373  legend1.Draw("same")
374 
375  canvas.cd(2)
376  hmax = 0
377  for h in sigmas:
378  if h:
379  hmax = max(hmax, h.GetMaximum())
380  for i, h in enumerate(sigmas):
381  if h:
382  h.SetMinimum(0)
383  h.SetMaximum(hmax * 1.1)
384  h.SetMarkerStyle(24)
385  h.SetMarkerColor(colors[i])
386  h.SetLineColor(colors[i])
387  first = True
388  legend2 = TLegend()
389  for i, h in enumerate(sigmas):
390  if not h or h.Integral() == 0:
391  continue
392  if first:
393  h.Draw()
394  first = False
395  else:
396  h.Draw("same")
397  legend2.AddEntry(h, components[i])
398  legend2.Draw("same")
399 
400  fillPatt = [file_in.Get("fillPatternOffset"), file_in.Get("fillPatternFract")]
401  for i, h in enumerate(fillPatt):
402  canvas.cd(3 + i)
403  if h:
404  if i == 1:
405  for k in range(h.GetNbinsX()):
406  h.SetBinError(k + 1, h.GetBinContent(k + 1) / 1000)
407  h.Draw()
408 
409  canvas.Print(outputFileName)
410 
411  # close pdf file
412 
413  canvas.Print(outputFileName + "]")
414 
415  # plot photon hits, use png format to shorten file size
416 
417  canvas.Clear()
418  canvas.Divide(4, 4)
419  for slot in range(1, 17):
420  canvas.cd(slot)
421  h = file_in.Get("hits_slot" + '{:0=2d}'.format(slot))
422  if h:
423  h.Draw("colz")
424  canvas.SaveAs(outputFileName.replace('.pdf', 'Hits.png'))
425 
426 
427 if __name__ == "__main__":
428  run_validation(*sys.argv[1:])