8 This class is designed to handle registering all of L1Calo's monitoring histograms and trees in a
9 coherent way. It will also generate the han config file for all the histograms.
14 from collections
import defaultdict
17 hanThresholdConfigs = {}
19 SIGNATURES = [
"gJ",
"gLJ",
"gLJRho",
"gXEJWOJ",
"gTEJWOJ",
"gXENC",
"gTENC",
"gXERHO",
"gTERHO",
"jJ",
"jEM",
"jTAU",
"jXE",
"jTE",
"eTAU",
"eEM"]
20 HELPURL =
"https://codimd.web.cern.ch/s/678H65Tk9"
24 from contextlib
import redirect_stdout
25 with open(filename,
'w')
as f:
26 with redirect_stdout(f):
36 def printConf(d,prefix=""):
37 for key,value
in d.items():
40 if(key==
"dir detail" or key==
"dir Developer"):
41 print(prefix+
" algorithm = GatherData")
42 printConf(value,prefix +
" ")
45 print(prefix,key,
"=",value)
47 if key ==
"output": outputs.add(value)
51 printConf(L1CaloMonitorCfgHelper.hanConfigs,
" ")
54 print(
"output top_level {")
55 def printOutputs(d,prefix=""):
56 for key,value
in d.items():
57 if(key.startswith(
"hist ")):
59 elif type(value)==dict:
60 print(prefix,key.replace(
"dir ",
"output "),
"{")
61 printOutputs(value,prefix +
" ")
63 print(
" output L1Calo {")
64 printOutputs(L1CaloMonitorCfgHelper.hanConfigs,
" ")
70 algorithm AnyNonZeroBinIsError {
71 # Use this algo if want error on any non-zero bin content
72 libname = libdqm_summaries.so
73 name = Bins_NotEqual_Threshold
75 thresholds = th_AnyBinIsError
78 for algName,algProps
in L1CaloMonitorCfgHelper.hanAlgConfigs.items():
79 print(f
"algorithm {algName} {{")
80 for propName,propVal
in algProps.items():
81 print(f
" {propName} = {propVal}")
85 thresholds th_AnyBinIsError {
92 for threshName,threshProps
in L1CaloMonitorCfgHelper.hanThresholdConfigs.items():
93 print(f
"thresholds {threshName} {{")
94 for parName,parLims
in threshProps.items():
95 print(f
" limits {parName} {{")
96 for limName,limVal
in parLims.items():
97 print(f
" {limName} = {limVal}")
103 def __init__(self, flags, algClassOrObj = None, name = None, *args, **kwargs):
105 Create the configuration helper.
108 flags -- the configuration flag object
109 algClassOrObj -- the name you want to assign the family of algorithms
111 from AthenaMonitoring
import AthMonitorCfgHelper
112 self.
helper = AthMonitorCfgHelper(flags,name)
113 self.
alg = self.
helper.addAlgorithm(algClassOrObj,name,*args, **kwargs)
if algClassOrObj
is not None else None
121 :param name: name of algorithm
122 :param hanConfig: dict of algo properties
123 :param thresholdConfig: dict of thresholds, keys in form of ParName.level
130 if thresholdConfig
is not None:
131 hanConfig[
"thresholds"] = f
"L1CaloThreshold{thresNum}"
133 for parName,limVals
in thresholdConfig.items():
134 if len(limVals) != 2:
135 raise Exception(
"must specify two limits: warning and error")
136 if parName
not in threshDict: threshDict[parName] = {}
137 threshDict[parName][
"warning"] = limVals[0]
138 threshDict[parName][
"error"] = limVals[1]
141 if str(thresh)==
str(threshDict):
143 hanConfig[
"thresholds"] = threshName
164 self.
defineHistogram(*args,fillGroup=fillGroup,hanConfig=hanConfig,paths=[],path=path,**kwargs)
167 argsCopy =
list(args)
168 if ";" not in args[0]:
169 argsCopy[0] +=
";h_" + argsCopy[0].
replace(
":",
"_")
171 if kwargs.get(
"path",
None)
is None:
173 kwargs[
"path"] =
"Developer/" + self.
alg.name
174 elif kwargs[
"path"][-1] ==
'/':
175 kwargs[
"path"] = kwargs[
"path"][:-1]
177 splitPath = kwargs[
"path"].
split(
"/")
178 if splitPath[0]
not in [
"Shifter",
"Expert",
"Developer"]:
179 raise Exception(
"Path of histogram invalid, does not start with one of the allowed audiences (Shifter,Expert,Developer)")
182 if splitPath[0] !=
"Developer" and splitPath[-1] !=
"detail" and (
"algorithm" not in hanConfig):
184 if "description" not in hanConfig:
185 raise Exception(
"Must specify a hanConfig for a Shifter or Expert (non-detail) histogram")
187 hanConfig[
"algorithm"] =
"GatherData"
190 if fillGroup
is None: fillGroup = self.
alg.name +
"_fillGroup"
194 if "merge" not in kwargs
and kwargs.get(
"type",
"") !=
"TEfficiency":
195 kwargs[
"merge"] =
"merge"
197 histName = argsCopy[0].
split(
";")[-1]
200 if splitPath[0] ==
"Expert":
201 linkUrl = self.
HELPURL +
"#" +
"".
join(splitPath[1:]+[histName])
202 linkUrl = f
"<a href=\"{linkUrl}\">Help</a>"
203 if "description" not in hanConfig: hanConfig[
"description"] = linkUrl
204 else: hanConfig[
"description"] +=
" - " + linkUrl
206 splitPathWithHist = splitPath + [histName]
207 x = L1CaloMonitorCfgHelper.hanConfigs
208 for i,p
in enumerate(splitPathWithHist):
209 key = (
"dir " if i!=len(splitPathWithHist)-1
else "hist ") + p
213 hanConfig[
"output"] =
"/".
join([
"L1Calo"]+splitPath)
220 if ";" not in args[0]:
221 raise Exception(
"Must specify a tree name using ';name' suffix")
222 treeName = args[0].
split(
";")[-1]
225 raise Exception(
"Should not have comma in list of branch names and types")
227 if kwargs.get(
"path",
None)
is None:
229 kwargs[
"path"] =
"Developer/" + self.
alg.name
232 splitPath = kwargs[
"path"].
split(
"/")
233 if splitPath[0]
not in [
"Developer"]:
234 raise Exception(
"Path of tree invalid, must be in the audience=Developer directory")
237 if fillGroup
is None: fillGroup = self.
alg.name +
"_fillGroup"
244 histName =
"h_" + treeName +
"_entries"
245 argsCopy =
list(args)
246 argsCopy[0] = argsCopy[0].
replace(
";"+treeName,
";"+histName)
247 kwargsCopy = dict(kwargs)
248 kwargsCopy[
"title"] = f
"Number of Entries in {treeName} TTree" +
";" +
";".
join(kwargsCopy.get(
"title",
"").
split(
";")[1:])
249 kwargsCopy[
"opt"] = [
'kCanRebin']
250 kwargsCopy[
"merge"] =
"merge"
251 is2d = (kwargsCopy[
"title"].
count(
";")>1)
252 self.
defineHistogram(argsCopy[0],type=
"TH2I" if is2d
else "TH1I",xbins=1,xmin=0,xmax=1,ybins=1
if is2d
else None,ymin=0,ymax=1,fillGroup=fillGroup,**kwargsCopy)
253 if not any([x
in self.
dqEnv for x
in [
'tier0',
'online']]):
264 '''Function to call l1calo DQ monitoring algorithms'''
265 from AthenaConfiguration.ComponentAccumulator
import ComponentAccumulator
266 from AthenaConfiguration.Enums
import Format
270 local_logger = logging.getLogger(
'AthenaMonitoringCfg')
271 info = local_logger.info
272 info(
'In LVL1CaloMonitoringConfig')
277 if not flags.Trigger.Online.isPartition:
278 if not flags.DQ.triggerDataAvailable:
281 isData =
not flags.Input.isMC
284 validation=flags.DQ.Steering.LVL1Calo.doValidation
288 if not validation
and isData
and flags.DQ.Environment
not in (
'tier0Raw',
'AOD'):
290 from TrigT1CaloMonitoring.PprMonitorAlgorithm
import PprMonitoringConfig
291 from TrigT1CaloMonitoring.JepJemMonitorAlgorithm
import JepJemMonitoringConfig
294 from AthenaConfiguration.AutoConfigFlags
import GetFileMD
296 inputContainsRun3FormatConfigMetadata = (
"metadata_items" in md
and any((
'TriggerMenuJson' in key)
for key
in md[
"metadata_items"].
keys()))
299 if flags.Input.Format
is not Format.POOL
or inputContainsRun3FormatConfigMetadata:
301 from TrigT1CaloMonitoring.CpmMonitorAlgorithm
import CpmMonitoringConfig
302 from TrigT1CaloMonitoring.CpmSimMonitorAlgorithm
import CpmSimMonitoringConfig
303 from TrigT1CaloMonitoring.JepCmxMonitorAlgorithm
import JepCmxMonitoringConfig
304 from TrigT1CaloMonitoring.OverviewMonitorAlgorithm
import OverviewMonitoringConfig
305 from TrigT1CaloMonitoring.PPMSimBSMonitorAlgorithm
import PPMSimBSMonitoringConfig
313 if flags.Input.TriggerStream ==
"physics_Mistimed":
314 from TrigT1CaloMonitoring.MistimedStreamMonitorAlgorithm
import MistimedStreamMonitorConfig
318 if flags.Input.Format
is Format.BS:
319 from TrigT1CaloByteStream.LVL1CaloRun2ByteStreamConfig
import LVL1CaloRun2ReadBSCfg
323 if flags.Trigger.enableL1CaloPhase1
and flags.Input.Format
is not Format.POOL:
325 from TrigT1CaloMonitoring.EfexMonitorAlgorithm
import EfexMonitoringConfig
327 result.merge(EfexMonitorCfg)
330 EfexMonAlg = result.getEventAlgo(
'EfexMonAlg')
331 from TrigT1CaloMonitoring.EfexMonitorAlgorithm
import EfexMonitoringHistConfig
333 result.merge(EfexMonitorHistCfg)
336 from TrigT1CaloMonitoring.GfexMonitorAlgorithm
import GfexMonitoringConfig
340 from L1CaloFEXSim.L1CaloFEXSimCfg
import L1CaloFEXSimCfg
344 from TrigT1CaloMonitoring.EfexSimMonitorAlgorithm
import EfexSimMonitoringConfig
347 from TrigT1CaloMonitoring.EfexInputMonitorAlgorithm
import EfexInputMonitoringConfig
350 from TrigT1CaloMonitoring.GfexSimMonitorAlgorithm
import GfexSimMonitoringConfig
354 from TrigT1CaloMonitoring.GfexInputMonitorAlgorithm
import GfexInputMonitoringConfig
362 maybeMissingRobs = []
365 from L1CaloFEXByteStream.L1CaloFEXByteStreamConfig
import jFexInputByteStreamToolCfg
368 for module_id
in inputjFexTool.ROBIDs:
369 maybeMissingRobs.append(module_id)
371 decoderTools += [inputjFexTool]
372 from AthenaConfiguration.ComponentFactory
import CompFactory
373 decoderAlg = CompFactory.L1TriggerByteStreamDecoderAlg(name=
"L1TriggerByteStreamDecoder", DecoderTools=[inputjFexTool], MaybeMissingROBs=maybeMissingRobs)
374 result.addEventAlgo(decoderAlg)
376 from L1CaloFEXSim.L1CaloFEXSimCfg
import L1CaloFEXSimCfg
379 from TrigT1CaloMonitoring.JfexInputMonitorAlgorithm
import JfexInputMonitoringConfig
383 from TrigT1CaloMonitoring.JfexSimMonitorAlgorithm
import JfexSimMonitoringConfig
385 result.merge(JfexSimMonitoring)
388 from TrigT1CaloMonitoring.JfexMonitorAlgorithm
import JfexMonitoringConfig
390 result.merge(JfexMonitoring)
393 from TrigT1CaloMonitoring.JetEfficiencyMonitorAlgorithm
import JetEfficiencyMonitoringConfig
396 result.printConfig( withDetails=
True )
401 from TrigT1CaloMonitoring.L1CaloLegacyEDMMonitorAlgorithm
import L1CaloLegacyEDMMonitoringConfig
404 from TrigT1CaloMonitoring.EfexMonitorAlgorithm
import EfexMonitoringConfig
406 result.merge(EfexMonitorCfg)
408 EfexMonAlg = result.getEventAlgo(
'EfexMonAlg')
409 EfexMonAlg.eFexEMTobKeyList = [
'L1_eEMRoI',
'L1_eEMxRoI']
410 EfexMonAlg.eFexTauTobKeyList = [
'L1_eTauRoI',
'L1_eTauxRoI']
411 from TrigT1CaloMonitoring.EfexMonitorAlgorithm
import EfexMonitoringHistConfig
413 result.merge(EfexMonitorHistCfg)
415 from TrigT1CaloMonitoring.GfexMonitorAlgorithm
import GfexMonitoringConfig
417 from TrigT1CaloMonitoring.JfexMonitorAlgorithm
import JfexMonitoringConfig
420 from TrigT1CaloMonitoring.JetEfficiencyMonitorAlgorithm
import JetEfficiencyMonitoringConfig
426 if __name__ ==
'__main__':
427 from AthenaConfiguration.AllConfigFlags
import initConfigFlags
428 from AthenaConfiguration.ComponentFactory
import CompFactory
429 from AthenaMonitoring.DQConfigFlags
import DQDataType
431 flags.DQ.useTrigger =
False
432 flags.DQ.Environment =
"user"
433 flags.DQ.DataType = DQDataType.MC
434 flags.DQ.enableLumiAccess =
False
437 h.defineHistogram(
"x,y;h_myHist",type=
'TH2D',path=
"Shifter/Blah",hanConfig={
"algorithm":
"blah"})
438 h.defineHistogram(
"x,y;h_myHis2t",type=
'TH2D',path=
"Shifter/Blah",hanConfig={
"algorithm":
"blah2"})
439 h.defineHistogram(
"x;anotherHist",type=
'TH1D',path=
"Developer/whatever",hanConfig={
"aaa":2})
440 h.defineTree(
"x,y,z,a,b;myTree",
"x/i:y/i:z/i:a/I:b/I",path=
"Developer/whatever")
443 h.defineDQAlgorithm(
"MyAlgo",
444 hanConfig={
"libname":
"libdqm_summaries.so",
"name":
"Bins_NotEqual_Threshold",
"BinThreshold":
"0."},
445 thresholdConfig={
"NBins":[1,1]})
447 L1CaloMonitorCfgHelper.printHanConfig()