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