Belle II Software  release-08-01-10
roiFindingTrackingValidation.py
1 #!/usr/bin/env python3
2 
3 
10 
11 """
12 <header>
13  <contact>software-tracking@belle2.org</contact>
14  <output>ROIFindingValidation.root</output>
15  <description>
16  This module validates the ROI Finding module.
17  </description>
18 </header>
19 """
20 # <input>EvtGenSimNoBkg.root</input>
21 
22 from tracking import add_tracking_for_PXDDataReduction_simulation
23 from tracking.validation.plot import ValidationPlot
24 from ROOT import Belle2
25 import collections
26 import ROOT
27 import basf2
28 from svd import add_svd_reconstruction
29 from simulation import add_simulation
30 NAME = 'ROIFinding' # not used?
31 CONTACT = 'software-tracking@belle2.org'
32 # INPUT_FILE = '../EvtGenSimNoBkg.root' #can't use it because PXDDataReduction in simulated
33 # INPUT_FILE = 'simRootOutput.root' # for debugging purposes
34 OUTPUT_FILE = 'ROIFindingTrackingValidation.root'
35 N_EVENTS = 1000
36 
37 ACTIVE = True
38 
39 
40 def run():
41  """
42  Create EvtGen input sample and run a simple ROI validation.
43  """
44  class ROIFindingTrackingValidationPlots(basf2.Module):
45 
46  """Module to collect information about the ROIs (PXDIntercepts & ROIs) and to
47  generate validation plots on the performance of the ROIFinding module."""
48 
49  def __init__(
50  self,
51  name='',
52  contact='',
53  output_file_name=None,
54  nROIs=0
55  ):
56  """Constructor"""
57 
58  super().__init__()
59 
60  self.validation_name = NAME
61 
62  self.contact = CONTACT
63 
64  self.output_file_name = OUTPUT_FILE
65 
66 
67  self.nROIs = 0
68 
69  self.nPXDDigits = 0
70 
71  self.nPXDDigitsIN = 0
72 
73  # default binning used for resolution plots over pt
74  # self.resolution_pt_binning = [0.05, 0.1, 0.25, 0.4, 0.6, 1., 1.5, 2., 3., 4.]
75 
76  def initialize(self):
77  """Receive signal at the start of event processing"""
78 
79 
80  self.nROIs_L1 = collections.deque()
81 
82  self.nROIs_L2 = collections.deque()
83 
84 
85  self.drf = collections.deque()
86 
87 
88  self.statU_L1 = collections.deque()
89 
90  self.statV_L1 = collections.deque()
91 
92  self.statU_L2 = collections.deque()
93 
94  self.statV_L2 = collections.deque()
95 
96 
97  self.theta_phi_L1 = collections.deque()
98 
99  def event(self):
100  ''' ROIs quantities'''
101  rois = Belle2.PyStoreArray('ROIs')
102 
103  nL1_ROI = 0
104  nL2_ROI = 0
105  for roi in rois:
106  sensor = roi.getSensorID()
107  if(sensor.getLayerNumber() == 1):
108  nL1_ROI = nL1_ROI + 1
109  else:
110  nL2_ROI = nL2_ROI + 1
111 
112  self.nROIs_L1.append(nL1_ROI)
113  self.nROIs_L2.append(nL2_ROI)
114 
115  self.nROIs = self.nROIs + rois.getEntries()
116 
117  '''Data Reduction Factor '''
118  tot_pxd = Belle2.PyStoreArray('PXDDigits')
119  in_pxd = Belle2.PyStoreArray('filteredPXDDigits')
120 
121  if len(tot_pxd) > 0:
122  self.drf.append(len(in_pxd) / len(tot_pxd))
123 
124  ''' PXDIntercepts Statistical Error '''
125  inters = Belle2.PyStoreArray('PXDIntercepts')
126  for inter in inters:
127  sensor = Belle2.VxdID(inter.getSensorID())
128  if(sensor.getLayerNumber() == 1):
129  self.statU_L1.append(inter.getSigmaU())
130  self.statV_L1.append(inter.getSigmaV())
131  else:
132  self.statU_L2.append(inter.getSigmaU())
133  self.statV_L2.append(inter.getSigmaV())
134 
135  def terminate(self):
136  """Receive signal at the end of event processing"""
137 
138  contact = self.contact
139  basf2.B2RESULT(f"total nROIs = {self.nROIs}")
140 
141  ''' Saving'''
142 
143  output_tfile = ROOT.TFile(self.output_file_name, 'recreate')
144 
145  h_nROIs_L1 = ValidationPlot('h_nROIs_L1')
146  h_nROIs_L1.hist(self.nROIs_L1, bins=100, lower_bound=0, upper_bound=100)
147  h_nROIs_L1.contact = contact
148  h_nROIs_L1.check = 'average of 25 +/- 10 is expected'
149  h_nROIs_L1.description = 'ROIs on L1'
150  h_nROIs_L1.title = 'ROIs on L1'
151  h_nROIs_L1.xlabel = 'number of ROIs'
152  h_nROIs_L1.ylabel = ''
153  h_nROIs_L1.write(output_tfile)
154 
155  h_nROIs_L2 = ValidationPlot('h_nROIs_L2')
156  h_nROIs_L2.hist(self.nROIs_L2, bins=100, lower_bound=0, upper_bound=100)
157  h_nROIs_L2.contact = contact
158  h_nROIs_L2.check = 'average of 25 +/- 10 is expected'
159  h_nROIs_L2.description = 'ROIs on L2'
160  h_nROIs_L2.title = 'ROIs on L2'
161  h_nROIs_L2.xlabel = 'number of ROIs'
162  h_nROIs_L2.ylabel = ''
163  h_nROIs_L2.write(output_tfile)
164 
165  h_drf = ValidationPlot('h_drf')
166  h_drf.hist(self.drf, bins=100, lower_bound=0, upper_bound=1)
167  h_drf.contact = contact
168  h_drf.check = 'with no bkg, the average should be around 70%'
169  h_drf.description = 'Fraction of PXDDDigits inside ROIs'
170  h_drf.title = 'Fraction of PXDDDigits inside ROIs'
171  h_drf.xlabel = 'DRF'
172  h_drf.ylabel = ''
173  h_drf.write(output_tfile)
174 
175  h_statU_L1 = ValidationPlot('h_statU_L1')
176  h_statU_L1.hist(self.statU_L1, bins=100, lower_bound=0, upper_bound=0.2)
177  h_statU_L1.contact = contact
178  h_statU_L1.check = 'average should be around 0.021 cm'
179  h_statU_L1.description = 'Statistical Error of the Intercept on L1 planes, along U'
180  h_statU_L1.title = 'L1 Intercept Statistical Uncertainity along U'
181  h_statU_L1.xlabel = 'U stat uncertainity'
182  h_statU_L1.ylabel = ''
183  h_statU_L1.write(output_tfile)
184 
185  h_statV_L1 = ValidationPlot('h_statV_L1')
186  h_statV_L1.hist(self.statV_L1, bins=100, lower_bound=0, upper_bound=0.2)
187  h_statV_L1.contact = contact
188  h_statV_L1.check = 'average should be around 0.021 cm'
189  h_statV_L1.description = 'Statistical Error of the Intercept on L1 planes, along V'
190  h_statV_L1.title = 'L1 Intercept Statistical Uncertainity along V'
191  h_statV_L1.xlabel = 'V stat uncertainity (cm)'
192  h_statV_L1.ylabel = ''
193  h_statV_L1.write(output_tfile)
194 
195  h_statU_L2 = ValidationPlot('h_statU_L2')
196  h_statU_L2.hist(self.statU_L2, bins=100, lower_bound=0, upper_bound=0.2)
197  h_statU_L2.contact = contact
198  h_statU_L2.check = 'average should be around 0.015 cm'
199  h_statU_L2.description = 'Statistical Error of the Intercept on L2 planes, along U'
200  h_statU_L2.title = 'L2 Intercept Statistical Uncertainity along U'
201  h_statU_L2.xlabel = 'U stat uncertainity (cm)'
202  h_statU_L2.ylabel = ''
203  h_statU_L2.write(output_tfile)
204 
205  h_statV_L2 = ValidationPlot('h_statV_L2')
206  h_statV_L2.hist(self.statV_L2, bins=100, lower_bound=0, upper_bound=0.2)
207  h_statV_L2.contact = contact
208  h_statV_L2.check = 'average should be around 0.016 cm'
209  h_statV_L2.description = 'Statistical Error of the Intercept on L2 planes, along V'
210  h_statV_L2.title = 'L2 Intercept Statistical Uncertainity along V'
211  h_statV_L2.xlabel = 'V stat uncertainity (cm)'
212  h_statV_L2.ylabel = ''
213  h_statV_L2.write(output_tfile)
214 
215  output_tfile.Close()
216 
217  """ Steering """
218 
219  basf2.set_random_seed(1509)
220 
221  path = basf2.create_path()
222 
223  path.add_module('EventInfoSetter', evtNumList=N_EVENTS)
224  path.add_module('EvtGenInput')
225  add_simulation(path, forceSetPXDDataReduction=True, usePXDDataReduction=False)
226  add_svd_reconstruction(path, isROIsimulation=True)
227 
228  # path.add_module('RootInput', inputFileName=INPUT_FILE, entrySequences=["0:{}".format(N_EVENTS-1)])
229  # path.add_module('Gearbox')
230  # path.add_module('Geometry')
231 
232  pxd_unfiltered_digits = 'PXDDigits'
233  pxd_filtered_digits = 'filteredPXDDigits'
234 
235  # SVD tracking
236  svd_reco_tracks = '__ROIsvdRecoTracks'
237  add_tracking_for_PXDDataReduction_simulation(path, ['SVD', 'CDC'], '__ROIsvdClusters') # CDC is not used at the moment!
238 
239  # ROI Finding
240  pxdDataRed = basf2.register_module('PXDROIFinder')
241  param_pxdDataRed = {
242  'recoTrackListName': svd_reco_tracks,
243  'PXDInterceptListName': 'PXDIntercepts',
244  'ROIListName': 'ROIs',
245  }
246  pxdDataRed.param(param_pxdDataRed)
247  path.add_module(pxdDataRed)
248 
249  # Filtering of PXDDigits
250  pxd_digifilter = basf2.register_module('PXDdigiFilter')
251  pxd_digifilter.param('ROIidsName', 'ROIs')
252  pxd_digifilter.param('PXDDigitsName', pxd_unfiltered_digits)
253  pxd_digifilter.param('PXDDigitsInsideROIName', pxd_filtered_digits)
254  pxd_digifilter.param('PXDDigitsOutsideROIName', 'PXDDigitsOutside')
255  path.add_module(pxd_digifilter)
256 
257  ROIValidationPlots = ROIFindingTrackingValidationPlots()
258  path.add_module(ROIValidationPlots)
259 
260  path.add_module('Progress')
261 
262  print(path)
263  basf2.process(path)
264  print(basf2.statistics)
265 
266 
267 if __name__ == '__main__':
268  if ACTIVE:
269  run()
270  else:
271  print("This validation deactivated and thus basf2 is not executed.\n"
272  "If you want to run this validation, please set the 'ACTIVE' flag above to 'True'.\n"
273  "Exiting.")
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33