ATLAS Offline Software
Loading...
Searching...
No Matches
Control/AthenaConfiguration/python/Utils.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3from GaudiKernel.GaudiHandles import GaudiHandle
4from AthenaConfiguration.ComponentFactory import CompFactory
5from AthenaCommon import Constants
6from AthenaCommon.Logging import logging
7import collections
8
9
10def loadDefaultComps(allcomps):
11 """Attempts to load all default components (those that are not actually configured)"""
12 loadedSome = False
13 def __load(comp, prop):
14 descr = comp._descriptors[prop]
15 if descr.default.getType() == "":
16 return
17 try:
18 childComp = CompFactory.getComp(descr.default.getType())(descr.default.getName())
19 comp._properties[prop] = childComp
20 nonlocal loadedSome
21 loadedSome = True
22 except Exception:
23 msg=logging.getLogger('loadDefaultComps')
24 msg.warning("Default component %s can not be loaded", descr.default.typeAndName )
25 pass
26
27 for comp in allcomps:
28 for propName,value in comp._descriptors.items():
29 if propName in comp._properties: continue
30 if isinstance(value.default, GaudiHandle):
31 __load(comp, propName )
32
33 if loadedSome:
34 loadDefaultComps(allcomps)
35
36def exposeHandles(allcomps):
37 """Sets all handle keys explicitly"""
38 def __getDefault(d):
39 if isinstance(d, collections.abc.Sequence):
40 return [el for el in d]
41 else:
42 return d.Path
43
44 for comp in allcomps:
45 for propName, value in comp._descriptors.items():
46 if propName in comp._properties: continue
47 if "HandleKey" in value.cpp_type:
48 comp._properties[propName] = __getDefault(value.default)
49
50def setupLoggingLevels(flags, ca):
51 """Read the Exec.*MessageComponents flags and modify OutputLevel of component(s).
52
53 The specification of components uses the Python `fnmatch` library and resembles UNIX paths.
54 An event algorithm MyAlgo/MyInstance has the following path:
55 MasterSeq/AthAllAlgSeq/AthAlgSeq/MyAlgo/MyInstance
56 A private tool MyTool of name ToolInstance used by that algorithm:
57 MasterSeq/AthAllAlgSeq/AthAlgSeq/MyAlgo/MyInstance/MyTool/ToolInstance
58 A public tool:
59 ToolSvc/MyTool/ToolInstance
60
61 The path specification can take the following forms:
62 '*/ToolInstance' : all tools that have matching instance name
63 '*/MyTool/*' : all instances of type MyTool
64 '*/MyAlgo/MyInstance' : specific algorithm instance
65 '*/MyAlgo/*' : all instances of the specific algorithm class
66 '*/AthAlgSeq/*' : all algorithms of the given sequence
67 'ToolSvc/My*/*' : all public tools with instance name starting with "My"
68
69 The modifications to the OutputLevel are applied in the order ERROR to VERBOSE, i.e.
70 it is possible to set higher verbosities with more specific selections.
71
72 Each setting can be either a string or a list of strings. If the component path contains
73 no '/' it is assumed to be a plain component name. In this case, the OutputLevel is set
74 using the property MessageSvc.setDebug or equivalent. This works also for converters, which
75 do not have any properties.
76 """
77
78 def __tolist(d):
79 return ([d] if d else []) if isinstance(d, str) else d
80
81 for flag_val, level in ((flags.Exec.ErrorMessageComponents, 'ERROR'),
82 (flags.Exec.WarningMessageComponents, 'WARNING'),
83 (flags.Exec.InfoMessageComponents, 'INFO'),
84 (flags.Exec.DebugMessageComponents, 'DEBUG'),
85 (flags.Exec.VerboseMessageComponents, 'VERBOSE')):
86 for c in __tolist(flag_val):
87 if "/" in c:
88 ca.foreach_component(c).OutputLevel = getattr(Constants, level)
89
90 # a plain component name is given
91 else:
92 msgSvc = ca.getService("MessageSvc") # should exist by the time this code runs
93 getattr(msgSvc, f'set{level.title()}').append(c) # e.g. setDebug property