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 = {}
21 SIGNATURES = [
"gJ",
"gLJ",
"gLJRho",
"gXEJWOJ",
"gXEJWOJMHT",
"gXEJWOJMST",
"gTEJWOJ",
"gXENC",
"gTENC",
"gXERHO",
"gTERHO",
"jJ",
"jEM",
"jTAU",
"jXE",
"jTE",
"eTAU",
"eEM"]
28 db = config.Configuration()
29 db.create_db(
"l1calo_gen_phase1.data.xml",[
"daq/schema/dqm.schema.xml",
"daq/sw/dqm-algorithms.data.xml",
"daq/sw/repository.data.xml",
"daq/sw/dqm-default-streams.data.xml"])
32 for confName,conf
in L1CaloMonitorCfgHelper.hanAlgConfigs.items():
35 for histPath,value
in L1CaloMonitorCfgHelper.xmlConfigs.items():
36 if value.get(
"algorithm",
"") == confName:
39 if not algUsed:
continue
42 dqAlgo = db.get_dal(
"DQAlgorithm",conf[
"name"])
46 db.create_obj(
"DQAlgorithm",conf[
"name"])
47 dqAlgo = db.get_dal(
"DQAlgorithm",conf[
"name"])
48 dqAlgo.LibraryName = conf[
"libname"]
49 print(
"Created dqAlgo",conf[
"name"])
51 for par,val
in conf.items():
52 if par==
"thresholds" and val
in L1CaloMonitorCfgHelper.hanThresholdConfigs:
53 for thresh,vals
in L1CaloMonitorCfgHelper.hanThresholdConfigs[val].
items():
54 if thresh
not in dqAlgo.ThresholdsNames:
56 dqAlgo.ThresholdsNames += [thresh]
57 print(
"Added",thresh,
"to",conf[
"name"],
"ThresholdNames")
58 elif par
not in [
"name",
"libname",
"thresholds"]+dqAlgo.ParametersNames:
60 dqAlgo.ParametersNames += [par]
61 print(
"Added",par,
"to",conf[
"name"],
"ParameterNames")
68 db.create_obj(
"DQShape",
"L1CaloShapeDeveloper")
69 db.create_obj(
"DQLayout",
"L1CaloLayoutDeveloper")
70 db.create_obj(
"DQRegion",
"L1CaloRegionDeveloper")
71 dqLayout = db.get_dal(
"DQLayout",
"L1CaloLayoutDeveloper")
72 dqLayout.DefaultChildrenShape = db.get_dal(
"DQShape",
"L1CaloShapeDeveloper")
73 db.update_dal(dqLayout)
74 dqRegion = db.get_dal(
"DQRegion",
"L1CaloRegionDeveloper")
75 dqRegion.Description =
"L1Calo Monitoring Development Folder"
76 dqRegion.Label =
"Developer"
77 dqRegion.DQLayout = dqLayout
78 dqRegion.DQSummaryMaker = db.get_dal(
"DQSummaryMaker",
"WorstCaseSummary")
80 for histPath,value
in L1CaloMonitorCfgHelper.xmlConfigs.items():
81 if "algorithm" not in value.keys():
continue
83 name =
"_".
join(histPath.split(
"/"))
84 db.create_obj(
"DQParameter",name)
85 dqPar = db.get_dal(
"DQParameter",name)
86 dqPar.InputDataSource = [
"Histogramming.l1calo-athenaHLT-Phase1./"+histPath]
87 dqPar.Description = value[
"description"]
89 if value[
"algorithm"]
in L1CaloMonitorCfgHelper.hanAlgConfigs:
90 algConf = L1CaloMonitorCfgHelper.hanAlgConfigs[value[
"algorithm"]]
91 dqPar.DQAlgorithm = db.get_dal(
"DQAlgorithm",algConf[
"name"])
92 for par,val
in algConf.items():
93 if par
in dqPar.DQAlgorithm.ParametersNames:
94 dqPar.Parameters += [f
"{par}={val}"]
95 if "thresholds" in algConf:
96 for thresh,vals
in L1CaloMonitorCfgHelper.hanThresholdConfigs[algConf[
"thresholds"]].
items():
97 dqPar.GreenThresholds += [f
"{thresh}={vals['warning']}"]
98 dqPar.RedThresholds += [f
"{thresh}={vals['error']}"]
100 dqPar.DQAlgorithm = db.get_dal(
"DQAlgorithm",value[
"algorithm"])
102 dqRegion.DQParameters += [dqPar]
105 db.update_dal(dqRegion)
106 db.commit(
"Autogenerated")
111 L1CaloMonitorCfgHelper.createXmls()
112 from contextlib
import redirect_stdout
113 from PathResolver
import PathResolver
115 with open(filename,
'w')
as f:
118 with open(header,
'r')
as fh:
119 for line
in fh: f.write(line)
120 with redirect_stdout(f):
131 def printConf(d,prefix="",currentOutput=""):
132 for key,value
in d.items():
133 if type(value)==dict:
134 print(prefix,key,
"{")
135 newCurrentOutput=
str(currentOutput)
136 if(key==
"dir detail" or key==
"dir Developer"):
137 print(prefix+
" algorithm = GatherData")
138 if key.startswith(
"dir ")
and any([x.startswith(
"hist ")
for x
in value.keys()]):
140 for childKey,childVal
in value.items():
141 if childKey.startswith(
"hist ")
and "output" in childVal:
142 print(prefix+
" output = "+childVal[
"output"])
143 newCurrentOutput =
str(childVal[
"output"])
145 printConf(value,prefix +
" ",newCurrentOutput)
150 if key ==
"output": outputs.add(value)
151 if key !=
"output" or value != currentOutput:
print(prefix,key,
"=",value)
152 if key ==
"algorithm": algorithms.add(value)
156 print(
"dir L1Calo {")
157 printConf(L1CaloMonitorCfgHelper.hanConfigs,
" ")
160 print(
"output top_level {")
161 print(
" output L1Calo {")
166 theDict = outputsDict
167 for p
in o.split(
"/"):
168 if p
not in theDict: theDict[p] = {}
170 def printOutputs(d,prefix=""):
171 for key,value
in d.items():
172 print(prefix,
"output",key,
"{")
173 if key==
"detail" or key==
"Developer":
print(prefix,
" algorithm = L1Calo_AlwaysUndefinedSummary")
174 printOutputs(value,prefix +
" ")
176 printOutputs(outputsDict[
"L1Calo"],
" ")
182 algorithm AnyNonZeroBinIsError {
183 # Use this algo if want error on any non-zero bin content
184 libname = libdqm_summaries.so
185 name = Bins_NotEqual_Threshold
187 thresholds = th_AnyBinIsError
189 algorithm L1Calo_AlwaysUndefinedSummary {
190 libname = libdqm_summaries.so
191 name = AlwaysUndefinedSummary
195 for algName,algProps
in L1CaloMonitorCfgHelper.hanAlgConfigs.items():
196 if algName
not in algorithms:
continue
197 print(f
"algorithm {algName} {{")
198 for propName,propVal
in algProps.items():
199 if propName ==
"thresholds": thresholds.add(propVal)
200 print(f
" {propName} = {propVal}")
204 thresholds th_AnyBinIsError {
211 for threshName,threshProps
in L1CaloMonitorCfgHelper.hanThresholdConfigs.items():
212 if threshName
not in thresholds:
continue
213 print(f
"thresholds {threshName} {{")
214 for parName,parLims
in threshProps.items():
215 print(f
" limits {parName} {{")
216 for limName,limVal
in parLims.items():
217 print(f
" {limName} = {limVal}")
223 def __init__(self, flags, algClassOrObj = None, name = None, *args, **kwargs):
225 Create the configuration helper.
228 flags -- the configuration flag object
229 algClassOrObj -- the name you want to assign the family of algorithms
231 from AthenaMonitoring
import AthMonitorCfgHelper
232 self.
helper = AthMonitorCfgHelper(flags,name)
233 self.
alg = self.
helper.addAlgorithm(algClassOrObj,name,*args, **kwargs)
if algClassOrObj
is not None else None
241 :param name: name of algorithm
242 :param hanConfig: dict of algo properties
243 :param thresholdConfig: dict of thresholds, key = ParName, value = pair of thresholds [warning,error]
250 if thresholdConfig
is not None:
251 hanConfig[
"thresholds"] = f
"{name}Thresholds"
253 for parName,limVals
in thresholdConfig.items():
254 if len(limVals) != 2:
255 raise Exception(
"must specify two limits: warning and error")
256 if parName
not in threshDict: threshDict[parName] = {}
257 threshDict[parName][
"warning"] = limVals[0]
258 threshDict[parName][
"error"] = limVals[1]
261 if str(thresh)==
str(threshDict):
263 hanConfig[
"thresholds"] = threshName
281 hanConfig = dict(hanConfig)
285 if self.
dqEnv==
'online' and any([x.startswith(
"Shifter/")
for x
in paths])
and not path.startswith(
"Shifter/"):
continue
287 self.
defineHistogram(*args,fillGroup=fillGroup,hanConfig=hanConfig,paths=[],path=path,**kwargs)
290 argsCopy =
list(args)
291 if ";" not in args[0]:
292 argsCopy[0] +=
";h_" + argsCopy[0].
replace(
":",
"_")
294 if kwargs.get(
"path",
None)
is None:
296 kwargs[
"path"] =
"Developer/" + self.
alg.name
297 elif kwargs[
"path"][-1] ==
'/':
298 kwargs[
"path"] = kwargs[
"path"][:-1]
300 splitPath = kwargs[
"path"].
split(
"/")
301 if splitPath[0]
not in [
"Shifter",
"Expert",
"Developer"]:
302 raise Exception(
"Path of histogram invalid, does not start with one of the allowed audiences (Shifter,Expert,Developer)")
305 if splitPath[0]==
"Shifter" and self.
dqEnv ==
'tier0':
309 if splitPath[0] !=
"Developer" and splitPath[-1] !=
"detail" and (
"algorithm" not in hanConfig)
and (splitPath[0]+
"/algorithm" not in hanConfig):
311 if "description" not in hanConfig
and splitPath[0]+
"/description" not in hanConfig:
312 raise Exception(
"Must specify a hanConfig for a Shifter or Expert (non-detail) histogram")
314 hanConfig[
"algorithm"] =
"GatherData"
315 elif "algorithm" in hanConfig
and hanConfig[
"algorithm"]
not in self.
hanAlgConfigs and hanConfig[
"algorithm"]
not in [
"All_Bins_Filled",
"Histogram_Effective_Empty",
"Histogram_Empty",
"Histogram_Not_Empty",
"No_OverFlows",
"No_UnderFlows"]:
317 raise Exception(f
'DQ Algorithm {hanConfig["algorithm"]} for histogram {args[0]} not defined. Please use defineDQAlgorithm method to define it')
318 elif splitPath[0]+
"/algorithm" in hanConfig
and hanConfig[splitPath[0]+
"/algorithm"]
not in self.
hanAlgConfigs and hanConfig[splitPath[0]+
"/algorithm"]
not in [
"All_Bins_Filled",
"Histogram_Effective_Empty",
"Histogram_Empty",
"Histogram_Not_Empty",
"No_OverFlows",
"No_UnderFlows"]:
320 raise Exception(f
'{splitPath[0]} DQ Algorithm {hanConfig[splitPath[0]+"/algorithm"]} for histogram {args[0]} not defined. Please use defineDQAlgorithm method to define it')
322 if fillGroup
is None: fillGroup = self.
alg.name +
"_fillGroup"
327 if "merge" not in kwargs
and kwargs.get(
"type",
"") !=
"TEfficiency":
328 kwargs[
"merge"] =
"merge"
330 histName = argsCopy[0].
split(
";")[-1]
333 if splitPath[0] ==
"Expert" and self.
HELPURL!=
"":
334 linkUrl = self.
HELPURL +
"#" +
"".
join(splitPath[1:]+[histName])
335 linkUrl = f
"<a href=\"{linkUrl}\">Help</a>"
336 if "description" not in hanConfig
and "Expert/descripton" not in hanConfig: hanConfig[
"description"] = linkUrl
337 elif "description" in hanConfig: hanConfig[
"description"] +=
" - " + linkUrl
338 else: hanConfig[
"Expert/description"] +=
" - " + linkUrl
341 if splitPath[0] ==
"Expert" or splitPath[0] ==
"Developer":
342 splitPathWithHist = splitPath + [histName]
344 embargo = (
"/".
join(splitPathWithHist)
in L1CaloMonitorCfgHelper.embargoed)
346 if "Expert/description" not in hanConfig: hanConfig[
"description"] =
"<b>EMBARGOED PLOT</b> - " + (hanConfig.get(
"description",
""))
347 else: hanConfig[
"Expert/description"] =
"<b>EMBARGOED PLOT</b> - " + (hanConfig.get(
"Expert/description",
""))
348 if "description" in hanConfig
and hanConfig[
"description"]==
"":
349 del hanConfig[
"description"]
350 if splitPath[0]+
"/description" in hanConfig
and hanConfig[splitPath[0]+
"/description"]==
"":
351 del hanConfig[splitPath[0]+
"/description"]
352 x = L1CaloMonitorCfgHelper.hanConfigs
353 for i,p
in enumerate(splitPathWithHist):
354 key = (
"dir " if i!=len(splitPathWithHist)-1
else "hist ") + p
358 hanConfig[
"output"] =
"/".
join([
"L1Calo"]+[splitPath[0]
if not embargo
else "Developer"]+splitPath[1:])
361 for k,v
in hanConfig.items():
362 if k.startswith(
"Shifter/"):
continue
365 if "algorithm" in myConfig
and myConfig[
"algorithm"]
in self.
hanAlgConfigs:
369 if len(
str(pVal))>0
and str(pVal)[0]==
"\"":
370 myConfig[
"description"] += f
"<br>{pName} : {pVal[1:-1]}"
372 elif splitPath[0] ==
"Shifter":
375 for k,v
in hanConfig.items():
376 if k.startswith(
"Expert/"):
continue
379 L1CaloMonitorCfgHelper.xmlConfigs[
"/".
join([
"L1Calo"]+splitPath+[histName])] = {}
380 L1CaloMonitorCfgHelper.xmlConfigs[
"/".
join([
"L1Calo"]+splitPath+[histName])].update(myConfig)
386 if ";" not in args[0]:
387 raise Exception(
"Must specify a tree name using ';name' suffix")
388 treeName = args[0].
split(
";")[-1]
391 raise Exception(
"Should not have comma in list of branch names and types")
393 if kwargs.get(
"path",
None)
is None:
395 kwargs[
"path"] =
"Developer/" + self.
alg.name
398 splitPath = kwargs[
"path"].
split(
"/")
399 if splitPath[0]
not in [
"Developer"]:
400 raise Exception(
"Path of tree invalid, must be in the audience=Developer directory")
403 if fillGroup
is None: fillGroup = self.
alg.name +
"_fillGroup"
410 histName =
"h_" + treeName +
"_entries"
411 argsCopy =
list(args)
412 argsCopy[0] = argsCopy[0].
replace(
";"+treeName,
";"+histName)
413 kwargsCopy = dict(kwargs)
414 kwargsCopy[
"title"] = f
"Number of Entries in {treeName} TTree" +
";" +
";".
join(kwargsCopy.get(
"title",
"").
split(
";")[1:])
415 kwargsCopy[
"opt"] = [
'kCanRebin',
'kAddBinsDynamically',
'kAlwaysCreate']
416 kwargsCopy[
"merge"] =
"merge"
417 is2d = (kwargsCopy[
"title"].
count(
";")>1)
420 argsCopy[0] = argsCopy[0].
split(
",")[0] +
"," + argsCopy[0].
split(
",")[1] +
";" + argsCopy[0].rsplit(
";",1)[-1]
422 argsCopy[0] = argsCopy[0].
split(
",")[0] +
";" + argsCopy[0].rsplit(
";",1)[-1]
423 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)
424 if not any([x
in self.
dqEnv for x
in [
'tier0',
'online']]):
435 '''Function to call l1calo DQ monitoring algorithms'''
436 from AthenaConfiguration.ComponentAccumulator
import ComponentAccumulator
437 from AthenaConfiguration.Enums
import Format
441 local_logger = logging.getLogger(
'AthenaMonitoringCfg')
442 info = local_logger.info
443 info(
'In LVL1CaloMonitoringConfig')
448 if not flags.Trigger.Online.isPartition:
449 if not flags.DQ.triggerDataAvailable:
452 isData =
not flags.Input.isMC
455 validation=flags.DQ.Steering.LVL1Calo.doValidation
459 if not validation
and isData
and flags.DQ.Environment
not in (
'tier0Raw',
'AOD'):
461 from TrigT1CaloMonitoring.PprMonitorAlgorithm
import PprMonitoringConfig
462 from TrigT1CaloMonitoring.JepJemMonitorAlgorithm
import JepJemMonitoringConfig
465 from AthenaConfiguration.AutoConfigFlags
import GetFileMD
467 inputContainsRun3FormatConfigMetadata = (
"metadata_items" in md
and any((
'TriggerMenuJson' in key)
for key
in md[
"metadata_items"].
keys()))
470 if flags.Input.Format
is not Format.POOL
or inputContainsRun3FormatConfigMetadata:
476 detMask=eformat.helper.DetectorMask(f
'{md.get("detectorMask",[0x0])[0]:032x}')
477 hasCPM = detMask.is_set(eformat.helper.SubDetector.TDAQ_CALO_CLUSTER_PROC_DAQ)
478 hasJEP = detMask.is_set(eformat.helper.SubDetector.TDAQ_CALO_JET_PROC_DAQ)
481 from TrigT1CaloMonitoring.CpmMonitorAlgorithm
import CpmMonitoringConfig
482 from TrigT1CaloMonitoring.CpmSimMonitorAlgorithm
import CpmSimMonitoringConfig
487 from TrigT1CaloMonitoring.JepCmxMonitorAlgorithm
import JepCmxMonitoringConfig
490 from TrigT1CaloMonitoring.OverviewMonitorAlgorithm
import OverviewMonitoringConfig
491 from TrigT1CaloMonitoring.PPMSimBSMonitorAlgorithm
import PPMSimBSMonitoringConfig
497 OverviewMonAlg = result.getEventAlgo(
"OverviewMonAlg")
498 OverviewMonAlg.CPMErrorLocation =
""
499 OverviewMonAlg.CPMMismatchLocation =
""
501 if flags.Input.TriggerStream ==
"physics_Mistimed":
502 from TrigT1CaloMonitoring.MistimedStreamMonitorAlgorithm
import MistimedStreamMonitorConfig
506 if flags.Input.Format
is Format.BS:
507 from TrigT1CaloByteStream.LVL1CaloRun2ByteStreamConfig
import LVL1CaloRun2ReadBSCfg
511 if flags.Trigger.enableL1CaloPhase1
and flags.Input.Format
is not Format.POOL:
514 from L1CaloFEXSim.L1CaloFEXSimCfg
import L1CaloFEXSimCfg
518 if flags.Trigger.L1.doeFex:
519 from TrigT1CaloMonitoring.EfexInputMonitorAlgorithm
import EfexInputMonitoringConfig
523 from TrigT1CaloMonitoring.EfexSimMonitorAlgorithm
import EfexSimMonitoringConfig
527 if flags.Trigger.L1.dogFex:
529 from TrigT1CaloMonitoring.GfexInputMonitorAlgorithm
import GfexInputMonitoringConfig
532 from TrigT1CaloMonitoring.GfexSimMonitorAlgorithm
import GfexSimMonitoringConfig
536 if flags.Trigger.L1.dojFex:
538 from TrigT1CaloMonitoring.JfexInputMonitorAlgorithm
import JfexInputMonitoringConfig
542 from TrigT1CaloMonitoring.JfexSimMonitorAlgorithm
import JfexSimMonitoringConfig
544 result.merge(JfexSimMonitoring)
546 if flags.Trigger.L1.doTopo
and isData:
548 from L1TopoSimulation.L1TopoSimulationConfig
import L1TopoSimulationCfg
549 result.merge(
L1TopoSimulationCfg(flags,readMuCTPI=
True,doMonitoring=
False, useMuonDecoder=
True, writeMuonRoIs =
False))
551 from L1TopoOnlineMonitoring.L1TopoOnlineMonitoringConfig
import Phase1TopoMonitoringCfg
555 if validation
or (isData
and flags.DQ.Environment
not in (
'tier0Raw',
'AOD')):
559 from TrigT1CaloMonitoring.L1CaloLegacyEDMMonitorAlgorithm
import L1CaloLegacyEDMMonitoringConfig
563 if flags.Trigger.L1.doeFex:
564 from TrigT1CaloMonitoring.EfexMonitorAlgorithm
import EfexMonitoringConfig
566 from TrigT1CaloMonitoring.EfexMonitorAlgorithm
import EfexMonitoringHistConfig
570 if flags.Trigger.L1.dogFex:
571 from TrigT1CaloMonitoring.GfexMonitorAlgorithm
import GfexMonitoringConfig
575 if flags.Trigger.L1.dojFex:
576 from TrigT1CaloMonitoring.JfexMonitorAlgorithm
import JfexMonitoringConfig
580 if flags.Trigger.L1.dojFex
or flags.Trigger.L1.dogFex:
581 from TrigT1CaloMonitoring.JetEfficiencyMonitorAlgorithm
import JetEfficiencyMonitoringConfig
584 result.printConfig( withDetails=
True )
588 if __name__ ==
'__main__':
589 from AthenaConfiguration.AllConfigFlags
import initConfigFlags
590 from AthenaConfiguration.ComponentFactory
import CompFactory
591 from AthenaMonitoring.DQConfigFlags
import DQDataType
593 flags.DQ.useTrigger =
False
594 flags.DQ.Environment =
"user"
595 flags.DQ.DataType = DQDataType.MC
596 flags.DQ.enableLumiAccess =
False
599 h.defineHistogram(
"x,y;h_myHist",type=
'TH2D',path=
"Shifter/Blah",hanConfig={
"algorithm":
"blah"})
600 h.defineHistogram(
"x,y;h_myHis2t",type=
'TH2D',path=
"Shifter/Blah",hanConfig={
"algorithm":
"blah2"})
601 h.defineHistogram(
"x;anotherHist",type=
'TH1D',path=
"Developer/whatever",hanConfig={
"aaa":2})
602 h.defineTree(
"x,y,z,a,b;myTree",
"x/i:y/i:z/i:a/I:b/I",path=
"Developer/whatever")
605 h.defineDQAlgorithm(
"MyAlgo",
606 hanConfig={
"libname":
"libdqm_summaries.so",
"name":
"Bins_NotEqual_Threshold",
"BinThreshold":
"0."},
607 thresholdConfig={
"NBins":[1,1]})
609 L1CaloMonitorCfgHelper.printHanConfig()