ATLAS Offline Software
Loading...
Searching...
No Matches
AthMonitorCfgHelper.py
Go to the documentation of this file.
2# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3#
4
5'''@file AthMonitorCfgHelper.py
6@author C. D. Burton
7@author P. Onyisi
8@date 2019-01-25
9@brief Helper classes for Run 3 monitoring algorithm configuration
10'''
11
12from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
13from AthenaConfiguration.ComponentFactory import CompFactory
14
16 '''
17 This class is for the Run 3-style configuration framework. It is intended to be instantiated once
18 per group of related monitoring algorithms.
19 '''
20 def __init__(self, flags, monName):
21 '''
22 Create the configuration helper. Needs the job flags and the name of the set of
23 monitoring algorithms.
24
25 Arguments:
26 flags -- the configuration flag object
27 monName -- the name you want to assign the family of algorithms
28 '''
29
30 AthSequencer=CompFactory.AthSequencer
31 self.flags = flags
32 self.monName = monName
33 self.monSeq = AthSequencer('AthMonSeq_' + monName)
34 self.monSeq.StopOverride=True
35 self.resobj = ComponentAccumulator()
36 self.resobj.addSequence(self.monSeq)
37 if self.flags.DQ.useTrigger:
38 from .TriggerInterface import TrigDecisionToolCfg
39 self.resobj.merge(TrigDecisionToolCfg(flags))
40
41 def addAlgorithm(self, algClassOrObj, name = None, addFilterTools = [], *args, **kwargs):
42 '''
43 Instantiate/add a monitoring algorithm
44
45 Arguments:
46 algClassOrObj -- the Configurable class object of the algorithm to create, or an instance
47 of the algorithm Configurable. The former is recommended. In the former case,
48 the name argument is required.
49 name -- the name of the algorithm to create. Required when passing a Configurable class object
50 as algClassOrObj. No effect if a Configurable instance is passed.
51 *args, **kwargs -- additional arguments will be forwarded to the Configurable constructor if
52 a Configurable class object is passed. No effect if a Configurable instance
53 is passed.
54
55 Returns:
56 algObj -- an algorithm Configurable object
57 '''
58 from inspect import isclass
59 if isclass(algClassOrObj):
60 if name is None:
61 raise TypeError('addAlgorithm with a class argument requires a name for the algorithm')
62 algObj = algClassOrObj(name, *args, **kwargs)
63 else:
64 algObj = algClassOrObj
65
66 # configure these properties; users really should have no reason to override them
67 algObj.Environment = self.flags.DQ.Environment
68 algObj.DataType = self.flags.DQ.DataType.value
69 if self.flags.DQ.useTrigger:
70 algObj.TrigDecisionTool = self.resobj.getPublicTool("TrigDecisionTool")
71
72 if self.flags.DQ.enableLumiAccess:
73 algObj.EnableLumi = True
74 from LumiBlockComps.LuminosityCondAlgConfig import LuminosityCondAlgCfg
75 self.resobj.merge (LuminosityCondAlgCfg (self.flags))
76 if not self.flags.Input.isMC:
77 from LumiBlockComps.LBDurationCondAlgConfig import LBDurationCondAlgCfg
78 from LumiBlockComps.TrigLiveFractionCondAlgConfig import TrigLiveFractionCondAlgCfg
79 self.resobj.merge (LBDurationCondAlgCfg (self.flags))
80 self.resobj.merge (TrigLiveFractionCondAlgCfg (self.flags))
81 else:
82 algObj.EnableLumi = False
83
84 # add some optional filters?
85 for obj in addFilterTools:
86 # accept either ComponentAccumulators or tools (trusting that user has already merged CA)
87 if isinstance(obj, ComponentAccumulator):
88 filter = self.resobj.popToolsAndMerge(obj)
89 elif hasattr(obj, 'getGaudiType') and obj.getGaudiType() == 'AlgTool':
90 filter = obj
91 else:
92 raise ValueError(f'Object {obj} passed to addFilterTools is not a ComponentAccumulator or an AlgTool')
93 algObj.FilterTools += [filter]
94
95
96 self.resobj.addEventAlgo(algObj, sequenceName=self.monSeq.name)
97 return algObj
98
99 def addGroup(self, alg, name, topPath='', defaultDuration='run'):
100 '''Add a group to an algorithm
101
102 Technically, adding a GenericMonitoringTool instance. The name given here can be
103 used to retrieve the group from within the algorithm when calling the fill()
104 function. Note this is *not* the same thing as the Monitored::Group class. To
105 avoid replication of code, this calls the more general case, getArray with an 1D
106 array of length 1.
107
108 Arguments:
109 alg -- algorithm Configurable object (e.g. one returned from addAlgorithm)
110 name -- name of the group
111 topPath -- directory name in the output ROOT file under which histograms will be
112 produced
113 defaultDuration -- default time between histogram reset for all histograms in
114 group; can be overridden for each specific histogram
115
116 Returns:
117 tool -- a GenericMonitoringTool Configurable object. This can be used to define
118 histograms associated with that group (using defineHistogram).
119 '''
120 if alg is not None and name == alg.getName():
121 raise ValueError(f"Cannot have a monitoring group with the same name as the parent algorithm ({name})")
122 array = self.addArray([1],alg,name,topPath=topPath,defaultDuration=defaultDuration)
123 return array[0]
124
125 def addArray(self, dimensions, alg, baseName, topPath='', defaultDuration='run'):
126 '''Add many groups to an algorithm
127
128 Arguments:
129 dimensions -- list holding the size in each dimension [n1,n2,n3,n4,...]
130 alg -- algorithm Configurable object
131 baseName -- base name of the group. postfixes are added by GMT Array initialize
132 topPath -- directory name in the output ROOT file under which histograms will be
133 produced
134 duration -- default time between histogram reset for all histograms in group
135
136 Returns:
137 tool -- a GenericMonitoringToolArray object. This is used to define histograms
138 associated with each group in the array.
139 '''
140 # Generate the n-dimensional array
141 from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringArray
142 array = GenericMonitoringArray(self.flags, baseName, dimensions)
143
144 acc = getDQTHistSvc(self.flags)
145 self.resobj.merge(acc)
146
147 pathToSet = self.flags.DQ.FileKey+('/%s' % topPath if topPath else '')
148 if self.flags.Output.HISTFileName:
149 pathToSet = '/' + pathToSet
150 array.broadcast('HistPath',pathToSet)
151 array.broadcast('UseCache',True)
152 convention = 'ONLINE' if self.flags.Common.isOnline else 'OFFLINE'
153 array.broadcast('convention', convention)
154 array.broadcast('defaultDuration',defaultDuration)
155 if alg is not None:
156 alg.GMTools += array.toolList()
157 return array
158
159 def result(self):
160 '''
161 Finalize the creation of the set of monitoring algorithms.
162
163 Returns:
164 resobj -- a ComponentAccumulator
165 '''
166 return self.resobj
167
168
169def getDQTHistSvc(flags):
170 '''
171 This function creates a THistSvc - used for the new-style job configuration
172
173 Returns:
174 (result, histsvc) -- a tuple of (ComponentAccumulator, THistSvc Configurable object)
175 '''
176 result = ComponentAccumulator()
177 histsvc = CompFactory.THistSvc()
178 if flags.Output.HISTFileName:
179 histsvc.Output += ["%s DATAFILE='%s' OPT='RECREATE'" % (flags.DQ.FileKey,
180 flags.Output.HISTFileName)]
181 result.addService(histsvc)
182 return result
ClassName: AthSequencer.
addGroup(self, alg, name, topPath='', defaultDuration='run')
addAlgorithm(self, algClassOrObj, name=None, addFilterTools=[], *args, **kwargs)
addArray(self, dimensions, alg, baseName, topPath='', defaultDuration='run')
Definition merge.py:1
HLT::TypeInformation::for_each_type_c< typenameEDMLIST::map, my_functor, my_result<>, my_arg< HLT::TypeInformation::get_cont, CONTAINER > >::type result