Tools and tips

Last update: 02 Dec 2020 [History] [Edit]

Browsing and comparing configurations

The configuration stored in ComponentAccumulator can be saved in the file like this:

acc = ComponentAccumulator()
...
# at the end of config file
with open("config.pkl", "wb") as file:
    acc.store(f)

The format of the file is binary however it can be browsed with the confTool.py and iconfTool tools:

> confTool.py -p config.pkl
# or for a more interactive and visual browsing
> iconfTool -i config.pkl

The confTool.py has multiple options to constrain or expand the amount of details in the output (see -h option). For action available in the iconfTool hit the keyword h.

Both tools can be used for comparing the configuration.

> confTool.py --diff old-config.pkl config.pkl

The output will indicate missing as well as different settings.

For comparisons with old configuration the athena option --config-only="old-config.pkl" can be added to Athena command line. With this the job does not actually run but the configuration is saved in the file that can be browsed or compared as above.

Discovering properties of the component

The component properties are also inherited from base classes. A quickest way to discover all of them is by instantiating the python configuration class and list the class description as in the following example:

# in the terminal with atlas s/w set-up
> python
>>> from AthenaConfiguration.ComponentFactory import CompFactory
>>> algClass = CompFactory.HelloAlg # an example algorithm in this case
>>> help(algClass)

This will result in the output like below with the details of all properties enlisted:

Help on class HelloAlg in module GaudiConfig2.Configurables:

class HelloAlg(GaudiConfig2._configurables.Configurable)
 |  HelloAlg(name=None, **kwargs)
 |
 |  Properties
 |  ----------
 |  - ExtraInputs: std::unordered_set<DataObjID,DataObjID_Hasher,std::equal_to<DataObjID>,std::allocator<DataObjID> > ([])
 |     [DataHandleHolderBase<PropertyHolder<CommonMessaging<implements<IAlgorithm,IDataHandleHolder,IProperty,IStateful> > > >]
 |
 |  - ExtraOutputs: std::unordered_set<DataObjID,DataObjID_Hasher,std::equal_to<DataObjID>,std::allocator<DataObjID> > ([])
 |     [DataHandleHolderBase<PropertyHolder<CommonMessaging<implements<IAlgorithm,IDataHandleHolder,IProperty,IStateful> > > >]
 |
 |  - OutputLevel: int (0)
 |    output level [Gaudi::Algorithm]
 |
 |  - Enable: bool (True)
 |    should the algorithm be executed or not [Gaudi::Algorithm]
 |
 |  - ErrorMax: unsigned int (1)
 |    [[deprecated]] max number of errors [Gaudi::Algorithm]
 .....

In the configuration objects (not classes!) can be queried for:

  • properties that are already set with comp._properties that returns dictionary with property name and value,
  • all properties with comp._descriptors returning dictionary with property name and descriptor object holding info about C++ type, default value and semantics,
  • complete component class name/instance name comp.getFullJobOptName() (e.g. MyNameSpace::MyTool/ToolA),
  • short name (without the class name) comp.name
  • component type comp.getGaudiType() that returns one of strings “Algorithm”, “Tool” or “Service”.

Debugging the configuration process

Sometimes it is necessary to interrupt the configuration process and be able to enter interactive mode somewhere deep in the calls stack. The code python module can be used for this.

In place where you intend the configuration process to be interrupted add the following:

import code; code.interact(banner="me debugging >>> ", local=locals())

With this the configuration process will be interrupted in this place and a control given to you. You can inspect local scope variables as needed. With Control-D that session will be ended and configuration process resumed.

Another option could be to use the python debugger pdb. Where you want to abort the configuration, add the following:

import pdb; pdb.set_trace()