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
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):
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
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)
71 pxd_digifilter = b2.register_module(
'PXDdigiFilter')
72 pxd_digifilter.param(
'ROIidsName',
'ROIs')
73 pxd_digifilter.param(
'PXDDigitsName', pxd_unfiltered_digits)
74 pxd_digifilter.param(
'PXDDigitsInsideROIName',
'PXDDigits')
75 pxd_digifilter.param(
'overrideDB', overrideDB)
76 pxd_digifilter.param(
'usePXDDataReduction', usePXDDataReduction)
77 path.add_module(pxd_digifilter)
81 datastore_cleaner = b2.register_module(
'PruneDataStore')
82 datastore_cleaner.param(
'keepMatchedEntries',
False)
83 datastore_cleaner.param(
'matchEntries', [
'ROIs',
'__ROIsvdRecoDigits',
'__ROIsvdClusters',
'__ROIsvdRecoTracks',
84 'SPTrackCands__ROI',
'SpacePoints__ROI', pxd_unfiltered_digits,
86 'SegmentNetwork__ROI',
'PXDInterceptsToROIs',
87 'RecoHitInformationsTo__ROIsvdClusters',
88 'SpacePoints__ROITo__ROIsvdClusters',
'__ROIsvdClustersToMCParticles',
89 '__ROIsvdRecoDigitsToMCParticles',
90 '__ROIsvdClustersTo__ROIsvdRecoDigits',
'__ROIsvdClustersToSVDTrueHits',
91 '__ROIsvdClustersTo__ROIsvdRecoTracks',
'__ROIsvdRecoTracksToPXDIntercepts',
92 '__ROIsvdRecoTracksToRecoHitInformations',
93 '__ROIsvdRecoTracksToSPTrackCands__ROI'])
94 path.add_module(datastore_cleaner)
97 def add_roiFinder(path, reco_tracks):
99 Add the ROI finding to the path creating ROIs out of reco tracks by extrapolating them to the PXD volume.
100 :param path: Where to add the module to.
101 :param reco_tracks: Which tracks to use in the extrapolation step.
104 pxdDataRed = b2.register_module(
'PXDROIFinder')
106 'recoTrackListName': reco_tracks,
107 'PXDInterceptListName':
'PXDIntercepts',
108 'ROIListName':
'ROIs',
109 'tolerancePhi': 0.15,
118 pxdDataRed.param(param_pxdDataRed)
119 path.add_module(pxdDataRed)
127 forceSetPXDDataReduction=False,
128 usePXDDataReduction=True,
129 cleanupPXDDataReduction=True,
130 generate_2nd_cdc_hits=False,
131 simulateT0jitter=True,
134 usePXDGatedMode=False,
135 skipExperimentCheckForBG=False):
137 This function adds the standard simulation modules to a path.
138 @param forceSetPXDDataReduction: override settings from the DB with the value set in 'usePXDDataReduction'
139 @param usePXDDataReduction: if 'forceSetPXDDataReduction==True', override settings from the DB
140 @param cleanupPXDDataReduction: if True the datastore objects used by PXDDataReduction are emptied
141 @param simulateT0jitter: if True simulate L1 trigger jitter
142 @param isCosmics: if True the filling pattern is removed from L1 jitter simulation
143 @param FilterEvents: if True only the events that pass the L1 trigger will survive simulation, the other are discarded.
144 Make sure you do need to filter events before you set the value to True.
145 @param skipExperimentCheckForBG: If True, skip the check on the experiment number consistency between the basf2
146 process and the beam background files. Note that this check should be skipped only by experts.
150 check_components(components)
153 if bkgfiles
is not None:
155 bkginput = b2.register_module(
'BGOverlayInput')
156 bkginput.param(
'inputFileNames', bkgfiles)
157 bkginput.param(
'skipExperimentCheck', skipExperimentCheckForBG)
158 path.add_module(bkginput)
160 bkgmixer = b2.register_module(
'BeamBkgMixer')
161 bkgmixer.param(
'backgroundFiles', bkgfiles)
163 bkgmixer.param(
'components', components)
164 path.add_module(bkgmixer)
166 if components
is None or 'PXD' in components:
168 bkgmixer.param(
'minTimePXD', -20000.0)
169 bkgmixer.param(
'maxTimePXD', 20000.0)
171 pxd_veto_emulator = b2.register_module(
'PXDInjectionVetoEmulator')
172 path.add_module(pxd_veto_emulator)
175 if 'Gearbox' not in path:
176 gearbox = b2.register_module(
'Gearbox')
177 path.add_module(gearbox)
180 if 'Geometry' not in path:
181 path.add_module(
'Geometry', useDB=
True)
182 if components
is not None:
183 b2.B2WARNING(
"Custom detector components specified: Will still build full geometry")
186 if simulateT0jitter
and 'EventT0Generator' not in path:
187 eventt0 = b2.register_module(
'EventT0Generator')
188 eventt0.param(
"isCosmics", isCosmics)
189 path.add_module(eventt0)
192 if 'SimulateEventLevelTriggerTimeInfo' not in path:
193 eventleveltriggertimeinfo = b2.register_module(
'SimulateEventLevelTriggerTimeInfo')
194 path.add_module(eventleveltriggertimeinfo)
197 if 'FullSim' not in path:
198 g4sim = b2.register_module(
'FullSim')
199 path.add_module(g4sim)
201 check_simulation(path)
208 if components
is None or 'CDC' in components:
209 cdc_digitizer = b2.register_module(
'CDCDigitizer')
210 cdc_digitizer.param(
"Output2ndHit", generate_2nd_cdc_hits)
211 path.add_module(cdc_digitizer)
214 if components
is None or 'TOP' in components:
215 top_digitizer = b2.register_module(
'TOPDigitizer')
216 path.add_module(top_digitizer)
219 if components
is None or 'ARICH' in components:
220 arich_digitizer = b2.register_module(
'ARICHDigitizer')
221 path.add_module(arich_digitizer)
224 if components
is None or 'ECL' in components:
225 ecl_digitizer = b2.register_module(
'ECLDigitizer')
226 if bkgfiles
is not None:
227 ecl_digitizer.param(
'Background', 1)
228 path.add_module(ecl_digitizer)
231 if components
is None or 'KLM' in components:
232 klm_digitizer = b2.register_module(
'KLMDigitizer')
233 path.add_module(klm_digitizer)
236 if bkgfiles
is not None and bkgOverlay:
237 m = path.add_module(
'BGOverlayExecutor', components=[
'CDC',
'TOP',
'ARICH',
'KLM'])
238 m.set_name(
'BGOverlayExecutor_CDC...KLM')
240 if components
is None or 'TRG' in components:
241 add_trigger_simulation(path, simulateT0jitter=simulateT0jitter, FilterEvents=FilterEvents)
244 if components
is None or 'SVD' in components:
245 add_svd_simulation(path)
246 if bkgfiles
is not None and bkgOverlay:
247 m = path.add_module(
'BGOverlayExecutor', components=[
'SVD'])
248 m.set_name(
'BGOverlayExecutor_SVD')
249 path.add_module(
'SVDShaperDigitSorter')
250 path.add_module(
'SVDZeroSuppressionEmulator')
253 if components
is None or 'PXD' in components:
254 if forceSetPXDDataReduction:
256 if usePXDDataReduction:
257 pxd_digits_name =
'pxd_unfiltered_digits'
258 add_pxd_simulation(path, digitsName=pxd_digits_name)
259 if bkgfiles
is not None and bkgOverlay:
260 m = path.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=pxd_digits_name)
261 m.set_name(
'BGOverlayExecutor_PXD')
262 path.add_module(
'PXDDigitSorter', digits=pxd_digits_name)
263 if usePXDDataReduction:
264 add_PXDDataReduction(path, components, pxd_digits_name, doCleanup=cleanupPXDDataReduction,
265 overrideDB=forceSetPXDDataReduction, usePXDDataReduction=usePXDDataReduction)
268 path_disableROI_Sim = b2.create_path()
269 add_pxd_simulation(path_disableROI_Sim, digitsName=
'PXDDigits')
270 if bkgfiles
is not None and bkgOverlay:
271 m = path_disableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'PXDDigits')
272 m.set_name(
'BGOverlayExecutor_PXD')
273 path_disableROI_Sim.add_module(
'PXDDigitSorter', digits=
'PXDDigits')
275 path_enableROI_Sim = b2.create_path()
276 add_pxd_simulation(path_enableROI_Sim, digitsName=
'pxd_unfiltered_digits')
277 if bkgfiles
is not None and bkgOverlay:
278 m = path_enableROI_Sim.add_module(
'BGOverlayExecutor', components=[
'PXD'], PXDDigitsName=
'pxd_unfiltered_digits')
279 m.set_name(
'BGOverlayExecutor_PXD')
280 path_enableROI_Sim.add_module(
'PXDDigitSorter', digits=
'pxd_unfiltered_digits')
281 add_PXDDataReduction(
284 pxd_unfiltered_digits=
'pxd_unfiltered_digits',
285 doCleanup=cleanupPXDDataReduction)
287 roi_condition_module_Sim = path.add_module(
'ROIfindingConditionFromDB')
288 roi_condition_module_Sim.if_true(path_enableROI_Sim, b2.AfterConditionPath.CONTINUE)
289 roi_condition_module_Sim.if_false(path_disableROI_Sim, b2.AfterConditionPath.CONTINUE)
292 path.add_module(
'StatisticsSummary').set_name(
'Sum_Simulation')