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