The Athena settings can be categorized as follows:
Settings 1-3 are treated as main Athena settings are are called flags.
They are defined in
AthenaConfiguration.AllConfigFlags and are further categorized into domains like
The flags are set at the start of the job definition. Then they should be locked for writing and can be used to drive the configuration. The example below illustrates a typical code arrangement.
# main job definition file from AthenaConfiguration.AllConfigFlags import ConfigFlags ConfigFlags.Input.Files = ... ConfigFlags.Domain.flagX= True ConfigFlags.lock() # locking happens here
The driver scripts typically use command line parser(look for getArgumentParser) capable of reading the flag values from the command line.
That is, in the command line you should be able to write
Main flags defining job input
Input.Files are mapped to options
The flags have a default value that can depend on values of other flags (more on that below). However setting the flag value in one of the aforementioned ways makes the flag value independent of other flags and constant.
The flags are passed to functions generating configuration always as a first argument. In the configuration fragment they can be used to drive settings of the component in any imaginable way.
... def funCfg(flags): # ... if flags.Domain.flagX: # some setting that depends on flagX ...
For information flags can also be printed with
The flags are unchangeable in configuration fragments. However there are cases when the same set of components need to be configured with different settings. In such case the configuration fragments should obtain effectively a different set of flags. This is achieved as follows. The flags set should contain a clone for domain/subdomain under an alternative name (see how to do this below). For example:
In the configuration fragment then the rewiring can happen as follows:
def aCfg(flags): if flags.Domain.flagX: # this code depends only on the flag.Domain.FlagX ... def bCfg(flags): x = aCfg(flags) # configure one set of components redirectedFlags = flags.cloneAndReplace("Domain", "DomainAlt") y = aCfg(redirectedFlags) # configure another set of components differently
The simplest flag definition contains the name and the initial/default value.
The nesting depth is not limited. And the type of the flag is not constrained.
The initial value can be replaced by a function. This is done for the flags for which the value depends on another flags value e.g.:
flags.addFlag("Domain.SubDomain.flagX", lambda otherFlags: not otherFlags.AnyDomain.anyFlag )
In the above example the value of the flag
flags.Domains.SubDomain.flagX is simply a logical function of another flag. But it can by any function of other flags or can use other sources of information to derive the value.
Once the flag value is set explicitly the function is not used anymore.
When the main flags (those ConfigFlags defined in AthenaConfiguration.AllConfigFlags) are imported only a few of them are defined. Many other flags are available, they are grouped and are registered and will be provided if any flag in this domain will be needed (for either setting or for obtaining the value of it).
This is done to avoid the loading of flags that are unnecessary to a given workflow.
Registration requires defining a function.
def __detector(): from AthenaConfiguration.DetectorConfigFlags import createDetectorConfigFlags return createDetectorConfigFlags() acf.addFlagsCategory( "Detector", __detector )
In the last line the
Detector is the name of the flags domain and has to agree with the name of flags defined inside of
createDetectorConfigFlags (otherwise automatic loading will miss them). The flag provided by this line are then available as
One caveat in this approach is that the main flags definition file depends on a particular package. Such a dependency can be removed by adding an additional layer of protection. See for an example how the flags defined in other packages are declared in
The flags that are loaded dynamically can have further subsets/subdomains that are loaded dynamically as well.
During the dynamic loading the flag names can be prefixed. That is used in the situation when domain flags (with potentially different values) are present in the set of flags multiple times. The most prominent example are many flags for various tracking cuts that are loaded here and tracking cuts for different HLT signatures. In the first place such flags are defined without domain prefix. The prefix is determined at loading and can be varied as in the example. So defined flags are then typically used in the flags redirection.