Belle II Software  release-05-02-19
monitor_module.py
1 # !/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 from basf2 import *
5 from ROOT import Belle2, TH2F, TH1F, TFile, gStyle, TColor, TCanvas
6 import numpy
7 from math import pi
8 from interactive import embed
9 
10 
11 # make the monitoring plots
12 file_type = 'png'
13 
14 color1501 = TColor(1501, 35 / 255., 55 / 255., 59 / 255.)
15 color1502 = TColor(1502, 99 / 255., 120 / 255., 173 / 255.)
16 color1503 = TColor(1503, 235 / 255., 129 / 255., 27 / 255.)
17 color1504 = TColor(1504, 99 / 255., 173 / 255., 132 / 255.)
18 color1505 = TColor(1505, 123 / 255., 111 / 255., 37 / 255.)
19 
20 nWiresInLayer = [160, 192, 256, 320, 384]
21 
22 
23 def set_style(hist, color=1503, marker=20):
24  hist.SetLineColor(color)
25  hist.SetLineWidth(2)
26  hist.SetFillStyle(0)
27  hist.SetMarkerStyle(marker)
28  hist.SetMarkerSize(2)
29  hist.SetMarkerColor(color)
30 
31 
32 hall = TH2F('all', 'all', 5, 0, 5, 384, 0, 384)
33 hhit = TH2F('hit', 'hit', 5, 0, 5, 384, 0, 384)
34 hno_ghost = TH2F('ng', 'hit', 5, 0, 5, 384, 0, 384)
35 hghost = TH2F('ghost', 'hit', 5, 0, 5, 384, 0, 384)
36 
37 hlr = TH1F('lr', 'left right', 4, 0, 4)
38 hpri = TH1F('pri', 'priority position', 4, 0, 4)
39 hpritime = TH1F('pritime', 'priority time', 512, 0, 512)
40 hftime = TH1F('found time', 'found time', 48, -35, 13)
41 
42 used = numpy.zeros(2336, numpy.int)
43 in_tsim = numpy.zeros(2336, numpy.int)
44 
45 
46 class Monitor(Module):
47  """
48  Module to make some monitor plots for TSF
49  """
50 
51  def initialize(self):
52  """
53  Initilization
54  """
55 
56  self.event_info = Belle2.PyStoreObj('EventMetaData')
57 
58  self.tshits = Belle2.PyStoreArray('CDCTriggerSegmentHits')
59 
60  self.simhits = Belle2.PyStoreArray('TSimSegmentHits')
61 
62  self.first_run = self.event_info.getRun()
63 
64  self.nevents = 0
65 
66  def event(self):
67  """
68  event function
69  """
70  self.nevents += 1
71  used.fill(0)
72  in_tsim.fill(0)
73  for simhit in self.simhits:
74  if simhit.getISuperLayer() % 2 == 0:
75  iax, iw = simhit.getISuperLayer() // 2, simhit.getIWire()
76  if simhit.getPriorityPosition() == 1:
77  iw += 1
78  if iw == nWiresInLayer[iax]:
79  iw = 0
80  hall.Fill(iax, iw)
81  in_tsim[simhit.getSegmentID()] = 1
82  for hit in self.tshits:
83  ind = hit.getSegmentID()
84  # only fill the histogram if the same ID is not found in the event
85  # In other words, it can't be the same hit from another 2D
86  # even if the unpacker does not eliminate repeated hits.
87  iax, iw = hit.getISuperLayer() // 2, hit.getIWire()
88  if hit.getPriorityPosition() == 1:
89  iw += 1
90  if iw == nWiresInLayer[iax]:
91  iw = 0
92  if not used[ind]:
93  used[ind] = 1
94  hhit.Fill(iax, iw)
95  if in_tsim[ind]:
96  hno_ghost.Fill(iax, iw)
97  if not in_tsim[ind]:
98  hghost.Fill(iax, iw)
99  hlr.Fill(hit.getLeftRight())
100  hpri.Fill(hit.getPriorityPosition())
101  hpritime.Fill(hit.priorityTime())
102  hftime.Fill(hit.foundTime())
103 
104  def terminate(self):
105  """
106  termination
107  """
108  if self.nevents == 0:
109  B2WARNING("The monitor module is never called.\n" +
110  "There seems to be no CDC Trigger data at all!")
111  return
112  elif hhit.GetEntries() == 0:
113  B2WARNING("No recorded TS hits at all!")
114  return
115  elif hall.GetEntries() == 0:
116  B2ERROR("No simulated TS hits at all!")
117  return
118  if not os.path.exists('monitor_plots'):
119  os.mkdir('monitor_plots')
120  can = TCanvas('can2', 'can2', 800, 700)
121  gStyle.SetOptStat(0)
122 
123  nts = [160, 192, 256, 320, 384]
124 
125  slall = [[]] * 5
126  slhit = [[]] * 5
127  slghost = [[]] * 5
128  quos = [[]] * 5
129  slng = [[]] * 5
130  quong = [[]] * 5
131  quo_ghost = [[]] * 5
132 
133  # 1 bin corresponds to 8 TS (2 bins for a merger unit)
134  width = 8
135  for iax in range(5):
136  ibin = iax + 1
137  p = hall.ProjectionY('all{}'.format(iax), ibin, ibin)
138  p.SetBins(nts[iax], 0, 2 * pi)
139  p.Rebin(width)
140  slall[iax] = p
141 
142  q = hhit.ProjectionY('hit{}'.format(iax), ibin, ibin)
143  q.SetBins(nts[iax], 0, 2 * pi)
144  q.Rebin(width)
145  slhit[iax] = q
146 
147  g = hghost.ProjectionY('ghost{}'.format(iax), ibin, ibin)
148  g.SetBins(nts[iax], 0, 2 * pi)
149  g.Rebin(width)
150  slghost[iax] = g
151 
152  s = hno_ghost.ProjectionY('ng{}'.format(iax), ibin, ibin)
153  s.SetBins(nts[iax], 0, 2 * pi)
154  s.Rebin(width)
155  slng[iax] = s
156 
157  r = g.Clone('ghost{}'.format(iax))
158  r2 = s.Clone('quong{}'.format(iax))
159  g.Sumw2()
160  p.Sumw2()
161  s.Sumw2()
162  # get the ratio of (found hit / simulated hit) with binomial error
163  r.Divide(g, p, 1.0, 1.0, 'B')
164  quos[iax] = r
165  r2.Divide(s, p, 1.0, 1.0, 'B')
166  quong[iax] = r2
167 
168  for hits, name in [(slhit, 'data TS'),
169  (slall, 'TSIM')]:
170  for i in range(5):
171  h = hits[i]
172  h.SetTitle(f'SL{i * 2}')
173  set_style(h, 1501 + i, 20 + i)
174  if name in ['data TS', 'TSIM']:
175  try:
176  h.Scale(1 / h.Integral('width'))
177  except ZeroDivisionError:
178  B2WARNING(f'Not a single hit in SL{i * 2}!')
179  continue
180  height = max([g.GetMaximum() for g in hits])
181  for h in hits:
182  h.SetMaximum(1.1 * height)
183  h.SetMinimum(0)
184  options = 'L M E0'
185  if h.GetTitle() != 'SL0':
186  options += ' same'
187  h.Draw(options)
188  can.BuildLegend(.85, .76, .95, .95)
189  hits[0].SetTitle(name + ' hit distribution in run {}; #phi (rad)'.format(
190  self.first_run))
191  can.SaveAs('monitor_plots/' + name.split()[0] +
192  '_ts_hits_{:05d}.{}'.format(self.first_run, file_type))
193 
194  for ratio, name in [(quos, 'ghost rate'), (quong, 'efficiency (w.r.t. fast TSIM)')]:
195  upp = max([g.GetMaximum() for g in ratio])
196  low = min([g.GetMinimum() for g in ratio])
197  for i in range(5):
198  h = ratio[i]
199  h.SetTitle('SL{}'.format(2 * i))
200  h.SetMaximum(1.1 * upp)
201  h.SetMinimum(0.9 * low)
202  set_style(h, 1501 + i, 20 + i)
203  options = 'e0'
204  if i != 0:
205  options += ' same'
206  h.Draw(options)
207  can.BuildLegend(.91, .76, .98, .95)
208  ratio[0].SetTitle('TSF ' + name + ' in run {};#phi (rad)'.format(
209  self.first_run))
210  file_name = name.split()[0]
211  can.SaveAs('monitor_plots/ts_{}_{:05d}.{}'.format(file_name, self.first_run, file_type))
212 
213  # ghost distribution
214  for h in [hlr, hpri, hpritime, hftime]:
215  set_style(h, 1503)
216  h.Draw()
217  name = h.GetTitle().replace(' ', '_')
218  can.SaveAs('monitor_plots/ghost_{}_{:05d}.{}'.format(name, self.first_run, file_type))
monitor_module.Monitor.terminate
def terminate(self)
Definition: monitor_module.py:104
monitor_module.Monitor.first_run
first_run
get run ID
Definition: monitor_module.py:62
Belle2::PyStoreObj
a (simplified) python wrapper for StoreObjPtr.
Definition: PyStoreObj.h:69
monitor_module.Monitor.nevents
nevents
Number of events.
Definition: monitor_module.py:64
monitor_module.Monitor.initialize
def initialize(self)
Definition: monitor_module.py:51
monitor_module.Monitor
Definition: monitor_module.py:46
Belle2::getRun
static ExpRun getRun(map< ExpRun, pair< double, double >> runs, double t)
Get exp number + run number from time.
Definition: Splitter.cc:262
monitor_module.Monitor.event
def event(self)
Definition: monitor_module.py:66
monitor_module.Monitor.tshits
tshits
CDCTRG TS hit.
Definition: monitor_module.py:58
Belle2::PyStoreArray
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:58
monitor_module.Monitor.event_info
event_info
Event info.
Definition: monitor_module.py:56
monitor_module.Monitor.simhits
simhits
TSIM TS hit.
Definition: monitor_module.py:60