12from geometry
import check_components
13from L1trigger
import add_trigger_simulation
14from pxd
import add_pxd_simulation
15from svd
import add_svd_simulation
16from svd
import add_svd_reconstruction
17from tracking
import add_tracking_for_PXDDataReduction_simulation, add_roiFinder
20def check_simulation(path):
21 """Check if the minimum number of modules required for simulation are in
22 the path and in the correct order
"""
23 required = ['Gearbox',
'Geometry',
'FullSim']
27 for module
in path.modules():
28 module_type = module.type()
30 if module_type
in required:
32 if module_type
in found:
33 b2.B2ERROR(f
"Duplicate module in path: {module_type}")
35 found.append(module.type())
37 if len(required) != len(found):
41 b2.B2ERROR(f
"No '{r}' module found but needed for simulation")
43 elif required != found:
44 b2.B2ERROR(f
"Simulation modules in wrong order. Should be '{', '.join(required)}' but is '{', '.join(found)}'")
47def add_PXDDataReduction(path, components, pxd_unfiltered_digits='pxd_unfiltered_digits',
48 doCleanup=True, overrideDB=False, usePXDDataReduction=True, save_slow_pions_in_mc=False):
50 This function adds the standard simulation modules to a path.
51 @param pxd_unfiltered_digits: the name of the StoreArray containing the input PXDDigits
52 @param overrideDB: override settings
from the DB
with the value set
in 'usePXDDataReduction'
53 @param usePXDDataReduction:
if 'overrideDB==True', override settings
from the DB
54 @param doCleanup:
if 'doCleanup=True' temporary datastore objects are emptied
55 @param save_slow_pions_in_mc:
if True, additional Regions of Interest on the PXD are created to save the PXDDigits
56 of slow pions
from D* -> D pi^{\\pm} decays using the MCSlowPionPXDROICreator based on MC truth information
61 add_svd_reconstruction(path, isROIsimulation=
True)
64 svd_reco_tracks =
'__ROIsvdRecoTracks'
66 add_tracking_for_PXDDataReduction_simulation(path, components, svd_cluster=
'__ROIsvdClusters')
68 add_roiFinder(path, svd_reco_tracks)
70 if save_slow_pions_in_mc:
71 path.add_module(
'MCSlowPionPXDROICreator', PXDDigitsName=pxd_unfiltered_digits, ROIsName=
'ROIs')
74 pxd_digifilter = b2.register_module(
'PXDdigiFilter')
75 pxd_digifilter.param(
'ROIidsName',
'ROIs')
76 pxd_digifilter.param(
'PXDDigitsName', pxd_unfiltered_digits)
77 pxd_digifilter.param(
'PXDDigitsInsideROIName',
'PXDDigits')
78 pxd_digifilter.param(
'overrideDB', overrideDB)
79 pxd_digifilter.param(
'usePXDDataReduction', usePXDDataReduction)
80 path.add_module(pxd_digifilter)
84 StoreArrays_to_clean = [
'ROIs',
'__ROIsvdRecoDigits',
'__ROIsvdClusters',
'__ROIsvdRecoTracks',
85 'SPTrackCands__ROI',
'SpacePoints__ROI',
87 'SegmentNetwork__ROI',
'PXDInterceptsToROIs',
88 'RecoHitInformationsTo__ROIsvdClusters',
89 'SpacePoints__ROITo__ROIsvdClusters',
'__ROIsvdClustersToMCParticles',
90 '__ROIsvdRecoDigitsToMCParticles',
91 '__ROIsvdClustersTo__ROIsvdRecoDigits',
'__ROIsvdClustersToSVDTrueHits',
92 '__ROIsvdClustersTo__ROIsvdRecoTracks',
'__ROIsvdRecoTracksToPXDIntercepts',
93 '__ROIsvdRecoTracksToRecoHitInformations',
94 '__ROIsvdRecoTracksToSPTrackCands__ROI']
99 if pxd_unfiltered_digits !=
'PXDDigits':
100 unfiltered_pxd_digits_arrays = [pxd_unfiltered_digits,
101 f
'{pxd_unfiltered_digits}ToMCParticles',
102 f
'{pxd_unfiltered_digits}ToPXDDigits',
103 f
'{pxd_unfiltered_digits}ToPXDTrueHits']
104 StoreArrays_to_clean += unfiltered_pxd_digits_arrays
106 datastore_cleaner = b2.register_module(
'PruneDataStore')
107 datastore_cleaner.param(
'keepMatchedEntries',
False)
108 datastore_cleaner.param(
'matchEntries', StoreArrays_to_clean)
109 path.add_module(datastore_cleaner)
117 forceSetPXDDataReduction=False,
118 usePXDDataReduction=True,
119 cleanupPXDDataReduction=True,
120 generate_2nd_cdc_hits=False,
121 simulateT0jitter=True,
124 usePXDGatedMode=False,
125 skipExperimentCheckForBG=False,
126 save_slow_pions_in_mc=False):
128 This function adds the standard simulation modules to a path.
129 @param forceSetPXDDataReduction: override settings
from the DB
with the value set
in 'usePXDDataReduction'
130 @param usePXDDataReduction:
if 'forceSetPXDDataReduction==True', override settings
from the DB
131 @param cleanupPXDDataReduction:
if True the datastore objects used by PXDDataReduction are emptied
132 @param simulateT0jitter:
if True simulate L1 trigger jitter
133 @param isCosmics:
if True the filling pattern
is removed
from L1 jitter simulation
134 @param FilterEvents:
if True only the events that
pass the L1 trigger will survive simulation, the other are discarded.
135 Make sure you do need to filter events before you set the value to
True.
136 @param skipExperimentCheckForBG: If
True, skip the check on the experiment number consistency between the basf2
137 process
and the beam background files. Note that this check should be skipped only by experts.
138 @param save_slow_pions_in_mc:
if True, additional Regions of Interest on the PXD are created to save the PXDDigits
139 of slow pions
from D* -> D pi^{\\pm} decays using the MCSlowPionPXDROICreator based on MC truth information
142 path.add_module('StatisticsSummary').set_name(
'Sum_PreSimulation')
145 check_components(components)
148 if bkgfiles
is not None:
150 bkginput = b2.register_module(
'BGOverlayInput')
151 bkginput.param(
'inputFileNames', bkgfiles)
152 bkginput.param(
'skipExperimentCheck', skipExperimentCheckForBG)
153 path.add_module(bkginput)
155 bkgmixer = b2.register_module(
'BeamBkgMixer')
156 bkgmixer.param(
'backgroundFiles', bkgfiles)
158 bkgmixer.param(
'components', components)
159 path.add_module(bkgmixer)
161 if components
is None or 'PXD' in components:
163 bkgmixer.param(
'minTimePXD', -20000.0)
164 bkgmixer.param(
'maxTimePXD', 20000.0)
166 pxd_veto_emulator = b2.register_module(
'PXDInjectionVetoEmulator')
167 path.add_module(pxd_veto_emulator)
170 if 'Gearbox' not in path:
171 gearbox = b2.register_module(
'Gearbox')
172 path.add_module(gearbox)
175 if 'Geometry' not in path:
176 path.add_module(
'Geometry', useDB=
True)
177 if components
is not None:
178 b2.B2WARNING(
"Custom detector components specified: Will still build full geometry")
181 if simulateT0jitter
and 'EventT0Generator' not in path:
182 eventt0 = b2.register_module(
'EventT0Generator')
183 eventt0.param(
"isCosmics", isCosmics)
184 path.add_module(eventt0)
187 if 'SimulateEventLevelTriggerTimeInfo' not in path:
188 eventleveltriggertimeinfo = b2.register_module(
'SimulateEventLevelTriggerTimeInfo')
189 path.add_module(eventleveltriggertimeinfo)
192 if 'FullSim' not in path:
193 g4sim = b2.register_module(
'FullSim')
194 path.add_module(g4sim)
196 check_simulation(path)
203 if components
is None or 'CDC' in components:
204 cdc_digitizer = b2.register_module(
'CDCDigitizer')
205 cdc_digitizer.param(
"Output2ndHit", generate_2nd_cdc_hits)
206 path.add_module(cdc_digitizer)
209 if components
is None or 'TOP' in components:
210 top_digitizer = b2.register_module(
'TOPDigitizer')
211 path.add_module(top_digitizer)
214 if components
is None or 'ARICH' in components:
215 arich_digitizer = b2.register_module(
'ARICHDigitizer')
216 path.add_module(arich_digitizer)
219 if components
is None or 'ECL' in components:
220 ecl_digitizer = b2.register_module(
'ECLDigitizer')
221 if bkgfiles
is not None:
222 ecl_digitizer.param(
'Background', 1)
223 path.add_module(ecl_digitizer)
226 if components
is None or 'KLM' in components:
227 klm_digitizer = b2.register_module(
'KLMDigitizer')
228 path.add_module(klm_digitizer)
231 if bkgfiles
is not None and bkgOverlay:
232 m = path.add_module(
'BGOverlayExecutor', components=[
'CDC',
'TOP',
'ARICH',
'KLM'])
233 m.set_name(
'BGOverlayExecutor_CDC...KLM')
235 if components
is None or 'TRG' in components:
236 add_trigger_simulation(path, simulateT0jitter=simulateT0jitter, FilterEvents=FilterEvents)
239 if components
is None or 'SVD' in components:
240 add_svd_simulation(path)
241 if bkgfiles
is not None and bkgOverlay:
242 m = path.add_module(
'BGOverlayExecutor', components=[
'SVD'])
243 m.set_name(
'BGOverlayExecutor_SVD')
244 path.add_module(
'SVDShaperDigitSorter')
245 path.add_module(
'SVDZeroSuppressionEmulator')
248 if components
is None or 'PXD' in components:
249 if forceSetPXDDataReduction:
251 if usePXDDataReduction:
252 pxd_digits_name =
'pxd_unfiltered_digits'
253 add_pxd_simulation(path, digitsName=pxd_digits_name)
254 if bkgfiles
is not None and bkgOverlay:
255 m = path.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=pxd_digits_name)
256 m.set_name(
'BGOverlayExecutor_PXD')
257 path.add_module(
'PXDDigitSorter', digits=pxd_digits_name)
258 if usePXDDataReduction:
259 add_PXDDataReduction(
263 doCleanup=cleanupPXDDataReduction,
264 overrideDB=forceSetPXDDataReduction,
265 usePXDDataReduction=usePXDDataReduction,
266 save_slow_pions_in_mc=save_slow_pions_in_mc)
269 path_disableROI_Sim = b2.create_path()
270 add_pxd_simulation(path_disableROI_Sim, digitsName=
'PXDDigits')
271 if bkgfiles
is not None and bkgOverlay:
272 m = path_disableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'PXDDigits')
273 m.set_name(
'BGOverlayExecutor_PXD')
274 path_disableROI_Sim.add_module(
'PXDDigitSorter', digits=
'PXDDigits')
276 path_enableROI_Sim = b2.create_path()
277 add_pxd_simulation(path_enableROI_Sim, digitsName=
'pxd_unfiltered_digits')
278 if bkgfiles
is not None and bkgOverlay:
279 m = path_enableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'pxd_unfiltered_digits')
280 m.set_name(
'BGOverlayExecutor_PXD')
281 path_enableROI_Sim.add_module(
'PXDDigitSorter', digits=
'pxd_unfiltered_digits')
282 add_PXDDataReduction(
285 pxd_unfiltered_digits=
'pxd_unfiltered_digits',
286 doCleanup=cleanupPXDDataReduction,
287 save_slow_pions_in_mc=save_slow_pions_in_mc)
289 roi_condition_module_Sim = path.add_module(
'ROIfindingConditionFromDB')
290 roi_condition_module_Sim.if_true(path_enableROI_Sim, b2.AfterConditionPath.CONTINUE)
291 roi_condition_module_Sim.if_false(path_disableROI_Sim, b2.AfterConditionPath.CONTINUE)
294 path.add_module(
'StatisticsSummary').set_name(
'Sum_Simulation')