Belle II Software  release-05-01-25
commondqm.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 import basf2 as b2
5 from geometry import check_components
6 from analysisDQM import add_analysis_dqm, add_mirabelle_dqm
7 
8 
9 def add_common_dqm(path, components=None, dqm_environment="expressreco", dqm_mode="dont_care", create_hlt_unit_histograms=False):
10  """
11  This function adds DQMs which are common for Cosmic runs and Collion runs
12 
13  @param components: A list of the detector components which are available in this
14  run of basf2
15  @param dqm_environment: The environment the DQM modules are running in
16  "expressreco" (default) if running on the ExpressReco system
17  "hlt" if running on the HLT online reconstructon nodes
18  If running on the hlt, you may want to output less or other DQM plots
19  due to the limited bandwith of the HLT nodes.
20  @param dqm_mode: How to split up the path for online/HLT.
21  For dqm_mode == "dont_care" all the DQM modules should be added.
22  For dqm_mode == "all_events" only the DQM modules which should run on all events
23  (filtered and dismissed) should be added
24  For dqm_mode == "before_reco" only the DQM modules which should run before
25  all reconstruction
26  For dqm_mode == "filtered" only the DQM modules which should run on filtered
27  events should be added
28  @param create_hlt_unit_histograms: Parameter for SoftwareTiggerHLTDQMModule.
29  Should be True only when running on the HLT servers
30  """
31  assert dqm_mode in ["dont_care", "all_events", "filtered", "before_filter"]
32  # Check components.
33  check_components(components)
34 
35  if dqm_environment == "expressreco" and (dqm_mode in ["dont_care"]):
36  # PXD (not useful on HLT)
37  if components is None or 'PXD' in components:
38  path.add_module('PXDDAQDQM', histogramDirectoryName='PXDDAQ')
39  path.add_module('PXDROIDQM', histogramDirectoryName='PXDROI')
40  path.add_module('PXDDQMExpressReco', histogramDirectoryName='PXDER')
41  path.add_module('SetupGenfitExtrapolation')
42  path.add_module('PXDROIFinder',
43  recoTrackListName='RecoTracks',
44  PXDInterceptListName='PXDIntercepts')
45  # moved to cosmics/collision as we need different cuts
46  # path.add_module('PXDDQMEfficiency', histogramDirectoryName='PXDEFF')
47  path.add_module('PXDTrackClusterDQM', histogramDirectoryName='PXDER')
48  path.add_module('PXDInjectionDQM', histogramDirectoryName='PXDINJ', eachModule=True)
49  # SVD
50  if components is None or 'SVD' in components:
51  # SVD DATA FORMAT
52  svdunpackerdqm = b2.register_module('SVDUnpackerDQM')
53  path.add_module(svdunpackerdqm)
54  # offline ZS emulator
55  path.add_module(
56  'SVDZeroSuppressionEmulator',
57  SNthreshold=5,
58  ShaperDigits='SVDShaperDigits',
59  ShaperDigitsIN='SVDShaperDigitsZS5',
60  FADCmode=True)
61  # SVD Occupancy after Injection
62  path.add_module('SVDDQMInjection', ShaperDigits='SVDShaperDigitsZS5')
63  # SVDDQMExpressReco General
64  path.add_module('SVDDQMExpressReco',
65  offlineZSShaperDigits='SVDShaperDigitsZS5')
66  # SVD HIT TIME
67  path.add_module('SVDDQMHitTime')
68  # SVD EFFICIENCY
69  path.add_module('SetupGenfitExtrapolation')
70  path.add_module('SVDROIFinder',
71  recoTrackListName='RecoTracks',
72  SVDInterceptListName='SVDIntercepts')
73  path.add_module('SVDDQMEfficiency')
74  # SVD CLUSTERS ON TRACK
75  path.add_module('SVDDQMClustersOnTrack')
76 
77  # Event time measuring detectors
78  if components is None or 'CDC' in components or 'ECL' in components or 'TOP' in components:
79  eventT0DQMmodule = b2.register_module('EventT0DQM')
80  path.add_module(eventT0DQMmodule)
81 
82  if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "before_filter"]):
83  path.add_module(
84  "SoftwareTriggerHLTDQM",
85  createHLTUnitHistograms=create_hlt_unit_histograms,
86  createTotalResultHistograms=False,
87  createExpRunEventHistograms=False,
88  createErrorFlagHistograms=True,
89  cutResultIdentifiers={},
90  histogramDirectoryName="softwaretrigger_before_filter",
91  ).set_name("SoftwareTriggerHLTDQM_before_filter")
92  path.add_module("StatisticsTimingHLTDQM",
93  createHLTUnitHistograms=create_hlt_unit_histograms,
94  )
95 
96  if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "filtered"]):
97  # HLT
98  hlt_trigger_lines_in_plot = []
99  hlt_skim_lines_in_plot = []
100 
101  hlt_trigger_lines_per_unit_in_plot = [
102  "ge3_loose_tracks_inc_1_tight_not_ee2leg",
103  "Elab_gt_0.5_plus_2_others_with_Elab_gt_0.18_plus_no_clust_with_Ecms_gt_2.0",
104  "selectee",
105  "Estargt2_GeV_cluster",
106  ]
107  cutResultIdentifiers = {}
108 
109  from softwaretrigger import filter_categories, skim_categories
110 
111  filter_cat = [method for method in dir(filter_categories) if method.startswith('__') is False if method is not 'RESULTS']
112  skim_cat = [method for method in dir(skim_categories) if method.startswith('__') is False]
113 
114  def read_lines(category):
115  return [i.split(" ", 1)[1].replace(" ", "_") for i in category]
116 
117  for i in filter_cat:
118  cutResultIdentifiers[i] = {"filter": read_lines(getattr(filter_categories, i))}
119  hlt_trigger_lines_in_plot += read_lines(getattr(filter_categories, i))
120 
121  for i in skim_cat:
122  cutResultIdentifiers[i] = {"skim": read_lines(getattr(skim_categories, i))}
123  hlt_skim_lines_in_plot += read_lines(getattr(skim_categories, i))
124 
125  cutResultIdentifiers["skim"] = {"skim": hlt_skim_lines_in_plot}
126  cutResultIdentifiers["filter"] = {"filter": hlt_trigger_lines_in_plot}
127 
128  # Default plot
129  path.add_module(
130  "SoftwareTriggerHLTDQM",
131  cutResultIdentifiers=cutResultIdentifiers,
132  l1Identifiers=["fff", "ffo", "lml0", "ffb", "fp"],
133  createHLTUnitHistograms=create_hlt_unit_histograms,
134  cutResultIdentifiersPerUnit=hlt_trigger_lines_per_unit_in_plot,
135  )
136  # Skim plots where bhabha contamination is removed
137  path.add_module(
138  "SoftwareTriggerHLTDQM",
139  cutResultIdentifiers={
140  "skim": {"skim": hlt_skim_lines_in_plot},
141  },
142  cutResultIdentifiersIgnored={
143  "skim": [
144  "accept_bhabha_all",
145  ]
146  },
147  createTotalResultHistograms=False,
148  createExpRunEventHistograms=False,
149  histogramDirectoryName="softwaretrigger_skim_nobhabha",
150  ).set_name("SoftwareTriggerHLTDQM_skim_nobhabha")
151 
152  if dqm_environment == "hlt" and (dqm_mode in ["dont_care", "filtered"]):
153  # SVD DATA FORMAT
154  if components is None or 'SVD' in components:
155  svdunpackerdqm = b2.register_module('SVDUnpackerDQM')
156  path.add_module(svdunpackerdqm)
157 
158  # CDC
159  if (components is None or 'CDC' in components) and (dqm_mode in ["dont_care", "filtered"]):
160  cdcdqm = b2.register_module('cdcDQM7')
161  path.add_module(cdcdqm)
162 
163  module_names = [m.name() for m in path.modules()]
164  if ('SoftwareTrigger' in module_names):
165  cdcdedxdqm = b2.register_module('CDCDedxDQM')
166  path.add_module(cdcdedxdqm)
167 
168  if dqm_environment == "expressreco":
169  path.add_module('CDCDQM')
170 
171  # ECL
172  if (components is None or 'ECL' in components) and (dqm_mode in ["dont_care", "filtered"]):
173  ecldqm = b2.register_module('ECLDQM')
174  path.add_module(ecldqm)
175  ecldqmext = b2.register_module('ECLDQMEXTENDED')
176  path.add_module(ecldqmext)
177  # we dont want to create large histograms on HLT, thus ERECO only
178  if dqm_environment == "expressreco":
179  path.add_module('ECLDQMInjection', histogramDirectoryName='ECLINJ')
180  # TOP
181  if (components is None or 'TOP' in components) and (dqm_mode in ["dont_care", "filtered"]):
182  topdqm = b2.register_module('TOPDQM')
183  path.add_module(topdqm)
184  # KLM
185  if (components is None or 'KLM' in components) and (dqm_mode in ["dont_care", "filtered"]):
186  klmdqm = b2.register_module("KLMDQM")
187  path.add_module(klmdqm)
188 
189  # TRG before all reconstruction runs (so on all events with all unpacked information)
190  if (components is None or 'TRG' in components) and (dqm_mode in ["dont_care", "before_filter"]):
191  # TRGECL
192  trgecldqm = b2.register_module('TRGECLDQM')
193  path.add_module(trgecldqm)
194  # TRGGDL
195  trggdldqm = b2.register_module('TRGGDLDQM')
196  trggdldqm.param('skim', 0)
197  path.add_module(trggdldqm)
198  # TRGTOP
199  trgtopdqm = b2.register_module('TRGTOPDQM')
200  trgtopdqm.param('skim', 0)
201  path.add_module(trgtopdqm)
202  # TRGGRL
203  trggrldqm = b2.register_module('TRGGRLDQM')
204  path.add_module(trggrldqm)
205  # TRGCDCTSF
206  nmod_tsf = [0, 1, 2, 3, 4, 5, 6]
207  for mod_tsf in nmod_tsf:
208  path.add_module('TRGCDCTSFDQM', TSFMOD=mod_tsf)
209  # TRGCDC2D
210  trgcdct2ddqm = b2.register_module('TRGCDCT2DDQM')
211  path.add_module(trgcdct2ddqm)
212  # TRGCDC3D
213  nmod_t3d = [0, 1, 2, 3]
214  for mod_t3d in nmod_t3d:
215  path.add_module('TRGCDCT3DConverter',
216  hitCollectionName='FirmCDCTriggerSegmentHits' + str(mod_t3d),
217  addTSToDatastore=True,
218  EventTimeName='FirmBinnedEventT0' + str(mod_t3d),
219  addEventTimeToDatastore=True,
220  inputCollectionName='FirmTRGCDC2DFinderTracks' + str(mod_t3d),
221  add2DFinderToDatastore=True,
222  outputCollectionName='FirmTRGCDC3DFitterTracks' + str(mod_t3d),
223  add3DToDatastore=True,
224  fit3DWithTSIM=0,
225  firmwareResultCollectionName='TRGCDCT3DUnpackerStore' + str(mod_t3d),
226  isVerbose=0)
227  path.add_module('TRGCDCT3DDQM', T3DMOD=mod_t3d)
228  # TRGCDCNNT
229  path.add_module('CDCTriggerNeuroDQM')
230  # TRG after skim
231  if (components is None or 'TRG' in components) and (dqm_mode in ["dont_care", "filtered"]):
232  # TRGGDL
233  trggdldqm_skim = b2.register_module('TRGGDLDQM')
234  trggdldqm_skim.param('skim', 1)
235  path.add_module(trggdldqm_skim)
236  # TRGTOP
237  trgtopdqm_skim = b2.register_module('TRGTOPDQM')
238  trgtopdqm_skim.param('skim', 1)
239  path.add_module(trgtopdqm_skim)
240 
241  # TrackDQM, needs at least one VXD components to be present or will crash otherwise
242  if (components is None or 'SVD' in components or 'PXD' in components) and (dqm_mode in ["dont_care", "filtered"]):
243  trackDqm = b2.register_module('TrackDQM')
244  path.add_module(trackDqm)
245 
246  # ARICH
247  if (components is None or 'ARICH' in components) and (dqm_mode in ["dont_care", "filtered"]):
248  path.add_module('ARICHDQM')
249 
250  if dqm_mode in ["dont_care", "filtered"]:
251  # PhysicsObjectsDQM
252  add_analysis_dqm(path)
253  if dqm_environment == "expressreco" and (dqm_mode in ["dont_care"]):
254  add_mirabelle_dqm(path)
255 
256  # We want to see the datasize of all events after removing the raw data
257  if dqm_mode in ["dont_care", "all_events"]:
258  # DAQ Monitor
259  path.add_module('DAQMonitor')