Belle II Software  release-08-01-10
test_mixing_overlay_equivalence.py
1 
8 
9 import basf2
10 import ROOT
11 from ROOT import Belle2
12 import b2test_utils
13 from 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 
38 xsimhits = []
39 
40 
41 class 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 
50  self.selected_sensorIDselected_sensorID = Belle2.VxdID(3, 1, 1)
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_sensorIDselected_sensorID:
58  xsimhits.append(h)
59 
60 
61 class InjectSimHits(basf2.Module):
62  '''Inject stored SVDSimHits'''
63 
64  def __init__(self):
65  '''initialize python module'''
66  super().__init__()
67 
68 
69  self.simhitssimhits = Belle2.PyStoreArray("SVDSimHits")
70 
71  def initialize(self):
72  '''initialize'''
73  self.simhitssimhits.registerInDataStore()
74 
75  def event(self):
76  '''event'''
77 
78  global xsimhits
79  for h in xsimhits:
80  simhit = self.simhitssimhits.appendNew()
81  simhit.__assign__(h)
82 
83 
84 if __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('Processed {0} matching digits.'.format(n_good))
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