Belle II Software  release-08-01-10
validateOverlay.py
1 #!/usr/bin/env python3
2 
3 
10 
11 """
12 <header>
13  <output>overlayPlots.root</output>
14  <contact>marko.staric@ijs.si</contact>
15  <description>Runs BG overlay and makes validation histograms</description>
16 </header>
17 """
18 
19 import basf2 as b2
20 from simulation import add_simulation
21 import os
22 import glob
23 from ROOT import Belle2
24 from ROOT import TH1F, TFile, TNamed, TNtuple
25 import sys
26 import array
27 
28 b2.set_random_seed(123452)
29 
30 
31 class Histogrammer(b2.Module):
32 
33  '''
34  Make validation histograms for BG overlay.
35  This validation assumes that all channels are active
36  (no masked strip, dead pixels, ...)
37  '''
38 
39  def initialize(self):
40  ''' Initialize the Module: book histograms and set descriptions and checks'''
41 
42 
43  self.histhist = []
44  self.histhist.append(TH1F('PXDDigits', 'PXDDigits (no data reduction)',
45  200, 0, 100000))
46  self.histhist.append(TH1F('SVDShaperDigits', 'SVDShaperDigits', 100, 0, 10000))
47  self.histhist.append(TH1F('SVDShaperDigitsZS5', 'ZS5 SVDShaperDigits', 100, 0, 8000))
48  self.histhist.append(TH1F('CDCHits', 'CDCHits', 100, 0, 6000))
49  self.histhist.append(TH1F('TOPDigits', 'TOPDigits', 100, 0, 2000))
50  self.histhist.append(TH1F('ARICHDigits', 'ARICHDigits', 100, 0, 300))
51  self.histhist.append(TH1F('ECLDigits', 'ECLDigits, m_Amp > 500 (roughly 25 MeV)',
52  100, 0, 400))
53  self.histhist.append(TH1F('KLMDigits', 'KLMDigits', 150, 0, 150))
54 
55 
56  self.hist2hist2 = []
57  self.hist2hist2.append(TH1F('PXDL1Occupancy', 'PXD L1 Occupancy', 100, 0, 4))
58  self.hist2hist2.append(TH1F('PXDL2Occupancy', 'PXD L2 Occupancy', 100, 0, 4))
59  self.hist2hist2.append(TH1F('PXDOccupancy', 'PXD Occupancy', 100, 0, 4))
60  self.hist2hist2.append(TH1F('SVDOccupancy', 'SVD L3 Occupancy', 100, 0, 15))
61  self.hist2hist2.append(TH1F('CDCInnerHitRate', 'CDC Hit Rate per wire for the Inner layers', 100, 0, 1000))
62  self.hist2hist2.append(TH1F('CDCOuterHitRate', 'CDC Hit Rate per wire for the Outer layers', 100, 0, 1000))
63  self.hist2hist2.append(TH1F('CDCHitRate', 'CDC Hit Rate per wire', 100, 0, 1000))
64 
65 
66  self.nPXDL1nPXDL1 = 250*768*2 * 8
67 
68  self.nPXDL2nPXDL2 = 250*768*2 * 12
69 
70  self.nPXDnPXD = self.nPXDL1nPXDL1 + self.nPXDL2nPXDL2
71 
72 
73  self.nSVDL3nSVDL3 = 768 * 7 * 2 * 2
74 
75 
76  self.nCDCinnCDCin = 160 * 8
77 
78  self.CDCITInCDCITIn = 408.7 * 1e-6
79 
80  self.nCDCoutnCDCout = 160*6 + 192*6 + 224*6 + 256*6 + 288*6 + 320*6 + 352*6 + 384 * 6
81 
82  self.CDCIToutCDCITout = 754.6 * 1e-6
83 
84 
85  self.allhallh = self.histhist+self.hist2hist2
86 
87  for h in self.allhallh:
88  if h.GetName() == 'PXDOccupancy':
89  h.SetXTitle('PXD occupancy [%]')
90  descr = TNamed(
91  'Description',
92  'PXD L1+L2 Occupancy per event - no data reduction (with BG overlay only and no event generator)')
93  elif h.GetName() == 'PXDL1Occupancy':
94  h.SetXTitle('PXD L1 occupancy [%]')
95  descr = TNamed(
96  'Description',
97  'PXD L1 Occupancy per event - no data reduction (with BG overlay only and no event generator)')
98  elif h.GetName() == 'PXDL2Occupancy':
99  h.SetXTitle('PXD L2 occupancy [%]')
100  descr = TNamed(
101  'Description',
102  'PXD L2 Occupancy per event - no data reduction (with BG overlay only and no event generator)')
103  elif h.GetName() == 'SVDOccupancy':
104  h.SetXTitle('SVD L3 ZS5 occupancy - average u,v [%]')
105  descr = TNamed(
106  'Description',
107  'SVD ZS5 L3 Occupancy per event average u,v (with BG overlay only and no event generator)')
108  elif h.GetName() == 'CDCHitRate':
109  h.SetXTitle('CDC Hit Rate [kHz/wire]')
110  descr = TNamed(
111  'Description',
112  'CDC Hit Rate, averaged inner/outer wires (with BG overlay only and no event generator)')
113  elif h.GetName() == 'CDCInnerHitRate':
114  h.SetXTitle('CDC Hit Rate for Inner Layers [kHz/wire]')
115  descr = TNamed(
116  'Description',
117  'CDC Hit Rate per wire, for the Inner layers (with BG overlay only and no event generator)')
118  elif h.GetName() == 'CDCOuterHitRate':
119  h.SetXTitle('CDC Hit Rate for Outer Layers [kHz/wire]')
120  descr = TNamed(
121  'Description',
122  'CDC Hit Rate per wire, for the Outer layers (with BG overlay only and no event generator)')
123  else:
124  h.SetXTitle('number of digits in event')
125  descr = TNamed('Description', 'Number of background ' + h.GetName() +
126  ' per event (with BG overlay only and no event generator)')
127 
128  h.SetYTitle('entries per bin')
129  h.GetListOfFunctions().Add(descr)
130  check = TNamed('Check', 'Distribution must agree with its reference')
131  h.GetListOfFunctions().Add(check)
132  contact = TNamed('Contact', 'marko.staric@ijs.si')
133  h.GetListOfFunctions().Add(contact)
134  options = TNamed('MetaOptions', 'shifter')
135  h.GetListOfFunctions().Add(options)
136 
137  ntplvar = "PXDL1_occupancy:PXDL2_occupancy:PXD_occupancy:SVDL3ZS5_occupancy"
138  ntplvar += ":CDCInner_hitRate:CDCOuter_hitRate:CDC_hitRate"
139 
140 
141  self.ntplntpl = TNtuple("ntpl", "Average Background Levels", (ntplvar))
142 
143  def event(self):
144  ''' Event processor: fill histograms '''
145 
146  for h in self.histhist:
147  digits = Belle2.PyStoreArray(h.GetName())
148  if h.GetName() == 'ECLDigits':
149  n = 0
150  for digit in digits:
151  if digit.getAmp() > 500: # roughly 25 MeV
152  n += 1
153  h.Fill(n)
154  else:
155  h.Fill(digits.getEntries())
156 
157  # PXD
158  pxdDigits = Belle2.PyStoreArray('PXDDigits')
159  self.hist2hist2[2].Fill(pxdDigits.getEntries()/self.nPXDnPXD * 100)
160  nL1 = 0
161  nL2 = 0
162  for pxdDigit in pxdDigits:
163  if pxdDigit.getSensorID().getLayerNumber() == 1: # check L1/L2
164  nL1 += 1
165  else:
166  nL2 += 1
167  self.hist2hist2[0].Fill(nL1/self.nPXDL1nPXDL1 * 100)
168  self.hist2hist2[1].Fill(nL2/self.nPXDL2nPXDL2 * 100)
169 
170  # SVD
171  svdDigits = Belle2.PyStoreArray('SVDShaperDigitsZS5')
172  nL3 = 0
173  for svdDigit in svdDigits:
174  if svdDigit.getSensorID().getLayerNumber() == 3: # only check SVD L3
175  nL3 += 1
176  self.hist2hist2[3].Fill(nL3/self.nSVDL3nSVDL3 * 100)
177 
178  # CDC
179  cdcHits = Belle2.PyStoreArray('CDCHits')
180  self.hist2hist2[6].Fill(cdcHits.getEntries() / (self.nCDCinnCDCin * self.CDCITInCDCITIn + self.nCDCoutnCDCout * self.CDCIToutCDCITout))
181  nCDC_in = 0
182  nCDC_out = 0
183  for cdcHit in cdcHits:
184  if cdcHit.getICLayer() < 8: # count wires of inner/outer layers
185  nCDC_in += 1
186  else:
187  nCDC_out += 1
188  self.hist2hist2[4].Fill(nCDC_in/self.nCDCinnCDCin / self.CDCITInCDCITIn)
189  self.hist2hist2[5].Fill(nCDC_out/self.nCDCoutnCDCout / self.CDCIToutCDCITout)
190 
191  def terminate(self):
192  """ Write histograms to file."""
193 
194  # ntpl content "PXDL1:PXDL2:PXD:SVDL3ZS5:CDCInner:CDCOuter:CDC");
195  values = [self.hist2hist2[0].GetMean(), self.hist2hist2[1].GetMean(), self.hist2hist2[2].GetMean(),
196  self.hist2hist2[3].GetMean(), self.hist2hist2[4].GetMean(), self.hist2hist2[5].GetMean(),
197  self.hist2hist2[6].GetMean()]
198 
199  self.ntplntpl.Fill(array.array("f", values),)
200  tfile = TFile('overlayPlots.root', 'recreate')
201  self.ntplntpl.Write()
202  for h in self.allhallh:
203  h.Write()
204  tfile.Close()
205 
206 
207 bg = None
208 if len(sys.argv) == 2:
209  bg = glob.glob(str(sys.argv[1]) + '/*.root')
210 elif 'BELLE2_BACKGROUND_DIR' in os.environ:
211  bg = glob.glob(os.environ['BELLE2_BACKGROUND_DIR'] + '/*.root')
212  if bg is None:
213  b2.B2FATAL('No beam background samples found in folder ' +
214  os.environ['BELLE2_BACKGROUND_DIR'])
215  b2.B2INFO('Using background samples from ' + os.environ['BELLE2_BACKGROUND_DIR'])
216 else:
217  b2.B2FATAL('variable BELLE2_BACKGROUND_DIR is not set')
218 
219 # Create path
220 main = b2.create_path()
221 
222 # Set number of events to generate
223 eventinfosetter = b2.register_module('EventInfoSetter')
224 eventinfosetter.param({'evtNumList': [1000], 'runList': [1]})
225 main.add_module(eventinfosetter)
226 
227 # Simulation
228 add_simulation(main, bkgfiles=bg, bkgOverlay=True, usePXDDataReduction=False, forceSetPXDDataReduction=True,
229  simulateT0jitter=False)
230 
231 # Add SVD offline zero-suppression (ZS5)
232 main.add_module(
233  'SVDZeroSuppressionEmulator',
234  SNthreshold=5,
235  ShaperDigits='SVDShaperDigits',
236  ShaperDigitsIN='SVDShaperDigitsZS5',
237  FADCmode=True)
238 
239 # Make histograms
240 main.add_module(Histogrammer())
241 
242 # Show progress of processing
243 main.add_module('Progress')
244 
245 # Process events
246 b2.process(main)
247 
248 # Print call statistics
249 print(b2.statistics)
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
nCDCout
number of outer CDC wires
ntpl
ntuple to store background levels
nSVDL3
number of L3 strips (u+v)
nCDCin
number of inner CDC wires
allh
merged list of all histograms
nPXDL2
number of PXD pixels (L2)
CDCITout
integration time of the outer CDC layers [ms]
nPXDL1
number of PXD pixels (L1)
CDCITIn
integration time of the inner CDC layers [ms]
hist
list of digits histograms
hist2
list of occupancy-like histograms
nPXD
number of PXD pixels (L1+L2)