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(
50 pxd_unfiltered_digits='pxd_unfiltered_digits',
53 usePXDDataReduction=True,
54 save_slow_pions_in_mc=False,
55 save_all_charged_particles_in_mc=False):
57 This function adds the standard simulation modules to a path.
58 @param pxd_unfiltered_digits: the name of the StoreArray containing the input PXDDigits
59 @param overrideDB: override settings
from the DB
with the value set
in 'usePXDDataReduction'
60 @param usePXDDataReduction:
if 'overrideDB==True', override settings
from the DB
61 @param doCleanup:
if 'doCleanup=True' temporary datastore objects are emptied
62 @param save_slow_pions_in_mc:
if True, additional Regions of Interest on the PXD are created to save the PXDDigits
63 of slow pions
from D* -> D pi^{\\pm} decays using the MCSlowPionPXDROICreator based on MC truth information
68 add_svd_reconstruction(path, isROIsimulation=
True)
71 svd_reco_tracks =
'__ROIsvdRecoTracks'
73 add_tracking_for_PXDDataReduction_simulation(path, components, svd_cluster=
'__ROIsvdClusters')
75 add_roiFinder(path, svd_reco_tracks)
77 if save_slow_pions_in_mc
or save_all_charged_particles_in_mc:
78 path.add_module(
'MCPXDROICreator',
79 PXDDigitsName=pxd_unfiltered_digits,
81 createROIForSlowPionsOnly=save_slow_pions_in_mc,
82 createROIForAll=save_all_charged_particles_in_mc)
85 pxd_digifilter = b2.register_module(
'PXDdigiFilter')
86 pxd_digifilter.param(
'ROIidsName',
'ROIs')
87 pxd_digifilter.param(
'PXDDigitsName', pxd_unfiltered_digits)
88 pxd_digifilter.param(
'PXDDigitsInsideROIName',
'PXDDigits')
89 pxd_digifilter.param(
'overrideDB', overrideDB)
90 pxd_digifilter.param(
'usePXDDataReduction', usePXDDataReduction)
91 path.add_module(pxd_digifilter)
95 StoreArrays_to_clean = [
'ROIs',
'__ROIsvdRecoDigits',
'__ROIsvdClusters',
'__ROIsvdRecoTracks',
96 'SPTrackCands__ROI',
'SpacePoints__ROI',
98 'SegmentNetwork__ROI',
'PXDInterceptsToROIs',
99 'RecoHitInformationsTo__ROIsvdClusters',
100 'SpacePoints__ROITo__ROIsvdClusters',
'__ROIsvdClustersToMCParticles',
101 '__ROIsvdRecoDigitsToMCParticles',
102 '__ROIsvdClustersTo__ROIsvdRecoDigits',
'__ROIsvdClustersToSVDTrueHits',
103 '__ROIsvdClustersTo__ROIsvdRecoTracks',
'__ROIsvdRecoTracksToPXDIntercepts',
104 '__ROIsvdRecoTracksToRecoHitInformations',
105 '__ROIsvdRecoTracksToSPTrackCands__ROI']
110 if pxd_unfiltered_digits !=
'PXDDigits':
111 unfiltered_pxd_digits_arrays = [pxd_unfiltered_digits,
112 f
'{pxd_unfiltered_digits}ToMCParticles',
113 f
'{pxd_unfiltered_digits}ToPXDDigits',
114 f
'{pxd_unfiltered_digits}ToPXDTrueHits']
115 StoreArrays_to_clean += unfiltered_pxd_digits_arrays
117 datastore_cleaner = b2.register_module(
'PruneDataStore')
118 datastore_cleaner.param(
'keepMatchedEntries',
False)
119 datastore_cleaner.param(
'matchEntries', StoreArrays_to_clean)
120 path.add_module(datastore_cleaner)
128 forceSetPXDDataReduction=False,
129 usePXDDataReduction=True,
130 cleanupPXDDataReduction=True,
131 generate_2nd_cdc_hits=False,
132 simulateT0jitter=True,
135 usePXDGatedMode=False,
136 skipExperimentCheckForBG=False,
137 save_slow_pions_in_mc=False,
138 save_all_charged_particles_in_mc=False):
140 This function adds the standard simulation modules to a path.
141 @param forceSetPXDDataReduction: override settings
from the DB
with the value set
in 'usePXDDataReduction'
142 @param usePXDDataReduction:
if 'forceSetPXDDataReduction==True', override settings
from the DB
143 @param cleanupPXDDataReduction:
if True the datastore objects used by PXDDataReduction are emptied
144 @param simulateT0jitter:
if True simulate L1 trigger jitter
145 @param isCosmics:
if True the filling pattern
is removed
from L1 jitter simulation
146 @param FilterEvents:
if True only the events that
pass the L1 trigger will survive simulation, the other are discarded.
147 Make sure you do need to filter events before you set the value to
True.
148 @param skipExperimentCheckForBG: If
True, skip the check on the experiment number consistency between the basf2
149 process
and the beam background files. Note that this check should be skipped only by experts.
150 @param save_slow_pions_in_mc:
if True, additional Regions of Interest on the PXD are created to save the PXDDigits
151 of slow pions
from D* -> D pi^{\\pm} decays using the MCSlowPionPXDROICreator based on MC truth information
152 @param save_all_charged_particles_in_mc:
if True, additional Regions of Interest on the PXD are created to save the PXDDigits
153 of all charged primary MCParticles that traverse PXD
156 path.add_module('StatisticsSummary').set_name(
'Sum_PreSimulation')
159 check_components(components)
162 if bkgfiles
is not None:
164 bkginput = b2.register_module(
'BGOverlayInput')
165 bkginput.param(
'inputFileNames', bkgfiles)
166 bkginput.param(
'skipExperimentCheck', skipExperimentCheckForBG)
167 path.add_module(bkginput)
169 bkgmixer = b2.register_module(
'BeamBkgMixer')
170 bkgmixer.param(
'backgroundFiles', bkgfiles)
172 bkgmixer.param(
'components', components)
173 path.add_module(bkgmixer)
175 if components
is None or 'PXD' in components:
177 bkgmixer.param(
'minTimePXD', -20000.0)
178 bkgmixer.param(
'maxTimePXD', 20000.0)
180 pxd_veto_emulator = b2.register_module(
'PXDInjectionVetoEmulator')
181 path.add_module(pxd_veto_emulator)
184 if 'Gearbox' not in path:
185 gearbox = b2.register_module(
'Gearbox')
186 path.add_module(gearbox)
189 if 'Geometry' not in path:
190 path.add_module(
'Geometry', useDB=
True)
191 if components
is not None:
192 b2.B2WARNING(
"Custom detector components specified: Will still build full geometry")
195 if simulateT0jitter
and 'EventT0Generator' not in path:
196 eventt0 = b2.register_module(
'EventT0Generator')
197 eventt0.param(
"isCosmics", isCosmics)
198 path.add_module(eventt0)
201 if 'SimulateEventLevelTriggerTimeInfo' not in path:
202 eventleveltriggertimeinfo = b2.register_module(
'SimulateEventLevelTriggerTimeInfo')
203 path.add_module(eventleveltriggertimeinfo)
206 if 'FullSim' not in path:
207 g4sim = b2.register_module(
'FullSim')
208 path.add_module(g4sim)
210 check_simulation(path)
217 if components
is None or 'CDC' in components:
218 cdc_digitizer = b2.register_module(
'CDCDigitizer')
219 cdc_digitizer.param(
"Output2ndHit", generate_2nd_cdc_hits)
220 path.add_module(cdc_digitizer)
223 if components
is None or 'TOP' in components:
224 top_digitizer = b2.register_module(
'TOPDigitizer')
225 path.add_module(top_digitizer)
228 if components
is None or 'ARICH' in components:
229 arich_digitizer = b2.register_module(
'ARICHDigitizer')
230 path.add_module(arich_digitizer)
233 if components
is None or 'ECL' in components:
234 ecl_digitizer = b2.register_module(
'ECLDigitizer')
235 if bkgfiles
is not None:
236 ecl_digitizer.param(
'Background', 1)
237 path.add_module(ecl_digitizer)
240 if components
is None or 'KLM' in components:
241 klm_digitizer = b2.register_module(
'KLMDigitizer')
242 path.add_module(klm_digitizer)
245 if bkgfiles
is not None and bkgOverlay:
246 m = path.add_module(
'BGOverlayExecutor', components=[
'CDC',
'TOP',
'ARICH',
'KLM'])
247 m.set_name(
'BGOverlayExecutor_CDC...KLM')
249 if components
is None or 'TRG' in components:
250 add_trigger_simulation(path, simulateT0jitter=simulateT0jitter, FilterEvents=FilterEvents)
253 if components
is None or 'SVD' in components:
254 add_svd_simulation(path)
255 if bkgfiles
is not None and bkgOverlay:
256 m = path.add_module(
'BGOverlayExecutor', components=[
'SVD'])
257 m.set_name(
'BGOverlayExecutor_SVD')
258 path.add_module(
'SVDShaperDigitSorter')
259 path.add_module(
'SVDZeroSuppressionEmulator')
262 if components
is None or 'PXD' in components:
263 if forceSetPXDDataReduction:
265 if usePXDDataReduction:
266 pxd_digits_name =
'pxd_unfiltered_digits'
267 add_pxd_simulation(path, digitsName=pxd_digits_name)
268 if bkgfiles
is not None and bkgOverlay:
269 m = path.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=pxd_digits_name)
270 m.set_name(
'BGOverlayExecutor_PXD')
271 path.add_module(
'PXDDigitSorter', digits=pxd_digits_name)
272 if usePXDDataReduction:
273 add_PXDDataReduction(
277 doCleanup=cleanupPXDDataReduction,
278 overrideDB=forceSetPXDDataReduction,
279 usePXDDataReduction=usePXDDataReduction,
280 save_slow_pions_in_mc=save_slow_pions_in_mc,
281 save_all_charged_particles_in_mc=save_all_charged_particles_in_mc)
284 path_disableROI_Sim = b2.create_path()
285 add_pxd_simulation(path_disableROI_Sim, digitsName=
'PXDDigits')
286 if bkgfiles
is not None and bkgOverlay:
287 m = path_disableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'PXDDigits')
288 m.set_name(
'BGOverlayExecutor_PXD')
289 path_disableROI_Sim.add_module(
'PXDDigitSorter', digits=
'PXDDigits')
291 path_enableROI_Sim = b2.create_path()
292 add_pxd_simulation(path_enableROI_Sim, digitsName=
'pxd_unfiltered_digits')
293 if bkgfiles
is not None and bkgOverlay:
294 m = path_enableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'pxd_unfiltered_digits')
295 m.set_name(
'BGOverlayExecutor_PXD')
296 path_enableROI_Sim.add_module(
'PXDDigitSorter', digits=
'pxd_unfiltered_digits')
297 add_PXDDataReduction(
300 pxd_unfiltered_digits=
'pxd_unfiltered_digits',
301 doCleanup=cleanupPXDDataReduction,
302 save_slow_pions_in_mc=save_slow_pions_in_mc,
303 save_all_charged_particles_in_mc=save_all_charged_particles_in_mc)
305 roi_condition_module_Sim = path.add_module(
'ROIfindingConditionFromDB')
306 roi_condition_module_Sim.if_true(path_enableROI_Sim, b2.AfterConditionPath.CONTINUE)
307 roi_condition_module_Sim.if_false(path_disableROI_Sim, b2.AfterConditionPath.CONTINUE)
310 path.add_module(
'StatisticsSummary').set_name(
'Sum_Simulation')