ATLAS Offline Software
LVL1CaloMonitoringConfig.py
Go to the documentation of this file.
1 #
2 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 #
4 
6 
7  """
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.
10  """
11 
12 
13 
14  from collections import defaultdict
15  hanConfigs = {} # nested structure as required, keys will be either "dir XXX" or "hist YYY"
16  hanAlgConfigs = {}
17  hanThresholdConfigs = {}
18  xmlConfigs = {} # flat dictionary of histograms that are in the shifter folders, so are used for online monitoring
19  embargoed = [] # list of embargoed dqdm plots
20 
21  SIGNATURES = ["gJ","gLJ","gLJRho","gXEJWOJ","gXEJWOJMHT","gXEJWOJMST","gTEJWOJ","gXENC","gTENC","gXERHO","gTERHO","jJ","jEM","jTAU","jXE","jTE","eTAU","eEM"]
22  HELPURL = "" #"https://codimd.web.cern.ch/s/678H65Tk9" No longer adding a help url
23 
24  @staticmethod
25  def createXmls():
26  # First create the DQAlgorithm config file
27  import config
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"])
30 
31  # first ensure all the algorithms exist
32  for confName,conf in L1CaloMonitorCfgHelper.hanAlgConfigs.items():
33  # only need algorithms for Shifter histograms
34  algUsed = False
35  for histPath,value in L1CaloMonitorCfgHelper.xmlConfigs.items():
36  if value.get("algorithm","") == confName:
37  algUsed = True
38  break
39  if not algUsed: continue
40  updated = False
41  try:
42  dqAlgo = db.get_dal("DQAlgorithm",conf["name"])
43  except RuntimeError:
44  # algorithm doesn't exist, create it ...
45  updated=True
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"])
50  # ensure all parameters appear in ParametersNames, and thresholds in ThresholdsNames
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:
55  updated=True
56  dqAlgo.ThresholdsNames += [thresh]
57  print("Added",thresh,"to",conf["name"],"ThresholdNames")
58  elif par not in ["name","libname","thresholds"]+dqAlgo.ParametersNames:
59  updated=True
60  dqAlgo.ParametersNames += [par]
61  print("Added",par,"to",conf["name"],"ParameterNames")
62  if updated:
63  db.update_dal(dqAlgo)
64 
65 
66  # now create DQParameter object for each histogram with a DQ algorithm
67  # need to have them all in a DQRegion that belongs to a DQLayout
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")
79 
80  for histPath,value in L1CaloMonitorCfgHelper.xmlConfigs.items():
81  if "algorithm" not in value.keys(): continue # only add histograms that have an algorithm
82 
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"]
88 
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']}"]
99  else:
100  dqPar.DQAlgorithm = db.get_dal("DQAlgorithm",value["algorithm"]) # catches cases of e.g. predefined parameterless alg like Histogram_Empty
101 
102  dqRegion.DQParameters += [dqPar]
103  db.update_dal(dqPar)
104 
105  db.update_dal(dqRegion)
106  db.commit("Autogenerated")
107 
108 
109  @staticmethod
110  def printHanConfig(filename="collisions_run.config"):
111  L1CaloMonitorCfgHelper.createXmls()
112  from contextlib import redirect_stdout
113  from PathResolver import PathResolver
114  header = PathResolver.FindCalibFile("TrigT1CaloMonitoring/hanConfig_header.txt")
115  with open(filename,'w') as f:
116  # copy the header if we have one
117  if header != "":
118  with open(header,'r') as fh:
119  for line in fh: f.write(line)
120  with redirect_stdout(f):
121  # Note: common configs (see common dir in DataQualityConfiguration) provides following algorithms by default:
122  # algorithm All_Bins_Filled
123  # algorithm Histogram_Effective_Empty
124  # algorithm Histogram_Empty
125  # algorithm Histogram_Not_Empty
126  # algorithm No_OverFlows
127  # algorithm No_UnderFlows
128 
129  outputs = set()
130  algorithms = set()
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") # define GatherData as default algo for all of these hists
138  if key.startswith("dir ") and any([x.startswith("hist ") for x in value.keys()]):
139  # this is a dir with hists, so specify output as the path .. take from the first hist child
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"])
144  break
145  printConf(value,prefix + " ",newCurrentOutput)
146  print(prefix,"}")
147  else:
148  # save all output paths to add to output block (don't need to print here b.c. specified at dir level
149  # exception is if plot was embargoed!
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)
153 
154 
155  print("#inputs")
156  print("dir L1Calo {")
157  printConf(L1CaloMonitorCfgHelper.hanConfigs," ")
158  print("}")
159  print("#outputs")
160  print("output top_level {")
161  print(" output L1Calo {")
162 
163  # go through outputs set, build a nested dictionary of paths
164  outputsDict = {}
165  for o in outputs:
166  theDict = outputsDict
167  for p in o.split("/"):
168  if p not in theDict: theDict[p] = {}
169  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 + " ")
175  print(prefix,"}")
176  printOutputs(outputsDict["L1Calo"]," ")
177  print(" }")
178  print("}")
179  # include example of adding algorithms and thresholds
180  print("""
181 #algorithms
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
186  BinThreshold = 0.
187  thresholds = th_AnyBinIsError
188 }
189 algorithm L1Calo_AlwaysUndefinedSummary {
190  libname = libdqm_summaries.so
191  name = AlwaysUndefinedSummary
192 }
193 """)
194  thresholds = set()
195  for algName,algProps in L1CaloMonitorCfgHelper.hanAlgConfigs.items():
196  if algName not in algorithms: continue # only print the algorithms that were used
197  print(f"algorithm {algName} {{")
198  for propName,propVal in algProps.items():
199  if propName == "thresholds": thresholds.add(propVal)
200  print(f" {propName} = {propVal}")
201  print(" }")
202  print("""
203 #thresholds
204 thresholds th_AnyBinIsError {
205  limits NBins {
206  warning = 0
207  error = 1
208  }
209 }
210 """)
211  for threshName,threshProps in L1CaloMonitorCfgHelper.hanThresholdConfigs.items():
212  if threshName not in thresholds: continue # only print used thresholds
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}")
218  print(" }")
219  print("}")
220 
221 
222 
223  def __init__(self, flags, algClassOrObj = None, name = None, *args, **kwargs):
224  '''
225  Create the configuration helper.
226 
227  Arguments:
228  flags -- the configuration flag object
229  algClassOrObj -- the name you want to assign the family of algorithms
230  '''
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
234  self.fillGroups = {}
235  self.dqEnv = flags.DQ.Environment # used to decide if should defineTree or not ...
236 
237  def defineDQAlgorithm(self,name,hanConfig,thresholdConfig=None):
238 
239  """
240 
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]
244  :return:
245  """
246 
247  # note: this method will replace any existing alg definition
248 
249  #thresNum = len(self.hanThresholdConfigs)
250  if thresholdConfig is not None:
251  hanConfig["thresholds"] = f"{name}Thresholds"
252  threshDict = {}
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]
259  # see if any existing thresholds are identical, if so we can reuse
260  for threshName,thresh in self.hanThresholdConfigs.items():
261  if str(thresh)==str(threshDict):
262  threshDict = None
263  hanConfig["thresholds"] = threshName
264  break
265  if threshDict is not None: self.hanThresholdConfigs[hanConfig["thresholds"]] = threshDict
266  self.hanAlgConfigs[name] = hanConfig
267 
268  return
269 
270 
271  def defineHistogram(self,*args,fillGroup=None,hanConfig={},paths=[],**kwargs):
272  '''
273 
274  :param path:
275  :param fillGroup:
276  :param args:
277  :param kwargs:
278  :return:
279  '''
280 
281  hanConfig = dict(hanConfig) # create a copy since will modify below (otherwise we end up modifying the default empty dict)
282 
283  if paths != []:
284  for path in paths:
285  if self.dqEnv=='online' and any([x.startswith("Shifter/") for x in paths]) and not path.startswith("Shifter/"): continue # only fill Shifter folder copies online
286  # create a copy of the histogram in each of the extra locations
287  self.defineHistogram(*args,fillGroup=fillGroup,hanConfig=hanConfig,paths=[],path=path,**kwargs)
288  return None
289 
290  argsCopy = list(args) # need to convert tuple to list to convert it
291  if ";" not in args[0]:
292  argsCopy[0] += ";h_" + argsCopy[0].replace(":","_")
293 
294  if kwargs.get("path",None) is None:
295  # put in the Developer path, under the name of the algorithm
296  kwargs["path"] = "Developer/" + self.alg.name
297  elif kwargs["path"][-1] == '/':
298  kwargs["path"] = kwargs["path"][:-1] # strip trailing slash
299  # verify path obeys convention
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)")
303 
304  # don't bother registering Shifter plots in tier0 ... only needed in p1 and user environments
305  if splitPath[0]=="Shifter" and self.dqEnv == 'tier0':
306  return None
307 
308  # require a hanConfig not in Developer or a detail dir
309  if splitPath[0] != "Developer" and splitPath[-1] != "detail" and ("algorithm" not in hanConfig) and (splitPath[0]+"/algorithm" not in hanConfig):
310  # will default to using GatherData as long as there is a description
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")
313  else:
314  hanConfig["algorithm"] = "GatherData" # must have an algo, otherwise wont be valid han config
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"]:
316  # if algorithm specified, must have been defined
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"]:
319  # if algorithm specified, must have been defined
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')
321 
322  if fillGroup is None: fillGroup = self.alg.name + "_fillGroup"
323  if fillGroup not in self.fillGroups:
324  self.fillGroups[fillGroup] = self.helper.addGroup(self.alg,fillGroup,topPath="L1Calo")
325 
326 
327  if "merge" not in kwargs and kwargs.get("type","") !="TEfficiency":
328  kwargs["merge"] = "merge" # ensures we don't get a warning about not specifying merge method
329  out = self.fillGroups[fillGroup].defineHistogram(*argsCopy,**kwargs)
330  histName = argsCopy[0].split(";")[-1]
331 
332  # add help link for all expert plots
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
339 
340  # only add to hanConfig if in Expert or Developer folder
341  if splitPath[0] == "Expert" or splitPath[0] == "Developer":
342  splitPathWithHist = splitPath + [histName]
343  # check if hist is in the embargoed list
344  embargo = ("/".join(splitPathWithHist) in L1CaloMonitorCfgHelper.embargoed)
345  if embargo:
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
355  if key not in x:
356  x[key] = {}
357  x = x[key]
358  hanConfig["output"] = "/".join(["L1Calo"]+[splitPath[0] if not embargo else "Developer"]+splitPath[1:]) #embargoed plots appear in developer folder in DQDM, but come from Expert folder in ROOT file
359  # create a copy of the hanConfig and remove any keys beginning with "Shifter/", which means its a shifter-only config attribute
360  myConfig = {}
361  for k,v in hanConfig.items():
362  if k.startswith("Shifter/"): continue
363  # strip Expert/ prefix if it exists
364  myConfig[str(k).replace("Expert/","")] = v
365  if "algorithm" in myConfig and myConfig["algorithm"] in self.hanAlgConfigs:
366  # if there are any string parameters in the config, add them to the description
367  # need this until WebDisplay shows string parameters
368  for pName,pVal in self.hanAlgConfigs[myConfig["algorithm"]].items():
369  if len(str(pVal))>0 and str(pVal)[0]=="\"":
370  myConfig["description"] += f"<br>{pName} : {pVal[1:-1]}"
371  x.update(myConfig)
372  elif splitPath[0] == "Shifter": # record shifter histograms in another map, for generating xmls
373  # create a copy of the hanConfig and remove any keys beginning with "Expert/", which means its a expert-only config attribute
374  myConfig = {}
375  for k,v in hanConfig.items():
376  if k.startswith("Expert/"): continue
377  # strip Shifter/ prefix if it exists
378  myConfig[str(k).replace("Shifter/","")] = v
379  L1CaloMonitorCfgHelper.xmlConfigs["/".join(["L1Calo"]+splitPath+[histName])] = {}
380  L1CaloMonitorCfgHelper.xmlConfigs["/".join(["L1Calo"]+splitPath+[histName])].update(myConfig) # copy in the config
381 
382  return out
383 
384  def defineTree(self,*args,fillGroup=None,**kwargs):
385 
386  if ";" not in args[0]:
387  raise Exception("Must specify a tree name using ';name' suffix")
388  treeName = args[0].split(";")[-1]
389 
390  if "," in args[1]: # catch a subtle typo that can screw up monitoring
391  raise Exception("Should not have comma in list of branch names and types")
392 
393  if kwargs.get("path",None) is None:
394  # put in the Developer path, under the name of the algorithm
395  kwargs["path"] = "Developer/" + self.alg.name
396 
397  # verify path obeys convention
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")
401 
402 
403  if fillGroup is None: fillGroup = self.alg.name + "_fillGroup"
404  if fillGroup not in self.fillGroups:
405  self.fillGroups[fillGroup] = self.helper.addGroup(self.alg,fillGroup,topPath="L1Calo")
406 
407  # always define a histogram to go with the tree, which will indicate how many entries there are
408  # this also ensures we satisfy the requirement that every fillGroup has an object defined
409  # (in the cases of running online/tier0 the defineTrees are blocked, but we still need a hist then)
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)
418  # take the right number of variables for defining the histogram
419  if is2d:
420  argsCopy[0] = argsCopy[0].split(",")[0] + "," + argsCopy[0].split(",")[1] + ";" + argsCopy[0].rsplit(";",1)[-1]
421  else:
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']]):
425  out = self.fillGroups[fillGroup].defineTree(*args,**kwargs)
426  else:
427  out = None
428  return out
429 
430  def result(self):
431  return self.helper.result()
432 
433 
435  '''Function to call l1calo DQ monitoring algorithms'''
436  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
437  from AthenaConfiguration.Enums import Format
438  import logging
439 
440  # local printing
441  local_logger = logging.getLogger('AthenaMonitoringCfg')
442  info = local_logger.info
443  info('In LVL1CaloMonitoringConfig')
444 
445  result = ComponentAccumulator()
446 
447  # If we're not putting trigger objects in event store, can't monitor them
448  if not flags.Trigger.Online.isPartition:
449  if not flags.DQ.triggerDataAvailable:
450  return result
451 
452  isData = not flags.Input.isMC
453 
454  # check if validation requested
455  validation=flags.DQ.Steering.LVL1Calo.doValidation
456 
457  # monitoring algorithm configs
458  # do not run on MC or RAW->ESD(tier0), or AOD-only
459  if not validation and isData and flags.DQ.Environment not in ('tier0Raw', 'AOD'):
460 
461  from TrigT1CaloMonitoring.PprMonitorAlgorithm import PprMonitoringConfig
462  from TrigT1CaloMonitoring.JepJemMonitorAlgorithm import JepJemMonitoringConfig
463 
464  # Use metadata to check Run3 compatible trigger info is available
465  from AthenaConfiguration.AutoConfigFlags import GetFileMD
466  md = GetFileMD(flags.Input.Files)
467  inputContainsRun3FormatConfigMetadata = ("metadata_items" in md and any(('TriggerMenuJson' in key) for key in md["metadata_items"].keys()))
468  result.merge(PprMonitoringConfig(flags))
469  result.merge(JepJemMonitoringConfig(flags))
470  if flags.Input.Format is not Format.POOL or inputContainsRun3FormatConfigMetadata:
471  # L1 menu available in the POOL file
472 
473  # since the legacy system started getting turned off in 2024, use detMask to determine
474  # which things are included, and therefore need monitoring ...
475  import eformat
476  detMask=eformat.helper.DetectorMask(f'{md.get("detectorMask",[0x0])[0]:032x}') #DetectorMask constructor swallows two 64bit ints
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)
479 
480  if hasCPM:
481  from TrigT1CaloMonitoring.CpmMonitorAlgorithm import CpmMonitoringConfig
482  from TrigT1CaloMonitoring.CpmSimMonitorAlgorithm import CpmSimMonitoringConfig
483  result.merge(CpmMonitoringConfig(flags))
484  result.merge(CpmSimMonitoringConfig(flags))
485 
486  if hasJEP:
487  from TrigT1CaloMonitoring.JepCmxMonitorAlgorithm import JepCmxMonitoringConfig
488  result.merge(JepCmxMonitoringConfig(flags))
489 
490  from TrigT1CaloMonitoring.OverviewMonitorAlgorithm import OverviewMonitoringConfig
491  from TrigT1CaloMonitoring.PPMSimBSMonitorAlgorithm import PPMSimBSMonitoringConfig
492  result.merge(PPMSimBSMonitoringConfig(flags))
493  result.merge(OverviewMonitoringConfig(flags))
494 
495  if not hasCPM:
496  # CPM was disabled for run 480893 onwards, so stop monitoring that part
497  OverviewMonAlg = result.getEventAlgo("OverviewMonAlg")
498  OverviewMonAlg.CPMErrorLocation = ""
499  OverviewMonAlg.CPMMismatchLocation = ""
500 
501  if flags.Input.TriggerStream == "physics_Mistimed":
502  from TrigT1CaloMonitoring.MistimedStreamMonitorAlgorithm import MistimedStreamMonitorConfig
503  result.merge(MistimedStreamMonitorConfig(flags))
504 
505  # For running on bytestream data
506  if flags.Input.Format is Format.BS:
507  from TrigT1CaloByteStream.LVL1CaloRun2ByteStreamConfig import LVL1CaloRun2ReadBSCfg
508  result.merge(LVL1CaloRun2ReadBSCfg(flags))
509 
510  # Phase 1 monitoring of inputs and sim-vs-hw
511  if flags.Trigger.enableL1CaloPhase1 and flags.Input.Format is not Format.POOL:
512 
513  # run the L1Calo simulation (causes conflicts with DAOD)
514  from L1CaloFEXSim.L1CaloFEXSimCfg import L1CaloFEXSimCfg
515  result.merge(L1CaloFEXSimCfg(flags))
516 
517  #efex monitoring
518  if flags.Trigger.L1.doeFex:
519  from TrigT1CaloMonitoring.EfexInputMonitorAlgorithm import EfexInputMonitoringConfig
520  result.merge(EfexInputMonitoringConfig(flags))
521 
522  # monitoring of simulation vs hardware
523  from TrigT1CaloMonitoring.EfexSimMonitorAlgorithm import EfexSimMonitoringConfig
524  result.merge(EfexSimMonitoringConfig(flags))
525 
526  #gfex monitoring
527  if flags.Trigger.L1.dogFex:
528  #gfex input monitoring
529  from TrigT1CaloMonitoring.GfexInputMonitorAlgorithm import GfexInputMonitoringConfig
530  result.merge(GfexInputMonitoringConfig(flags))
531 
532  from TrigT1CaloMonitoring.GfexSimMonitorAlgorithm import GfexSimMonitoringConfig
533  result.merge(GfexSimMonitoringConfig(flags))
534 
535  #jfex monitoring
536  if flags.Trigger.L1.dojFex:
537  #jfex monitoring for input data
538  from TrigT1CaloMonitoring.JfexInputMonitorAlgorithm import JfexInputMonitoringConfig
539  result.merge(JfexInputMonitoringConfig(flags))
540 
541  #jfex monitoring for Data Vs Simulation
542  from TrigT1CaloMonitoring.JfexSimMonitorAlgorithm import JfexSimMonitoringConfig
543  JfexSimMonitoring = JfexSimMonitoringConfig(flags)
544  result.merge(JfexSimMonitoring)
545 
546  if flags.Trigger.L1.doTopo and isData:
547  #L1TopoSimulation (with monitoring Off to avoid clash with next call)
548  from L1TopoSimulation.L1TopoSimulationConfig import L1TopoSimulationCfg
549  result.merge(L1TopoSimulationCfg(flags,readMuCTPI=True,doMonitoring=False, useMuonDecoder=True, writeMuonRoIs = False))
550  #L1TopoOnlineMonitoring specific for L1Calo DQPlots
551  from L1TopoOnlineMonitoring.L1TopoOnlineMonitoringConfig import Phase1TopoMonitoringCfg
552  result.merge(Phase1TopoMonitoringCfg(flags))
553 
554  # run FEX output monitoring if doing validation or running on data not @ tier0 or on AOD
555  if validation or (isData and flags.DQ.Environment not in ('tier0Raw', 'AOD')):
556 
557  if validation:
558  # only run this monitoring if doing validation
559  from TrigT1CaloMonitoring.L1CaloLegacyEDMMonitorAlgorithm import L1CaloLegacyEDMMonitoringConfig
560  result.merge(L1CaloLegacyEDMMonitoringConfig(flags))
561 
562  #efex monitoring
563  if flags.Trigger.L1.doeFex:
564  from TrigT1CaloMonitoring.EfexMonitorAlgorithm import EfexMonitoringConfig
565  result.merge(EfexMonitoringConfig(flags))
566  from TrigT1CaloMonitoring.EfexMonitorAlgorithm import EfexMonitoringHistConfig
567  result.merge(EfexMonitoringHistConfig(flags,result.getEventAlgo('EfexMonAlg')))
568 
569  #gfex monitoring
570  if flags.Trigger.L1.dogFex:
571  from TrigT1CaloMonitoring.GfexMonitorAlgorithm import GfexMonitoringConfig
572  result.merge(GfexMonitoringConfig(flags))
573 
574  #jfex monitoring
575  if flags.Trigger.L1.dojFex:
576  from TrigT1CaloMonitoring.JfexMonitorAlgorithm import JfexMonitoringConfig
577  result.merge(JfexMonitoringConfig(flags))
578 
579  # jet efficiency monitoring -- needs either gfex or jfex to be worth scheduling
580  if flags.Trigger.L1.dojFex or flags.Trigger.L1.dogFex:
581  from TrigT1CaloMonitoring.JetEfficiencyMonitorAlgorithm import JetEfficiencyMonitoringConfig
582  result.merge(JetEfficiencyMonitoringConfig(flags))
583 
584  result.printConfig( withDetails= True )
585 
586  return result
587 
588 if __name__ == '__main__':
589  from AthenaConfiguration.AllConfigFlags import initConfigFlags
590  from AthenaConfiguration.ComponentFactory import CompFactory
591  from AthenaMonitoring.DQConfigFlags import DQDataType
592  flags = initConfigFlags()
593  flags.DQ.useTrigger = False
594  flags.DQ.Environment = "user"
595  flags.DQ.DataType = DQDataType.MC
596  flags.DQ.enableLumiAccess = False
597  flags.lock()
598  h = L1CaloMonitorCfgHelper(flags,CompFactory.JfexSimMonitorAlgorithm,"MyAlg")
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")
603 
604  # example of an algorithm requiring all bins to be empty
605  h.defineDQAlgorithm("MyAlgo",
606  hanConfig={"libname":"libdqm_summaries.so","name":"Bins_NotEqual_Threshold","BinThreshold":"0."},
607  thresholdConfig={"NBins":[1,1]}) # first number if warning threshold, second is error threshold
608 
609  L1CaloMonitorCfgHelper.printHanConfig()
python.AutoConfigFlags.GetFileMD
def GetFileMD(filenames, allowEmpty=True, maxLevel='peeker')
Definition: AutoConfigFlags.py:65
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
EfexMonitorAlgorithm.EfexMonitoringHistConfig
def EfexMonitoringHistConfig(flags, eFexAlg)
Definition: EfexMonitorAlgorithm.py:24
PPMSimBSMonitorAlgorithm.PPMSimBSMonitoringConfig
def PPMSimBSMonitoringConfig(flags)
Definition: PPMSimBSMonitorAlgorithm.py:7
PathResolver::FindCalibFile
static std::string FindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.h:63
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.hanThresholdConfigs
hanThresholdConfigs
Definition: LVL1CaloMonitoringConfig.py:17
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.defineDQAlgorithm
def defineDQAlgorithm(self, name, hanConfig, thresholdConfig=None)
Definition: LVL1CaloMonitoringConfig.py:237
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.dqEnv
dqEnv
Definition: LVL1CaloMonitoringConfig.py:235
EfexSimMonitorAlgorithm.EfexSimMonitoringConfig
def EfexSimMonitoringConfig(flags)
Definition: EfexSimMonitorAlgorithm.py:4
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.defineHistogram
def defineHistogram(self, *args, fillGroup=None, hanConfig={}, paths=[], **kwargs)
Definition: LVL1CaloMonitoringConfig.py:271
GfexSimMonitorAlgorithm.GfexSimMonitoringConfig
def GfexSimMonitoringConfig(flags, UseOfflineCopy=True)
Definition: GfexSimMonitorAlgorithm.py:4
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.createXmls
def createXmls()
Definition: LVL1CaloMonitoringConfig.py:25
LVL1CaloRun2ByteStreamConfig.LVL1CaloRun2ReadBSCfg
def LVL1CaloRun2ReadBSCfg(flags, forRoIBResultToxAOD=False)
Definition: LVL1CaloRun2ByteStreamConfig.py:121
XMLtoHeader.count
count
Definition: XMLtoHeader.py:84
CpmSimMonitorAlgorithm.CpmSimMonitoringConfig
def CpmSimMonitoringConfig(inputFlags)
Definition: CpmSimMonitorAlgorithm.py:4
L1TopoSimulationConfig.L1TopoSimulationCfg
def L1TopoSimulationCfg(flags, doMonitoring=True, readMuCTPI=False, name="L1TopoSimulation", deactivateL1TopoMuons=False, useMuonRoIs=False, useMuonDecoder=False, writeMuonRoIs=True)
Definition: L1TopoSimulationConfig.py:46
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.fillGroups
fillGroups
Definition: LVL1CaloMonitoringConfig.py:234
EfexInputMonitorAlgorithm.EfexInputMonitoringConfig
def EfexInputMonitoringConfig(flags)
Definition: EfexInputMonitorAlgorithm.py:44
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.printHanConfig
def printHanConfig(filename="collisions_run.config")
Definition: LVL1CaloMonitoringConfig.py:110
L1CaloLegacyEDMMonitorAlgorithm.L1CaloLegacyEDMMonitoringConfig
def L1CaloLegacyEDMMonitoringConfig(inputFlags)
Definition: L1CaloLegacyEDMMonitorAlgorithm.py:5
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.__init__
def __init__(self, flags, algClassOrObj=None, name=None, *args, **kwargs)
Definition: LVL1CaloMonitoringConfig.py:223
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper
Definition: LVL1CaloMonitoringConfig.py:5
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
GfexInputMonitorAlgorithm.GfexInputMonitoringConfig
def GfexInputMonitoringConfig(flags)
Definition: GfexInputMonitorAlgorithm.py:4
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
PprMonitorAlgorithm.PprMonitoringConfig
def PprMonitoringConfig(inputFlags)
Definition: PprMonitorAlgorithm.py:5
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.helper
helper
Definition: LVL1CaloMonitoringConfig.py:232
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.HELPURL
HELPURL
Definition: LVL1CaloMonitoringConfig.py:22
LVL1CaloMonitoringConfig.LVL1CaloMonitoringConfig
def LVL1CaloMonitoringConfig(flags)
Definition: LVL1CaloMonitoringConfig.py:434
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:71
GfexMonitorAlgorithm.GfexMonitoringConfig
def GfexMonitoringConfig(flags)
Definition: GfexMonitorAlgorithm.py:4
L1TopoOnlineMonitoringConfig.Phase1TopoMonitoringCfg
def Phase1TopoMonitoringCfg(flags)
Definition: L1TopoOnlineMonitoringConfig.py:66
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.alg
alg
Definition: LVL1CaloMonitoringConfig.py:233
JepCmxMonitorAlgorithm.JepCmxMonitoringConfig
def JepCmxMonitoringConfig(inputFlags)
Definition: JepCmxMonitorAlgorithm.py:4
MistimedStreamMonitorAlgorithm.MistimedStreamMonitorConfig
def MistimedStreamMonitorConfig(flags, Legacy, PhaseI)
Definition: MistimedStreamMonitorAlgorithm.py:6
Trk::open
@ open
Definition: BinningType.h:40
LVL1CaloMonitoringConfig.type
type
Definition: LVL1CaloMonitoringConfig.py:599
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
JfexSimMonitorAlgorithm.JfexSimMonitoringConfig
def JfexSimMonitoringConfig(flags)
Definition: JfexSimMonitorAlgorithm.py:4
pickleTool.object
object
Definition: pickleTool.py:29
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.result
def result(self)
Definition: LVL1CaloMonitoringConfig.py:430
JfexInputMonitorAlgorithm.JfexInputMonitoringConfig
def JfexInputMonitoringConfig(flags)
Definition: JfexInputMonitorAlgorithm.py:4
EfexMonitorAlgorithm.EfexMonitoringConfig
def EfexMonitoringConfig(inputFlags)
Definition: EfexMonitorAlgorithm.py:4
JetEfficiencyMonitorAlgorithm.JetEfficiencyMonitoringConfig
def JetEfficiencyMonitoringConfig(flags)
Definition: JetEfficiencyMonitorAlgorithm.py:4
CpmMonitorAlgorithm.CpmMonitoringConfig
def CpmMonitoringConfig(inputFlags)
Definition: CpmMonitorAlgorithm.py:4
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.hanAlgConfigs
hanAlgConfigs
Definition: LVL1CaloMonitoringConfig.py:16
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
JepJemMonitorAlgorithm.JepJemMonitoringConfig
def JepJemMonitoringConfig(inputFlags)
Definition: JepJemMonitorAlgorithm.py:4
L1CaloFEXSimCfg
Definition: L1CaloFEXSimCfg.py:1
LVL1CaloMonitoringConfig.L1CaloMonitorCfgHelper.defineTree
def defineTree(self, *args, fillGroup=None, **kwargs)
Definition: LVL1CaloMonitoringConfig.py:384
JfexMonitorAlgorithm.JfexMonitoringConfig
def JfexMonitoringConfig(flags)
Definition: JfexMonitorAlgorithm.py:4
OverviewMonitorAlgorithm.OverviewMonitoringConfig
def OverviewMonitoringConfig(inputFlags)
Definition: OverviewMonitorAlgorithm.py:4