Belle II Software  release-06-02-00
commondqm.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 
11 
12 import basf2 as b2
13 from svd import add_svd_create_recodigits
14 from svd.dqm_utils import add_svd_dqm_dose
15 from geometry import check_components
16 from analysisDQM import add_analysis_dqm, add_mirabelle_dqm
17 
18 
19 def 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 bandwith 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  # SVD ROI
96  path.add_module('SVDROIDQM', plotRecoDigits=False)
97 
98  # Event time measuring detectors
99  if components is None or 'CDC' in components or 'ECL' in components or 'TOP' in components:
100  eventT0DQMmodule = b2.register_module('EventT0DQM')
101  path.add_module(eventT0DQMmodule)
102 
103  if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "before_filter"]):
104  path.add_module(
105  "SoftwareTriggerHLTDQM",
106  createHLTUnitHistograms=create_hlt_unit_histograms,
107  createTotalResultHistograms=False,
108  createExpRunEventHistograms=False,
109  createErrorFlagHistograms=True,
110  cutResultIdentifiers={},
111  histogramDirectoryName="softwaretrigger_before_filter",
112  pathLocation="before filter",
113  ).set_name("SoftwareTriggerHLTDQM_before_filter")
114 
115  path.add_module("StatisticsTimingHLTDQM",
116  createHLTUnitHistograms=create_hlt_unit_histograms,
117  )
118 
119  if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "filtered"]):
120  # HLT
121  hlt_trigger_lines_in_plot = []
122  hlt_skim_lines_in_plot = []
123 
124  hlt_trigger_lines_per_unit_in_plot = [
125  "ge3_loose_tracks_inc_1_tight_not_ee2leg",
126  "Elab_gt_0.5_plus_2_others_with_Elab_gt_0.18_plus_no_clust_with_Ecms_gt_2.0",
127  "selectee",
128  "Estargt2_GeV_cluster",
129  ]
130  cutResultIdentifiers = {}
131 
132  from softwaretrigger import filter_categories, skim_categories
133 
134  filter_cat = [method for method in dir(filter_categories) if method.startswith('__') is False if method != 'RESULTS']
135  skim_cat = [method for method in dir(skim_categories) if method.startswith('__') is False]
136 
137  def read_lines(category):
138  return [i.split(" ", 1)[1].replace(" ", "_") for i in category]
139 
140  for i in filter_cat:
141  cutResultIdentifiers[i] = {"filter": read_lines(getattr(filter_categories, i))}
142  hlt_trigger_lines_in_plot += read_lines(getattr(filter_categories, i))
143 
144  for i in skim_cat:
145  cutResultIdentifiers[i] = {"skim": read_lines(getattr(skim_categories, i))}
146  hlt_skim_lines_in_plot += read_lines(getattr(skim_categories, i))
147 
148  cutResultIdentifiers["skim"] = {"skim": hlt_skim_lines_in_plot}
149  cutResultIdentifiers["filter"] = {"filter": hlt_trigger_lines_in_plot}
150 
151  additionalL1Identifiers = [
152  'ffy',
153  'fyo',
154  'c4',
155  'hie',
156  'mu_b2b',
157  'mu_eb2b',
158  'beklm',
159  'eklm2',
160  'cdcklm1',
161  'seklm1',
162  'ieklm1',
163  'ecleklm1',
164  'fso',
165  'fioiecl1',
166  'ff30',
167  'stt',
168  'ioiecl1',
169  'ioiecl2',
170  'lml1',
171  'lml2',
172  'lml3',
173  'lml4',
174  'lml5',
175  'lml6',
176  'lml7',
177  'lml8',
178  'lml9',
179  'lml10',
180  'lml12',
181  'lml13',
182  'bhapur']
183 
184  # Default plot
185  path.add_module(
186  "SoftwareTriggerHLTDQM",
187  cutResultIdentifiers=cutResultIdentifiers,
188  l1Identifiers=["fff", "ffo", "lml0", "ffb", "fp"],
189  additionalL1Identifiers=additionalL1Identifiers,
190  createHLTUnitHistograms=create_hlt_unit_histograms,
191  cutResultIdentifiersPerUnit=hlt_trigger_lines_per_unit_in_plot,
192  pathLocation="after filter",
193  )
194  # Skim plots where bhabha contamination is removed
195  path.add_module(
196  "SoftwareTriggerHLTDQM",
197  cutResultIdentifiers={
198  "skim": {"skim": hlt_skim_lines_in_plot},
199  },
200  cutResultIdentifiersIgnored={
201  "skim": [
202  "accept_bhabha_all",
203  ]
204  },
205  createTotalResultHistograms=False,
206  createExpRunEventHistograms=False,
207  histogramDirectoryName="softwaretrigger_skim_nobhabha",
208  ).set_name("SoftwareTriggerHLTDQM_skim_nobhabha")
209 
210  if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "filtered"]):
211  # SVD DATA FORMAT
212  if components is None or 'SVD' in components:
213  svdunpackerdqm = b2.register_module('SVDUnpackerDQM')
214  path.add_module(svdunpackerdqm)
215 
216  # CDC
217  if (components is None or 'CDC' in components) and (dqm_mode in ["dont_care", "filtered"]):
218  cdcdqm = b2.register_module('cdcDQM7')
219  path.add_module(cdcdqm)
220 
221  module_names = [m.name() for m in path.modules()]
222  if ('SoftwareTrigger' in module_names):
223  cdcdedxdqm = b2.register_module('CDCDedxDQM')
224  path.add_module(cdcdedxdqm)
225 
226  if dqm_environment == "expressreco":
227  path.add_module('CDCDQM')
228 
229  # ECL
230  if (components is None or 'ECL' in components) and (dqm_mode in ["dont_care", "filtered"]):
231  ecldqm = b2.register_module('ECLDQM')
232  path.add_module(ecldqm)
233  ecldqmext = b2.register_module('ECLDQMEXTENDED')
234  path.add_module(ecldqmext)
235  # we dont want to create large histograms on HLT, thus ERECO only
236  if dqm_environment == "expressreco":
237  path.add_module('ECLDQMInjection', histogramDirectoryName='ECLINJ')
238 
239  # TOP
240  if (components is None or 'TOP' in components) and (dqm_mode in ["dont_care", "filtered"]):
241  topdqm = b2.register_module('TOPDQM')
242  path.add_module(topdqm)
243 
244  # KLM
245  if (components is None or 'KLM' in components) and (dqm_mode in ["dont_care", "filtered"]):
246  klmdqm = b2.register_module("KLMDQM")
247  path.add_module(klmdqm)
248 
249  # TRG before all reconstruction runs (so on all events with all unpacked information)
250  if (components is None or 'TRG' in components) and (dqm_mode in ["dont_care", "before_filter"]):
251  # TRGECL
252  trgecldqm = b2.register_module('TRGECLDQM')
253  path.add_module(trgecldqm)
254  # TRGGDL
255  trggdldqm = b2.register_module('TRGGDLDQM')
256  trggdldqm.param('skim', 0)
257  path.add_module(trggdldqm)
258  # TRGTOP
259  trgtopdqm = b2.register_module('TRGTOPDQM')
260  trgtopdqm.param('skim', 0)
261  path.add_module(trgtopdqm)
262  # TRGGRL
263  trggrldqm = b2.register_module('TRGGRLDQM')
264  path.add_module(trggrldqm)
265  # TRGCDCTSF
266  nmod_tsf = [0, 1, 2, 3, 4, 5, 6]
267  for mod_tsf in nmod_tsf:
268  path.add_module('TRGCDCTSFDQM', TSFMOD=mod_tsf)
269  # TRGCDC2D
270  trgcdct2ddqm = b2.register_module('TRGCDCT2DDQM')
271  path.add_module(trgcdct2ddqm)
272  # TRGCDC3D
273  nmod_t3d = [0, 1, 2, 3]
274  for mod_t3d in nmod_t3d:
275  path.add_module('TRGCDCT3DConverter',
276  hitCollectionName='FirmCDCTriggerSegmentHits' + str(mod_t3d),
277  addTSToDatastore=True,
278  EventTimeName='FirmBinnedEventT0' + str(mod_t3d),
279  addEventTimeToDatastore=True,
280  inputCollectionName='FirmTRGCDC2DFinderTracks' + str(mod_t3d),
281  add2DFinderToDatastore=True,
282  outputCollectionName='FirmTRGCDC3DFitterTracks' + str(mod_t3d),
283  add3DToDatastore=True,
284  fit3DWithTSIM=0,
285  firmwareResultCollectionName='TRGCDCT3DUnpackerStore' + str(mod_t3d),
286  isVerbose=0)
287  path.add_module('TRGCDCT3DDQM', T3DMOD=mod_t3d)
288  # CDCTriggerNeuro
289  path.add_module('CDCTriggerNeuroDQM')
290  # TRG after skim
291  if (components is None or 'TRG' in components) and (dqm_mode in ["dont_care", "filtered"]):
292  # TRGGDL
293  trggdldqm_skim = b2.register_module('TRGGDLDQM')
294  trggdldqm_skim.param('skim', 1)
295  path.add_module(trggdldqm_skim)
296  # TRGTOP
297  trgtopdqm_skim = b2.register_module('TRGTOPDQM')
298  trgtopdqm_skim.param('skim', 1)
299  path.add_module(trgtopdqm_skim)
300 
301  # TrackDQM, needs at least one VXD components to be present or will crash otherwise
302  if (components is None or 'SVD' in components or 'PXD' in components) and (dqm_mode in ["dont_care", "filtered"]):
303  if (dqm_environment == "hlt"):
304  path.add_module('TrackingHLTDQM')
305  else:
306  path.add_module('ParallelTrackFilter', min_d0=-0.5, max_d0=0.5, min_z0=-1, max_z0=1,
307  inputArrayName="", outputINArrayName="TracksFromIP", outputOUTArrayName="TracksNotFromIP")
308  path.add_module('TrackingExpressRecoDQM', histogramDirectoryName="TrackingERDQM_FromIP",
309  tracksStoreArrayName="TracksFromIP", histogramTitleSuffix=" - Tracks from IP") \
310  .set_name("TrackingExpressRecoDQM_FromIP")
311  path.add_module('TrackingExpressRecoDQM', histogramDirectoryName="TrackingERDQM_NotFromIP",
312  tracksStoreArrayName="TracksNotFromIP", histogramTitleSuffix=" - Tracks not from IP") \
313  .set_name("TrackingExpressRecoDQM_NotFromIP")
314 
315  # ARICH
316  if (components is None or 'ARICH' in components) and (dqm_mode in ["dont_care", "filtered"]):
317  path.add_module('ARICHDQM')
318 
319  if dqm_mode in ["dont_care", "filtered"]:
320  # PhysicsObjectsDQM
321  add_analysis_dqm(path)
322  if dqm_environment == "expressreco" and (dqm_mode in ["dont_care"]):
323  add_mirabelle_dqm(path)
324 
325  # KLM2 (requires mu+ particle list from add_analysis_dqm)
326  if (components is None or 'KLM' in components) and (dqm_mode in ["dont_care", "filtered"]):
327  klmdqm2 = b2.register_module("KLMDQM2")
328  path.add_module(klmdqm2, MuonListName='mu+:KLMDQM',
329  MinimalMatchingDigits=12,
330  MinimalMatchingDigitsOuterLayers=0,
331  MinimalMomentumNoOuterLayers=4.0)
332 
333  # We want to see the datasize of all events after removing the raw data
334  if dqm_mode in ["dont_care", "all_events"]:
335  # DAQ Monitor
336  path.add_module('DAQMonitor')