Belle II Software development
commondqm.py
1#!/usr/bin/env python3
2
3
10
11import basf2 as b2
12from svd import add_svd_create_recodigits
13from svd.dqm_utils import add_svd_dqm_dose
14from geometry import check_components
15from analysisDQM import add_analysis_dqm, add_mirabelle_dqm, get_hadB_path
16import neurotrigger
17
18
19def add_common_dqm(path, components=None, dqm_environment="expressreco", dqm_mode="dont_care", create_hlt_unit_histograms=False):
20 """
21 This function adds DQMs which are common for Cosmic runs and Collion runs
22
23 @param components: A list of the detector components which are available in this
24 run of basf2
25 @param dqm_environment: The environment the DQM modules are running in
26 "expressreco" (default) if running on the ExpressReco system
27 "hlt" if running on the HLT online reconstructon nodes
28 If running on the hlt, you may want to output less or other DQM plots
29 due to the limited bandwidth of the HLT nodes.
30 @param dqm_mode: How to split up the path for online/HLT.
31 For dqm_mode == "dont_care" all the DQM modules should be added.
32 For dqm_mode == "all_events" only the DQM modules which should run on all events
33 (filtered and dismissed) should be added
34 For dqm_mode == "before_reco" only the DQM modules which should run before
35 all reconstruction
36 For dqm_mode == "filtered" only the DQM modules which should run on filtered
37 events should be added
38 @param create_hlt_unit_histograms: Parameter for SoftwareTiggerHLTDQMModule.
39 Should be True only when running on the HLT servers
40 """
41 assert dqm_mode in ["dont_care", "all_events", "filtered", "before_filter"]
42 # Check components.
43 check_components(components)
44
45 if dqm_environment == "expressreco" and (dqm_mode in ["dont_care"]):
46 # PXD (not useful on HLT)
47 if components is None or 'PXD' in components:
48 path.add_module('PXDDAQDQM', histogramDirectoryName='PXDDAQ')
49 path.add_module('PXDROIDQM', histogramDirectoryName='PXDROI')
50 path.add_module('PXDDQMExpressReco', histogramDirectoryName='PXDER')
51 path.add_module('SetupGenfitExtrapolation')
52 path.add_module('PXDROIFinder',
53 recoTrackListName='RecoTracks',
54 PXDInterceptListName='PXDIntercepts')
55 # moved to cosmics/collision as we need different cuts
56 # path.add_module('PXDDQMEfficiency', histogramDirectoryName='PXDEFF')
57 path.add_module('PXDTrackClusterDQM', histogramDirectoryName='PXDER')
58 path.add_module('PXDInjectionDQM', histogramDirectoryName='PXDINJ', eachModule=True)
59 # SVD
60 if components is None or 'SVD' in components:
61 # reconstruct SVDRecoDigits first of all
62 add_svd_create_recodigits(path)
63
64 # SVD DATA FORMAT
65 svdunpackerdqm = b2.register_module('SVDUnpackerDQM')
66 path.add_module(svdunpackerdqm)
67 # offline ZS emulator
68 path.add_module(
69 'SVDZeroSuppressionEmulator',
70 SNthreshold=5,
71 ShaperDigits='SVDShaperDigits',
72 ShaperDigitsIN='SVDShaperDigitsZS5',
73 FADCmode=True)
74 # SVD Occupancy after Injection
75 path.add_module('SVDDQMInjection', ShaperDigits='SVDShaperDigitsZS5')
76 # SVDDQMExpressReco General
77 path.add_module('SVDDQMExpressReco',
78 offlineZSShaperDigits='SVDShaperDigitsZS5')
79 # SVD HIT TIME
80 path.add_module('SVDDQMHitTime')
81 # SVD EFFICIENCY
82 path.add_module('SetupGenfitExtrapolation')
83 path.add_module('SVDROIFinder',
84 recoTrackListName='RecoTracks',
85 SVDInterceptListName='SVDIntercepts')
86 path.add_module('SVDDQMEfficiency')
87 # SVD CLUSTERS ON TRACK
88 path.add_module('SVDDQMClustersOnTrack')
89 # SVD DOSE
90 add_svd_dqm_dose(path, 'SVDShaperDigitsZS5')
91
92 # Event time measuring detectors
93 if components is None or 'CDC' in components or 'ECL' in components or 'TOP' in components:
94 eventT0DQMmodule = b2.register_module('EventT0DQM')
95 path.add_module(eventT0DQMmodule)
96
97 if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "before_filter"]):
98 path.add_module(
99 "SoftwareTriggerHLTDQM",
100 createHLTUnitHistograms=create_hlt_unit_histograms,
101 createTotalResultHistograms=False,
102 createExpRunEventHistograms=False,
103 createErrorFlagHistograms=True,
104 cutResultIdentifiers={},
105 histogramDirectoryName="softwaretrigger_before_filter",
106 pathLocation="before filter",
107 ).set_name("SoftwareTriggerHLTDQM_before_filter")
108
109 path.add_module(
110 "TrackingAbortDQM",
111 histogramDirectoryName="TrackingAbort_before_filter",
112 ).set_name("TrackingAbortDQM_before_filter")
113
114 path.add_module("DetectorOccupanciesDQM", histogramDirectoryName="DetectorOccupancies_before_filter").set_name(
115 "DetectorOccupanciesDQM_before_filter")
116
117 path.add_module("StatisticsTimingHLTDQM",
118 createHLTUnitHistograms=create_hlt_unit_histograms,
119 )
120 # TTD trigger and bunch injection monitoring
121 path.add_module('TTDDQM')
122
123 if dqm_mode in ["dont_care", "filtered"]:
124 # HLT
125 hlt_trigger_lines_in_plot = []
126 hlt_skim_lines_in_plot = []
127
128 hlt_trigger_lines_per_unit_in_plot = [
129 "ge3_loose_tracks_inc_1_tight_not_ee2leg",
130 "Elab_gt_0.5_plus_2_others_with_Elab_gt_0.18_plus_no_clust_with_Ecms_gt_2.0",
131 "selectee",
132 "Estargt2_GeV_cluster",
133 ]
134 cutResultIdentifiers = {}
135
136 from softwaretrigger import filter_categories, skim_categories
137
138 filter_cat = [method for method in dir(filter_categories) if method.startswith('__') is False if method != 'RESULTS']
139 skim_cat = [method for method in dir(skim_categories) if method.startswith('__') is False]
140
141 def read_lines(category):
142 return [i.split(" ", 1)[1].replace(" ", "_") for i in category]
143
144 for i in filter_cat:
145 cutResultIdentifiers[i] = {"filter": read_lines(getattr(filter_categories, i))}
146 hlt_trigger_lines_in_plot += read_lines(getattr(filter_categories, i))
147
148 for i in skim_cat:
149 cutResultIdentifiers[i] = {"skim": read_lines(getattr(skim_categories, i))}
150 hlt_skim_lines_in_plot += read_lines(getattr(skim_categories, i))
151
152 cutResultIdentifiers["skim"] = {"skim": hlt_skim_lines_in_plot}
153 cutResultIdentifiers["filter"] = {"filter": hlt_trigger_lines_in_plot}
154
155 additionalL1Identifiers = [
156 'ffy',
157 'fyo',
158 'c4',
159 'hie',
160 'mu_b2b',
161 'mu_eb2b',
162 'beklm',
163 'eklm2',
164 'cdcklm1',
165 'seklm1',
166 'ieklm1',
167 'ecleklm1',
168 'fso',
169 'fioiecl1',
170 'ff30',
171 'stt',
172 'ioiecl1',
173 'ioiecl2',
174 'lml1',
175 'lml2',
176 'lml3',
177 'lml4',
178 'lml5',
179 'lml6',
180 'lml7',
181 'lml8',
182 'lml9',
183 'lml10',
184 'lml12',
185 'lml13',
186 'bhapur']
187
188 # Default plot
189 path.add_module(
190 "SoftwareTriggerHLTDQM",
191 cutResultIdentifiers=cutResultIdentifiers,
192 l1Identifiers=["fff", "ffo", "lml0", "ffb", "fp", "passive_veto"],
193 additionalL1Identifiers=additionalL1Identifiers,
194 createHLTUnitHistograms=create_hlt_unit_histograms,
195 cutResultIdentifiersPerUnit=hlt_trigger_lines_per_unit_in_plot,
196 pathLocation="after filter",
197 )
198
199 path.add_module("StatisticsTimingHLTDQM",
200 histogramDirectoryName="timing_statistics_after_filter"
201 ).set_name("StatisticsTimingHLTDQM_after_filter")
202
203 path.add_module("TrackingAbortDQM")
204
205 path.add_module("DetectorOccupanciesDQM")
206
207 # Skim plots where bhabha contamination is removed
208 path.add_module(
209 "SoftwareTriggerHLTDQM",
210 cutResultIdentifiers={
211 "skim": {"skim": hlt_skim_lines_in_plot},
212 },
213 cutResultIdentifiersIgnored={
214 "skim": [
215 "accept_bhabha_all",
216 ]
217 },
218 createTotalResultHistograms=False,
219 createExpRunEventHistograms=False,
220 histogramDirectoryName="softwaretrigger_skim_nobhabha",
221 ).set_name("SoftwareTriggerHLTDQM_skim_nobhabha")
222
223 if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "filtered"]):
224 # SVD DATA FORMAT
225 if components is None or 'SVD' in components:
226 svdunpackerdqm = b2.register_module('SVDUnpackerDQM')
227 path.add_module(svdunpackerdqm)
228
229 # CDC
230 if (components is None or 'CDC' in components) and (dqm_mode in ["dont_care", "filtered"]):
231 cdcdqm = b2.register_module('cdcDQM7')
232 path.add_module(cdcdqm)
233
234 module_names = [m.name() for m in path.modules()]
235 if ('SoftwareTrigger' in module_names):
236 cdcdedxdqm = b2.register_module('CDCDedxDQM')
237 path.add_module(cdcdedxdqm)
238
239 if dqm_environment == "expressreco":
240 path.add_module('CDCDQM')
241
242 # ECL
243 if (components is None or 'ECL' in components) and (dqm_mode in ["dont_care", "filtered"]):
244 ecldqm = b2.register_module('ECLDQM')
245 path.add_module(ecldqm)
246 ecldqmext = b2.register_module('ECLDQMEXTENDED')
247 path.add_module(ecldqmext)
248 path.add_module('ECLDQMOutOfTimeDigits')
249 path.add_module('ECLDQMConnectedRegions')
250 # we dont want to create large histograms on HLT, thus ERECO only
251 if dqm_environment == "expressreco":
252 path.add_module('ECLDQMInjection', histogramDirectoryName='ECLINJ')
253
254 # TOP
255 if (components is None or 'TOP' in components) and (dqm_mode in ["dont_care", "filtered"]):
256 topdqm = b2.register_module('TOPDQM')
257 path.add_module(topdqm)
258
259 # KLM
260 if (components is None or 'KLM' in components) and (dqm_mode in ["dont_care", "filtered"]):
261 klmdqm = b2.register_module("KLMDQM")
262 path.add_module(klmdqm)
263
264 # TRG before all reconstruction runs (so on all events with all unpacked information)
265 if (components is None or 'TRG' in components) and (dqm_mode in ["dont_care", "before_filter"]):
266 # TRGECL
267 trgecldqm = b2.register_module('TRGECLDQM')
268 path.add_module(trgecldqm)
269 trgecltimingdqm = b2.register_module('TRGECLEventTimingDQM')
270 path.add_module(trgecltimingdqm)
271 # TRGGDL
272 trggdldqm = b2.register_module('TRGGDLDQM')
273 trggdldqm.param('skim', 0)
274 path.add_module(trggdldqm)
275 # TRGGRL
276 trggrldqm = b2.register_module('TRGGRLDQM')
277 path.add_module(trggrldqm)
278 # TRGCDCTSF
279 nmod_tsf = [0, 1, 2, 3, 4, 5, 6]
280 for mod_tsf in nmod_tsf:
281 path.add_module('TRGCDCTSFDQM', TSFMOD=mod_tsf)
282 # TRGCDC2D
283 trgcdct2ddqm = b2.register_module('TRGCDCT2DDQM')
284 path.add_module(trgcdct2ddqm)
285 # TRGCDC3D
286 nmod_t3d = [0, 1, 2, 3]
287 for mod_t3d in nmod_t3d:
288 path.add_module('TRGCDCT3DConverter',
289 hitCollectionName='FirmCDCTriggerSegmentHits' + str(mod_t3d),
290 addTSToDatastore=True,
291 EventTimeName='FirmBinnedEventT0' + str(mod_t3d),
292 addEventTimeToDatastore=True,
293 inputCollectionName='FirmTRGCDC2DFinderTracks' + str(mod_t3d),
294 add2DFinderToDatastore=True,
295 outputCollectionName='FirmTRGCDC3DFitterTracks' + str(mod_t3d),
296 add3DToDatastore=True,
297 fit3DWithTSIM=0,
298 firmwareResultCollectionName='TRGCDCT3DUnpackerStore' + str(mod_t3d),
299 isVerbose=0)
300 path.add_module('TRGCDCT3DDQM', T3DMOD=mod_t3d)
301 # CDCTriggerNeuro
302 if dqm_environment != "expressreco":
304 path.add_module('CDCTriggerNeuroDQMOnline', histogramDirectoryName="TRGCDCTNN2", useRecoTracks=False)
305 path.add_module('CDCTriggerNeuroDQM')
306
307 # TRG for expressreco:
308 if dqm_environment == "expressreco" and (components is None or 'TRG' in components) and (dqm_mode in ["dont_care"]):
309 # TRGCDCTNN
311 path.add_module('CDCTriggerRecoMatcher', TrgTrackCollectionName=neurotrigger.hwneurotracks,
312 hitCollectionName=neurotrigger.hwneuroinputsegmenthits, axialOnly=True)
313 path.add_module('CDCTriggerRecoMatcher', TrgTrackCollectionName=neurotrigger.hwsimneurotracks,
314 hitCollectionName=neurotrigger.hwneuroinputsegmenthits, axialOnly=True)
315 path.add_module('CDCTriggerRecoMatcher', TrgTrackCollectionName=neurotrigger.hwneuroinput2dfindertracks,
316 hitCollectionName=neurotrigger.hwneuroinputsegmenthits, axialOnly=True)
317 path.add_module('CDCTriggerNeuroDQMOnline', histogramDirectoryName="TRGCDCTNN2", useRecoTracks=True)
318
319 # TRG after skim
320 if (components is None or 'TRG' in components) and (dqm_mode in ["dont_care", "filtered"]):
321 # TRGGDL
322 trggdldqm_skim = b2.register_module('TRGGDLDQM')
323 trggdldqm_skim.param('skim', 1)
324 path.add_module(trggdldqm_skim)
325 trgeffdqm = b2.register_module("TRGEFFDQM")
326 path.add_module(trgeffdqm)
327
328 # TrackDQM, needs at least one VXD components to be present or will crash otherwise
329 if (components is None or 'SVD' in components or 'PXD' in components) and (dqm_mode in ["dont_care", "filtered"]):
330 if (dqm_environment == "hlt"):
331 path.add_module('TrackingHLTDQM')
332 else:
333 path.add_module('ParallelTrackFilter', min_d0=-0.5, max_d0=0.5, min_z0=-1, max_z0=1,
334 inputArrayName="", outputINArrayName="TracksFromIP", outputOUTArrayName="TracksNotFromIP")
335 path.add_module('TrackingExpressRecoDQM', histogramDirectoryName="TrackingERDQM_FromIP",
336 tracksStoreArrayName="TracksFromIP", histogramTitleSuffix=" - Tracks from IP") \
337 .set_name("TrackingExpressRecoDQM_FromIP")
338 path.add_module('TrackingExpressRecoDQM', histogramDirectoryName="TrackingERDQM_NotFromIP",
339 tracksStoreArrayName="TracksNotFromIP", histogramTitleSuffix=" - Tracks not from IP",
340 produce1Dresiduals=False, produce2Dresiduals=False, produceTRClusterPlots=False) \
341 .set_name("TrackingExpressRecoDQM_NotFromIP")
342
343 # ARICH
344 if (components is None or 'ARICH' in components) and (dqm_mode in ["dont_care", "filtered"]):
345 path.add_module('ARICHDQM')
346
347 if dqm_mode in ["dont_care", "filtered"]:
348 # PhysicsObjectsDQM
349 add_analysis_dqm(path)
350 if dqm_environment == "expressreco" and (dqm_mode in ["dont_care"]):
351 add_mirabelle_dqm(path)
352 get_hadB_path(path)
353
354 # KLM2 (requires mu+ particle list from add_analysis_dqm)
355 if (components is None or ('KLM' in components and 'CDC' in components)) and (dqm_mode in ["dont_care", "filtered"]):
356 path.add_module("KLMDQM2", MuonListName='mu+:KLMDQM',
357 MinimalMatchingDigits=12,
358 MinimalMatchingDigitsOuterLayers=0,
359 MinimalMomentumNoOuterLayers=4.0,
360 SoftwareTriggerName="")
361
362 # We want to see the datasize of all events after removing the raw data
363 if dqm_mode in ["dont_care", "all_events"]:
364 # DAQ Monitor
365 path.add_module('DAQMonitor')
def add_neurotrigger_hw(path, nntweightfile=None, debug_level=4, debugout=False, **kwargs)