Belle II Software development
test_mixing_overlay_equivalence.py
1
8
9import basf2
10import ROOT
11from ROOT import Belle2
12import b2test_utils
13from svd import add_svd_simulation
14
15# ====================================================================
16# This test does the following:
17# 1. Simulate a few hundred ParticleGun events to produce a background
18# sample.
19# 2. Produce background overlay sample from background sample. .
20# 3. Set aside SimHits from a selected sensor to create signal-background
21# collisions.
22# 4. Inject collision SimHits, add background using the background mixer,
23# and digitize. Sort and save.
24# 5. Inject collision SimHits, digitize, and use background overlay
25# to add background. Sort and save.
26# 7. Compare SVDShaperDigits in the two ROOT files.
27#
28# NB: I sort both digit samples before saving. Normally, the digits
29# require sorting only after background overlay, but SVDDigitizer happens
30# to sort digits differently than ShaperDigitSorter. Both sortings are
31# correct, but the sorting to eventually correct is that in the
32# digitizer.
33# NB: Switching off electronic effects in SVDDigitizer prevents it from
34# adding noise digits.
35# ====================================================================
36
37
38xsimhits = []
39
40
41class SetAsideSimHits(basf2.Module):
42 """Set aside all SimHits on a selected sensor/side to create
43 signal/background collisions."""
44
45 def __init__(self):
46 '''initialize python module'''
47 super().__init__()
48
49
51
52 def event(self):
53 '''event'''
54 global xsimhits
55 storesimhits = Belle2.PyStoreArray("SVDSimHits")
56 for h in storesimhits:
57 if h.getSensorID == self.selected_sensorID:
58 xsimhits.append(h)
59
60
61class InjectSimHits(basf2.Module):
62 '''Inject stored SVDSimHits'''
63
64 def __init__(self):
65 '''initialize python module'''
66 super().__init__()
67
68
69 self.simhits = Belle2.PyStoreArray("SVDSimHits")
70
71 def initialize(self):
72 '''initialize'''
73 self.simhits.registerInDataStore()
74
75 def event(self):
76 '''event'''
77
78 global xsimhits
79 for h in xsimhits:
80 simhit = self.simhits.appendNew()
81 simhit.__assign__(h)
82
83
84if __name__ == "__main__":
85
87
88 basf2.B2INFO('Creating background data...')
89
90 create_bgfile = basf2.create_path()
91 create_bgfile.add_module('EventInfoSetter', expList=[0], runList=[0], evtNumList=[100])
92 create_bgfile.add_module('Gearbox')
93 create_bgfile.add_module('Geometry', components=['MagneticField', 'SVD'])
94 create_bgfile.add_module('ParticleGun')
95 create_bgfile.add_module('FullSim')
96 create_bgfile.add_module('BeamBkgTagSetter', backgroundType="twoPhoton", realTime=310.0)
97 create_bgfile.add_module('RootOutput', outputFileName='bgForMixing.root', branchNames=['BackgroundMetaData', 'SVDSimHits'])
99 b2test_utils.safe_process(create_bgfile)
100
101 basf2.B2INFO('Creating overlay data...')
102
103 create_ovrfile = basf2.create_path()
104 create_ovrfile.add_module('EventInfoSetter', expList=[0], runList=[0], evtNumList=[1])
105 create_ovrfile.add_module('Gearbox')
106 create_ovrfile.add_module('Geometry', components=['MagneticField', 'SVD'])
107 create_ovrfile.add_module('BeamBkgMixer', backgroundFiles=['bgForMixing.root'], minTime=-150, maxTime=150)
108 # Turn off generation of noise digits in SVDDigitizer.
109 add_svd_simulation(create_ovrfile)
110
111 create_ovrfile.add_module(SetAsideSimHits())
112 create_ovrfile.add_module('RootOutput', outputFileName='bgForOverlay.root', branchNames=['SVDShaperDigits'])
114 b2test_utils.safe_process(create_ovrfile)
115
116 basf2.B2INFO('Background mixing...')
117
118 produce_mixed = basf2.create_path()
119 produce_mixed.add_module('EventInfoSetter', expList=[0], runList=[0], evtNumList=[1])
120 produce_mixed.add_module('Gearbox')
121 produce_mixed.add_module('Geometry', components=['MagneticField', 'SVD'])
122 # Inject stored simhits
123 produce_mixed.add_module(InjectSimHits())
124 # Time window for background file to just cover one event
125 produce_mixed.add_module('BeamBkgMixer', backgroundFiles=['bgForMixing.root'], minTime=-150, maxTime=150)
126 # Turn off generation of noise digits in SVDDigitizer.
127 add_svd_simulation(produce_mixed)
128
129 produce_mixed.add_module('SVDShaperDigitSorter')
130 produce_mixed.add_module('RootOutput', outputFileName='mixedBg.root')
132 b2test_utils.safe_process(produce_mixed)
133
134 basf2.B2INFO('Background overlay...')
135
136 produce_overlaid = basf2.create_path()
137 produce_overlaid.add_module('EventInfoSetter', expList=[0], runList=[0], evtNumList=[1])
138 produce_overlaid.add_module('Gearbox')
139 produce_overlaid.add_module('Geometry', components=['MagneticField', 'SVD'])
140 produce_overlaid.add_module('BGOverlayInput', inputFileNames=['bgForOverlay.root'])
141 produce_overlaid.add_module(InjectSimHits())
142
143 add_svd_simulation(produce_overlaid)
144
145 produce_overlaid.add_module('BGOverlayExecutor')
146 # Sort digits after overlay
147 produce_overlaid.add_module('SVDShaperDigitSorter')
148 produce_overlaid.add_module('RootOutput', outputFileName='overlaidBg.root')
150 b2test_utils.safe_process(produce_overlaid)
151
152 basf2.B2INFO('Comparing...')
153
154 # Compare diigts stored in the two root files
155 f_mixed = ROOT.TFile('mixedBg.root')
156 tree_mixed = f_mixed.Get('tree')
157
158 f_over = ROOT.TFile('overlaidBg.root')
159 tree_over = f_over.Get('tree')
160
161 # We only have a single event in both files
162 n_good = 0
163 for evt1, evt2 in zip(tree_mixed, tree_over):
164 d_mixed = evt1.SVDShaperDigits
165 d_over = evt2.SVDShaperDigits
166 if (len(d_mixed) != len(d_over)):
167 basf2.B2ERROR('Lengths of SVDShaperDigit arrays DIFFER!')
168 break
169 for d1, d2 in zip(d_mixed, d_over):
170 match = True
171 match = match and (d1.getSensorID() == d2.getSensorID())
172 match = match and (d1.isUStrip() == d2.isUStrip())
173 match = match and (d1.getCellID() == d2.getCellID())
174 for s1, s2 in zip(d1.getSamples(), d2.getSamples()):
175 match = match and (int(s1) == int(s2))
176 if not match:
177 print(d1.toString())
178 print(d2.toString())
179 basf2.B2ERROR('Digits do not match.')
180 else:
181 n_good += 1
182
183 basf2.B2INFO(f'Processed {n_good} matching digits.')
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
def clean_working_directory()
Definition: __init__.py:189
def show_only_errors()
Definition: __init__.py:94
def safe_process(*args, **kwargs)
Definition: __init__.py:236