13 from geometry
import check_components
14 from L1trigger
import add_trigger_simulation
15 from pxd
import add_pxd_simulation
16 from svd
import add_svd_simulation
17 from svd
import add_svd_reconstruction
18 from tracking
import add_tracking_for_PXDDataReduction_simulation, add_roiFinder
21 def check_simulation(path):
22 """Check if the minimum number of modules required for simulation are in
23 the path and in the correct order"""
24 required = [
'Gearbox',
'Geometry',
'FullSim']
28 for module
in path.modules():
29 module_type = module.type()
31 if module_type
in required:
33 if module_type
in found:
34 b2.B2ERROR(
"Duplicate module in path: %s" % module_type)
36 found.append(module.type())
38 if len(required) != len(found):
42 b2.B2ERROR(
"No '%s' module found but needed for simulation" % r)
44 elif required != found:
45 b2.B2ERROR(
"Simulation modules in wrong order. Should be '%s' but is '%s'"
46 % (
", ".join(required),
", ".join(found)))
49 def add_PXDDataReduction(path, components, pxd_unfiltered_digits='pxd_unfiltered_digits',
50 doCleanup=True, overrideDB=False, usePXDDataReduction=True, save_slow_pions_in_mc=False):
52 This function adds the standard simulation modules to a path.
53 @param pxd_unfiltered_digits: the name of the StoreArray containing the input PXDDigits
54 @param overrideDB: override settings from the DB with the value set in 'usePXDDataReduction'
55 @param usePXDDataReduction: if 'overrideDB==True', override settings from the DB
56 @param doCleanup: if 'doCleanup=True' temporary datastore objects are emptied
57 @param save_slow_pions_in_mc: if True, additional Regions of Interest on the PXD are created to save the PXDDigits
58 of slow pions from D* -> D pi^{\\pm} decays using the MCSlowPionPXDROICreator based on MC truth information
63 add_svd_reconstruction(path, isROIsimulation=
True)
66 svd_reco_tracks =
'__ROIsvdRecoTracks'
68 add_tracking_for_PXDDataReduction_simulation(path, components, svd_cluster=
'__ROIsvdClusters')
70 add_roiFinder(path, svd_reco_tracks)
72 if save_slow_pions_in_mc:
73 path.add_module(
'MCSlowPionPXDROICreator', PXDDigitsName=pxd_unfiltered_digits, ROIsName=
'ROIs')
76 pxd_digifilter = b2.register_module(
'PXDdigiFilter')
77 pxd_digifilter.param(
'ROIidsName',
'ROIs')
78 pxd_digifilter.param(
'PXDDigitsName', pxd_unfiltered_digits)
79 pxd_digifilter.param(
'PXDDigitsInsideROIName',
'PXDDigits')
80 pxd_digifilter.param(
'overrideDB', overrideDB)
81 pxd_digifilter.param(
'usePXDDataReduction', usePXDDataReduction)
82 path.add_module(pxd_digifilter)
86 datastore_cleaner = b2.register_module(
'PruneDataStore')
87 datastore_cleaner.param(
'keepMatchedEntries',
False)
88 datastore_cleaner.param(
'matchEntries', [
'ROIs',
'__ROIsvdRecoDigits',
'__ROIsvdClusters',
'__ROIsvdRecoTracks',
89 'SPTrackCands__ROI',
'SpacePoints__ROI', pxd_unfiltered_digits,
91 'SegmentNetwork__ROI',
'PXDInterceptsToROIs',
92 'RecoHitInformationsTo__ROIsvdClusters',
93 'SpacePoints__ROITo__ROIsvdClusters',
'__ROIsvdClustersToMCParticles',
94 '__ROIsvdRecoDigitsToMCParticles',
95 '__ROIsvdClustersTo__ROIsvdRecoDigits',
'__ROIsvdClustersToSVDTrueHits',
96 '__ROIsvdClustersTo__ROIsvdRecoTracks',
'__ROIsvdRecoTracksToPXDIntercepts',
97 '__ROIsvdRecoTracksToRecoHitInformations',
98 '__ROIsvdRecoTracksToSPTrackCands__ROI',
101 f
'{pxd_unfiltered_digits}ToMCParticles',
102 f
'{pxd_unfiltered_digits}ToPXDDigits',
103 f
'{pxd_unfiltered_digits}ToPXDTrueHits'])
104 path.add_module(datastore_cleaner)
112 forceSetPXDDataReduction=False,
113 usePXDDataReduction=True,
114 cleanupPXDDataReduction=True,
115 generate_2nd_cdc_hits=False,
116 simulateT0jitter=True,
119 usePXDGatedMode=False,
120 skipExperimentCheckForBG=False,
121 save_slow_pions_in_mc=False):
123 This function adds the standard simulation modules to a path.
124 @param forceSetPXDDataReduction: override settings from the DB with the value set in 'usePXDDataReduction'
125 @param usePXDDataReduction: if 'forceSetPXDDataReduction==True', override settings from the DB
126 @param cleanupPXDDataReduction: if True the datastore objects used by PXDDataReduction are emptied
127 @param simulateT0jitter: if True simulate L1 trigger jitter
128 @param isCosmics: if True the filling pattern is removed from L1 jitter simulation
129 @param FilterEvents: if True only the events that pass the L1 trigger will survive simulation, the other are discarded.
130 Make sure you do need to filter events before you set the value to True.
131 @param skipExperimentCheckForBG: If True, skip the check on the experiment number consistency between the basf2
132 process and the beam background files. Note that this check should be skipped only by experts.
133 @param save_slow_pions_in_mc: if True, additional Regions of Interest on the PXD are created to save the PXDDigits
134 of slow pions from D* -> D pi^{\\pm} decays using the MCSlowPionPXDROICreator based on MC truth information
138 check_components(components)
141 if bkgfiles
is not None:
143 bkginput = b2.register_module(
'BGOverlayInput')
144 bkginput.param(
'inputFileNames', bkgfiles)
145 bkginput.param(
'skipExperimentCheck', skipExperimentCheckForBG)
146 path.add_module(bkginput)
148 bkgmixer = b2.register_module(
'BeamBkgMixer')
149 bkgmixer.param(
'backgroundFiles', bkgfiles)
151 bkgmixer.param(
'components', components)
152 path.add_module(bkgmixer)
154 if components
is None or 'PXD' in components:
156 bkgmixer.param(
'minTimePXD', -20000.0)
157 bkgmixer.param(
'maxTimePXD', 20000.0)
159 pxd_veto_emulator = b2.register_module(
'PXDInjectionVetoEmulator')
160 path.add_module(pxd_veto_emulator)
163 if 'Gearbox' not in path:
164 gearbox = b2.register_module(
'Gearbox')
165 path.add_module(gearbox)
168 if 'Geometry' not in path:
169 path.add_module(
'Geometry', useDB=
True)
170 if components
is not None:
171 b2.B2WARNING(
"Custom detector components specified: Will still build full geometry")
174 if simulateT0jitter
and 'EventT0Generator' not in path:
175 eventt0 = b2.register_module(
'EventT0Generator')
176 eventt0.param(
"isCosmics", isCosmics)
177 path.add_module(eventt0)
180 if 'SimulateEventLevelTriggerTimeInfo' not in path:
181 eventleveltriggertimeinfo = b2.register_module(
'SimulateEventLevelTriggerTimeInfo')
182 path.add_module(eventleveltriggertimeinfo)
185 if 'FullSim' not in path:
186 g4sim = b2.register_module(
'FullSim')
187 path.add_module(g4sim)
189 check_simulation(path)
196 if components
is None or 'CDC' in components:
197 cdc_digitizer = b2.register_module(
'CDCDigitizer')
198 cdc_digitizer.param(
"Output2ndHit", generate_2nd_cdc_hits)
199 path.add_module(cdc_digitizer)
202 if components
is None or 'TOP' in components:
203 top_digitizer = b2.register_module(
'TOPDigitizer')
204 path.add_module(top_digitizer)
207 if components
is None or 'ARICH' in components:
208 arich_digitizer = b2.register_module(
'ARICHDigitizer')
209 path.add_module(arich_digitizer)
212 if components
is None or 'ECL' in components:
213 ecl_digitizer = b2.register_module(
'ECLDigitizer')
214 if bkgfiles
is not None:
215 ecl_digitizer.param(
'Background', 1)
216 path.add_module(ecl_digitizer)
219 if components
is None or 'KLM' in components:
220 klm_digitizer = b2.register_module(
'KLMDigitizer')
221 path.add_module(klm_digitizer)
224 if bkgfiles
is not None and bkgOverlay:
225 m = path.add_module(
'BGOverlayExecutor', components=[
'CDC',
'TOP',
'ARICH',
'KLM'])
226 m.set_name(
'BGOverlayExecutor_CDC...KLM')
228 if components
is None or 'TRG' in components:
229 add_trigger_simulation(path, simulateT0jitter=simulateT0jitter, FilterEvents=FilterEvents)
232 if components
is None or 'SVD' in components:
233 add_svd_simulation(path)
234 if bkgfiles
is not None and bkgOverlay:
235 m = path.add_module(
'BGOverlayExecutor', components=[
'SVD'])
236 m.set_name(
'BGOverlayExecutor_SVD')
237 path.add_module(
'SVDShaperDigitSorter')
238 path.add_module(
'SVDZeroSuppressionEmulator')
241 if components
is None or 'PXD' in components:
242 if forceSetPXDDataReduction:
244 if usePXDDataReduction:
245 pxd_digits_name =
'pxd_unfiltered_digits'
246 add_pxd_simulation(path, digitsName=pxd_digits_name)
247 if bkgfiles
is not None and bkgOverlay:
248 m = path.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=pxd_digits_name)
249 m.set_name(
'BGOverlayExecutor_PXD')
250 path.add_module(
'PXDDigitSorter', digits=pxd_digits_name)
251 if usePXDDataReduction:
252 add_PXDDataReduction(
256 doCleanup=cleanupPXDDataReduction,
257 overrideDB=forceSetPXDDataReduction,
258 usePXDDataReduction=usePXDDataReduction,
259 save_slow_pions_in_mc=save_slow_pions_in_mc)
262 path_disableROI_Sim = b2.create_path()
263 add_pxd_simulation(path_disableROI_Sim, digitsName=
'PXDDigits')
264 if bkgfiles
is not None and bkgOverlay:
265 m = path_disableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'PXDDigits')
266 m.set_name(
'BGOverlayExecutor_PXD')
267 path_disableROI_Sim.add_module(
'PXDDigitSorter', digits=
'PXDDigits')
269 path_enableROI_Sim = b2.create_path()
270 add_pxd_simulation(path_enableROI_Sim, digitsName=
'pxd_unfiltered_digits')
271 if bkgfiles
is not None and bkgOverlay:
272 m = path_enableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'pxd_unfiltered_digits')
273 m.set_name(
'BGOverlayExecutor_PXD')
274 path_enableROI_Sim.add_module(
'PXDDigitSorter', digits=
'pxd_unfiltered_digits')
275 add_PXDDataReduction(
278 pxd_unfiltered_digits=
'pxd_unfiltered_digits',
279 doCleanup=cleanupPXDDataReduction,
280 save_slow_pions_in_mc=save_slow_pions_in_mc)
282 roi_condition_module_Sim = path.add_module(
'ROIfindingConditionFromDB')
283 roi_condition_module_Sim.if_true(path_enableROI_Sim, b2.AfterConditionPath.CONTINUE)
284 roi_condition_module_Sim.if_false(path_disableROI_Sim, b2.AfterConditionPath.CONTINUE)
287 path.add_module(
'StatisticsSummary').set_name(
'Sum_Simulation')