ATLAS Offline Software
Loading...
Searching...
No Matches
LArRawChannelMonAlg.py
Go to the documentation of this file.
2# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3#
4
5"""!@file LArRawChannelMonAlg.py
6@date Nov. 2021
7@brief configuration of LArRawChannels monitoring algorithm following
8the implementation model of other LAr DQM algorithms, and default
9settings taken from LArMonTools/LArRawChannelMonTool_joboptions.py
10"""
11
12from LArMonitoring.GlobalVariables import lArDQGlobals
13from GaudiKernel.SystemOfUnits import MeV, GeV
14
15_USE_LEGACY_BINNING_IN_ENDCAPS = True
16
17
19 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
20 from AthenaConfiguration.ComponentFactory import CompFactory
21 from AthenaMonitoring import AthMonitorCfgHelper
22 from CaloTools.CaloNoiseCondAlgConfig import CaloNoiseCondAlgCfg
23 from AthenaMonitoring.AtlasReadyFilterConfig import AtlasReadyFilterCfg
24 from AthenaConfiguration.Enums import BeamType
25 cosmics = (flags.Beam.Type is BeamType.Cosmics)
26 stream = _get_stream(flags)
27 try:
28 signal = flags.LArMon.doLArRawMonitorSignal
29 except AttributeError:
30 signal = False
31 helper = AthMonitorCfgHelper(flags, 'LArRawChannelMonAlgCfg')
33 helper, instance=CompFactory.LArRawChannelMonAlg,
34 flags=flags, cosmics=cosmics, stream=stream, doSignal=signal)
35 noise_alg = CaloNoiseCondAlgCfg(flags, noisetype=alg.NoiseKey.Path)
36 accumulator = ComponentAccumulator()
37 accumulator.merge(noise_alg)
38 alg.AtlasReadyFilterTool.append(
39 accumulator.popToolsAndMerge(AtlasReadyFilterCfg(flags)))
40 accumulator.merge(helper.result())
41 return accumulator
42
43
44def LArRawChannelMonConfigCore(helper, instance, flags, cosmics, stream, doSignal):
45 alg = helper.addAlgorithm(instance, 'LArRawChannelMonAlg')
46 alg.occupancy_thresholds = [
47 100 * MeV, # EMBA
48 100 * MeV, # EMBC
49 100 * MeV, # EMECA
50 100 * MeV, # EMECC
51 500 * MeV, # HECA
52 500 * MeV, # HECC
53 700 * MeV, # FCALA
54 700 * MeV, # FCALC
55 ]
56 alg.signal_thresholds = [-9999. * GeV ] * 8
57 alg.pos_noise_thresholds = [3] * 8
58 alg.neg_noise_thresholds = [3] * 8
59 alg.bcid_signal_threshold = 500. * MeV
60
61 alg.time_threshold = 5
62 alg.quality_threshold = 65530
63 alg.noise_threshold = 3
64 alg.noise_burst_percent_threshold = [
65 1, # EMBA
66 1, # EMBC
67 1, # EMECA
68 1, # EMECC
69 1, # HECA
70 1, # HECC
71 2, # FCALA
72 2, # FCALC
73 ]
74 alg.noise_burst_nChannel_threshold = [10] * 8
75 alg.monitor_occupancy = True # False
76 if cosmics:
77 alg.NoiseKey = 'electronicNoise'
78 alg.monitor_signal = True
79 alg.monitor_positive_noise = True
80 alg.monitor_negative_noise = True
81 else:
82 alg.NoiseKey = 'totalNoise'
83 alg.monitor_signal = doSignal
84 alg.monitor_positive_noise = doSignal
85 alg.monitor_negative_noise = doSignal
86 alg.monitor_time = False
87 alg.monitor_quality = doSignal
88 alg.monitor_burst = True
89 if stream in ('express', 'RNDM'):
90 alg.noise_streams = ['RNDM']
91 alg.TriggerChain = 'L1_RD0_EMPTY'
92 else:
93 alg.noise_streams = ['RNDM']
94 alg.ProblemsToMask = [
95 'highNoiseHG',
96 'highNoiseMG',
97 'highNoiseLG',
98 'deadReadout',
99 'deadPhys',
100 'almostDead',
101 'short',
102 'sporadicBurstNoise',
103 ]
104 alg.db_and_ofc_only = True
105
106 from LArConfiguration.LArConfigFlags import RawChannelSource
107 if flags.LAr.RawChannelSource is RawChannelSource.Calculated:
108 alg.LArRawChannelContainerKey="LArRawChannels_FromDigits"
109
110 # Histograms for different partitions are handled together via a
111 # GenericMonitoringArray, but since some of the ranges and titles
112 # vary between partitions, the definition of histograms must be
113 # done separately for each partition, using the 'pattern' argument:
114 montool = helper.addArray([lArDQGlobals.Partitions], alg,
115 'LArRawChannelMon', topPath='/LAr/RawChannel')
116 for index, partition in enumerate(lArDQGlobals.Partitions):
117 _define_histograms(partition, index, montool, alg)
118 return alg
119
120
121def _define_histograms(partition, part_index, montool, alg):
122 common_args = {
123 'path': '{0}',
124 'pattern': [partition],
125 'opt' : 'kAlwaysCreate'
126 # 'merge' unspecified: the default should suit all histograms
127 }
128 hargs2d = {
129 **common_args,
130 'type': 'TH2I',
132 }
133 lumiblock_binning = {'xbins': 3000, 'xmin': 0.5, 'xmax': 3000.5}
134 title = ' as a function of FEB and channel in {0};' \
135 'Halfcrate (+ increasing slot);Channel'
136 sigma_pos = '{:g}#sigma'.format(alg.pos_noise_thresholds[part_index])
137 sigma_neg = '{:g}#sigma'.format(alg.neg_noise_thresholds[part_index])
138 montool.defineHistogram(
139 'S,C;{0}_occupancy', **hargs2d,
140 cutmask='occ',
141 title='Number of events above {:g} MeV{}'.format(
142 alg.occupancy_thresholds[part_index] / MeV,
143 title))
144 hargs2d['type'] = 'TProfile2D'
145 title = title.replace('{0}', '{0} (no LArEventInfo::ERROR)')
146 if alg.monitor_signal:
147 montool.defineHistogram(
148 'S,C,E;{0}_signal_AVG', **hargs2d,
149 cutmask='sig',
150 title='{0}{1};{0}'.format('Average Energy (MeV)', title))
151 montool.defineHistogram(
152 'S,C,G;{0}_gain', **hargs2d,
153 cutmask='sig',
154 title='{0}{1};{0}'.format('Average gain', title))
155 title += ';Percentage Accepted'
156 percent = 'Percentage of events '
157 if alg.monitor_positive_noise:
158 montool.defineHistogram(
159 'S,C,posn;{0}_acceptance_AVG', **hargs2d,
160 title='{} above {} total noise{}'.format(
161 percent, sigma_pos, title))
162 if alg.monitor_negative_noise:
163 montool.defineHistogram(
164 'S,C,negn;{0}_noise_acceptance_AVG', **hargs2d,
165 title='{} below -{} total noise{}'.format(
166 percent, sigma_neg, title))
167 if alg.monitor_quality:
168 montool.defineHistogram(
169 'S,C,Q4k;{0}_quality_AVG', **hargs2d,
170 title='{} with q-factor above {:g}{}'.format(
171 percent, alg.quality_threshold, title))
172 if alg.monitor_quality:
173 montool.defineHistogram(
174 'nQ4k;{0}_quality_nChannel', **common_args,
175 type='TH1D', xbins=50, xmin=-0.5, xmax=49.5,
176 title = 'Number of channels in {{0}} with q-factor > {};' \
177 'Number of channels;Number of events per channel'.format(
178 alg.quality_threshold))
179 montool.defineHistogram(
180 'lb;{0}_quality_burst', **common_args,
181 type='TH1D', **lumiblock_binning, cutmask='qburst',
182 title = 'Number of events with more than {:g}% ' \
183 'of all channels in {{0}} reporting q-factor > {};' \
184 'Luminosity Block;Number of events per LB'.format(
185 alg.noise_burst_percent_threshold[part_index],
186 alg.quality_threshold))
187 if alg.monitor_burst:
188 title = 'Yield of channels with E > +{t} in {{0}}{cut};' \
189 'Percent of channels;Number of events per 0.02%'
190 hargs = {
191 **common_args,
192 'type': 'TH1D',
193 'xbins': 375,
194 'xmin': 0.,
195 'xmax': 7.5
196 }
197 name = '%noisy;{0}_noise_fraction'
198 montool.defineHistogram(
199 name, **hargs, title=title.format(t=sigma_pos, cut=''))
200 montool.defineHistogram(
201 '%noisy_neg;{0}_noise_fraction_Neg', **hargs,
202 title=title.replace('> +', '< -').format(t=sigma_neg, cut=''))
203 montool.defineHistogram(
204 name + '_W', **hargs, cutmask='quietW',
205 title=title.format(t=sigma_pos, cut=' (no LArNoisyRO_StdOpt)'))
206 montool.defineHistogram(
207 name + '_NoLArNoisyRO', **hargs, cutmask='quiet',
208 title=title.format(t=sigma_pos, cut=' (no LArNoisyRO_Std)'))
209 montool.defineHistogram(
210 name + '_TimeVetoLArNoisyRO', **hargs, cutmask='quietITW',
211 title=title.format(t=sigma_pos, cut=' (time vetoed)'))
212 title = 'Number of events with Y(3#sigma) > {t} in {{0}}{cut};' \
213 'Luminosity Block;Number of events per LB'
214 hargs = {**common_args, 'type': 'TH1D', **lumiblock_binning}
215 tb = '{:g}%'.format(alg.noise_burst_percent_threshold[part_index])
216 montool.defineHistogram(
217 'lb;{0}_burst', **hargs, cutmask='burst',
218 title=title.format(t=tb, cut=''))
219 montool.defineHistogram(
220 'lb;{0}_timeVetoBurst', **hargs, cutmask='burst_quietW',
221 title=title.format(t=tb, cut=' (time vetoed)'))
222 if alg.monitor_time:
223 montool.defineHistogram(
224 'T;{0}_mean_feb_time', **common_args, type='TH1D',
225 xbins=101, xmin=-50.5, xmax=50.5,
226 title='Average time of channels in each FEB of {{0}} ' \
227 'reporting E > {} #sigma;<t(FEB)> - <t(event)> (ns);' \
228 'Number of FEBs per ns'.format(alg.time_threshold))
229 if alg.monitor_signal:
230 montool.defineHistogram(
231 'lb,detE;{0}_pedestal_evolution', **common_args, type='TProfile',
232 **lumiblock_binning, cutmask='quietW',
233 title='Energy sum (time vetoed) in {0};' \
234 'Luminosity Block;Mean total energy(MeV)')
235 montool.defineHistogram(
236 'bc,detE;{0}_sumE_vs_BCID', **common_args, type='TProfile',
237 xbins=3564, xmin=0.5, xmax=3564.5,
238 title = 'Energy sum per bunch crossing in {0};' \
239 'Bunch Crossing ID;Mean total energy (MeV)')
240
241
242def _get_stream(flags):
243 if flags.DQ.useTrigger and not flags.Common.isOnline:
244 from PyUtils.MetaReader import read_metadata
245 metadata=read_metadata(flags.Input.Files[0])
246 return (metadata[flags.Input.Files[0]]['stream'] + '_').split('_')[1]
247 return ''
248
249
251 n = lArDQGlobals.Feedthrough_Slot_Nbins.get(partition, 1)
252 bins = lArDQGlobals.Feedthrough_Slot_range.get(partition, (0., 1.))
253 labels = ['?'] * n
254 if partition.startswith('EMB'):
255 if len(lArDQGlobals.Feedthrough_Slot_labels_Barrel) == n:
256 labels = lArDQGlobals.Feedthrough_Slot_labels_Barrel
257 elif len(lArDQGlobals.Feedthrough_Slot_labels_Endcap) == n:
258 labels = lArDQGlobals.Feedthrough_Slot_labels_Endcap
259 axis_ranges = {
260 'xbins': n,
261 'xmin': bins[0],
262 'xmax': bins[1],
263 'xlabels': labels,
264 'ybins': lArDQGlobals.FEB_N_channels,
265 'ymin': -0.5,
266 'ymax': lArDQGlobals.FEB_N_channels - 0.5,
267 }
268 if _USE_LEGACY_BINNING_IN_ENDCAPS and not partition.startswith('EMB'):
269 merged_bins = {
270 'EMEC': [
271 (14, 15), (29, 30), (48, 60), (74, 75), (89, 105), (119, 120),
272 (134, 135), (153, 165), (179, 180), (194, 195), (209, 210),
273 (224, 225), (243, 255), (269, 270), (284, 285), (299, 300),
274 (314, 315), (333, 345), (359, 360), (374, 375)
275 ],
276 'HEC': [
277 (1, 49), (56, 154), (161, 244), (251, 334), (341, 375)
278 ],
279 'FCal': [(1, 90), (106, 375)],
280 }
281 bins = [0.5]
282 for b in merged_bins[partition[:-1]]:
283 bins += [x + 0.5 for x in range(int(bins[-1] + 0.5), b[0])]
284 bins.append(b[1] + 0.5)
285 axis_ranges['xbins'] = bins
286 # Try to obtain meaningful bin labels from GlobalVariables.py:
287 if n > 1 and axis_ranges['xmax'] > axis_ranges['xmin']:
288 labels = [''] * (len(bins) - 1)
289 coeff = n / (axis_ranges['xmax'] - axis_ranges['xmin'])
290 nslots = lArDQGlobals.FEB_Slot[partition][1]
291 for b, x in enumerate(bins[:-1]):
292 i = (int(coeff * (x - axis_ranges['xmin'])))
293 i -= (i % nslots)
294 if bins[b+1] - x < 1.5 and 0 <= i < n:
295 txt = axis_ranges['xlabels'][i]
296 if txt not in labels:
297 labels[b] = txt
298 axis_ranges['xlabels'] = labels
299 else:
300 axis_ranges.pop('xlabels')
301 axis_ranges.pop('xmin')
302 axis_ranges.pop('xmax')
303 return axis_ranges
304
305
306if __name__=='__main__':
307 from AthenaConfiguration.AllConfigFlags import initConfigFlags
308 flags = initConfigFlags()
309
310 from AthenaCommon.Logging import log
311 from AthenaCommon.Constants import WARNING
312 log.setLevel(WARNING)
313
314 from LArMonitoring.LArMonConfigFlags import addLArMonFlags
315 flags.addFlagsCategory("LArMon", addLArMonFlags)
316
317 from AthenaConfiguration.TestDefaults import defaultTestFiles
318 from AthenaConfiguration.Enums import BeamType
319 flags.Input.Files = defaultTestFiles.RAW_RUN3
320 from AthenaConfiguration.TestDefaults import defaultGeometryTags
321 flags.GeoModel.AtlasVersion = defaultGeometryTags.RUN3
322 flags.Output.HISTFileName = 'LArRawChannelMonOutput.root'
323 flags.DQ.enableLumiAccess = False
324 flags.DQ.useTrigger = False
325 flags.Beam.Type = BeamType.Collisions
326 flags.lock()
327
328 from AthenaConfiguration.MainServicesConfig import MainServicesCfg
329 cfg = MainServicesCfg(flags)
330 from CaloRec.CaloRecoConfig import CaloRecoCfg
331 cfg.merge(CaloRecoCfg(flags))
332 cfg.merge(LArRawChannelMonConfig(flags))
333 cfg.run(100)
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179
_superslot_channel_axis_ranges(partition)
_define_histograms(partition, part_index, montool, alg)
LArRawChannelMonConfigCore(helper, instance, flags, cosmics, stream, doSignal)