Belle II Software development
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
22from tracking import add_tracking_for_PXDDataReduction_simulation
23from tracking.validation.plot import ValidationPlot
24from ROOT import Belle2
25import collections
26import ROOT
27import basf2
28from svd import add_svd_reconstruction
29from simulation import add_simulation
30NAME = 'ROIFinding' # not used?
31CONTACT = '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
34OUTPUT_FILE = 'ROIFindingTrackingValidation.root'
35N_EVENTS = 1000
36
37ACTIVE = True
38
39
40def 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 Uncertainty along U'
181 h_statU_L1.xlabel = 'U stat uncertainty'
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 Uncertainty along V'
191 h_statV_L1.xlabel = 'V stat uncertainty (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 Uncertainty along U'
201 h_statU_L2.xlabel = 'U stat uncertainty (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 Uncertainty along V'
211 h_statV_L2.xlabel = 'V stat uncertainty (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
267if __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