Athena Guidelines
Warning
These guidelines are under development.
These guidelines are intended to complement the C++ coding guidelines with Athena-specific coding conventions.
(Here we are thinking that it would be good to provide AthenaExamples
corresponding to these guidelines and also real world examples in the code.)
Package structure
For now, please see the Athena packages section here for guidance on how to structure Athena packages.
Algorithms
- All Algorithms should inherit from AthReentrantAlgorithm.
- In the case of Conditions Algorithms, the
isReEntrant()
method should be overridden to return false though.virtual bool isReEntrant() const override { return false; }
Passing data between components
- Data should be passed between algorithms by using
WriteHandle
andReadHandle
instances (orWriteCondHandle
andReadCondHandle
instances for conditions information). These handles interact with the appropriateStoreGateSvc
instance. - If A component has a handle (
ToolHandle
,ServiceHandle
) to component B, then data should be passed from A to B explicitly via function arguments and from B to A via function arguments or return values.
EDM
ReadHandleKeys/WriteHandleKeys
- If an Algorithm creates a collection, a
WriteHandle
should always be used to record this collection to StoreGate. The Algorithm should have a correspondingWriteHandleKey
configurable property. - If an Algorithm reads a collection from StoreGate, a
ReadHandle
should always be used. The Algorithm should have a correspondingReadHandleKey
configurable property.
Warning
Objects written to StoreGate should not be modified once the corresponding WriteHandle
has gone out of scope.
In such cases, a copy of the object with the required updates should be made instead. (Exception: See information about "Decorations" for xAOD::Containers below.)
xAOD Basics
(Add information from Attila's talk in SW weekly here.)
- Static variables are part of the versioned main store. They form the variables that define the baseline object and are there for every object of this type.
- Dynamic variables are not in the versioned store. As different flavour of an object can have different additional info. For example different types of calorimeter clusters, electron, muons etc.
- "Decorations" are a type of Dynamic variables that are added, in later stages, to a collection already in the store. Examples include modifying collections read from AOD in Derivations, or adding isolation and truth information to already reconstructed objects .
- During the creation of a collection there is typically no need for the "Decoration" machinery as the collection is not in the store. So a
WriteDecorHandle
should not be used. (It just adds an unnecessary level of complexity by declaring surplus dependencies to the scheduler.) In such a case useSG::AuxElement::Accessor
.
Note
ReadDecorHandle
and WriteDecorHandle
are only needed to aid scheduling in MT jobs.
Handle Rules
Tip
WriteHandle
should always be used to record this collection to StoreGate. The Algorithm/component should have a correspondingWriteHandleKey
configurable property.ReadHandle
should always be used to read a collection from StoreGate. The Algorithm/component should have a correspondingReadHandleKey
configurable property.WriteDecorHandle
must be used if a secondary algorithm (i.e. one which did not create the actual container) applies additional dynamic variables ("Decorations") to a container.WriteDecorHandleKey
configurable properties should be used to createWriteDecorHandle
instances.ReadDecorHandle
should only be used to access dynamic variables applied to a container by a secondary algorithm ("Decorations").ReadDecorHandleKey
configurable properties should be used to createReadDecorHandle
instances.
Warning
WriteDecorHandle
should not be used for additional dynamic variables applied by the same algorithm which created the container, insteadSG::AuxElement::Accessor
should be used (unless they can be accessed via main versioned store interface).ReadDecorHandle
should not be used to access dynamic variables applied by the algorithm which created the container (this includes the case where the decorated object is read from the input file), instead aSG::AuxElement::ConstAccessor
should be used (unless they can be accessed via main versioned store interface).- Prefer
SG::AuxElement::Accessor
overSG::AuxElement::Decorator
unlessWriteDecorHandle
should be used.
Reporting errors
Error Reporting Basics
Athena provides two tools to report on the status of an algorithm or tool: returning a StatusCode
and issuing a message using a MsgStream
. For an AthAlgorithm
or AthAlgTool
this involves the following:
ATH_CHECK( myService.retrieve() );
if ( myService.retrieve().isFailure() ) {
ATH_MSG_ERROR("Could not retrieve myService");
return StatusCode::FAILURE;
}
The MsgStream
should always be used to print messages - never use std::cout
or similar. It is thoroughly demonstrated in AthExHelloWorld
Error Reporting Policy
When reporting the result of an Algorithm/AlgTool there are three StatusCodes
:
(SUCCESS
, RECOVERABLE
, and FAILURE
) and six verbosity levels (VERBOSE
, DEBUG
, INFO
, WARNING
, ERROR
, FATAL
). By default Athena prints out all messages streamed with verbosity levels INFO
and above. To help choosing the correct message level, i.e. for failures during the execute
method of an Algorithm or from an AlgTool method called during the event loop, the following guidelines should be followed:
- if something prevents the Algorithm to do its expected job (for example an input data object is not there or it is empty) but there is no indication that the current event is corrupted
- action: print a
WARNING
and returnStatusCode::SUCCESS
. Such messages will be flagged in production and investigated by a human being leading to a JIRA being filed, so if such warnings are likely to appear frequently the code should be written such that they are avoided, or the message downgraded
- action: print a
- if something is definitely wrong with the current event (e.g. the structure of an input data object looks corrupted)
- action: print an
ERROR
and returnStatusCode::FAILURE
(depending on the Athena configuration this error will be ignored, or will cause athena to go to next event, or will cause the job to terminate)
- action: print an
- if a job configuration problem is discovered
- action: print a
FATAL
and returnStatusCode::FAILURE
. This is the only circumstance in whichFATAL
should be used. Since in most cases these checks can already be done during initialize, the usage ofFATAL
during the event loop should be very rare.
- action: print a
- in general,
INFO
should not be used in the event loop.
In the initialize
step, INFO
messages can be used freely to print out the configuration received by Athena from the Python layer. WARNINGS
can be used to print out potentially contradictory configurations or where the user-supplied configuration was over-ridden for some reason.
DEBUG
messages should be used to assist other developers who are investigating problems later on. This might include (for example) printing out the properties of an object if it reaches a certain state.
Error Handling in Athena and Production Scripts
Athena monitors the status of each top-level algorithm by looking at the StatusCode
the algorithm returns from the initialize
, execute
, and finalize
methods, and by catching any exception thrown from within the algorithm scope. By default if any algorithm throws an exception, Athena will wrap-up and terminate the job immediately. This behaviour can be changed by configuring the ExceptionSvc
. For example, to tell Athena to ignore any error codes returned by the algorithm MyAlg
, add the following to the configuration:
cfg.addService(CompFactory.ExceptionSvc(Catch="LIST", Algorithms=[ "MyAlg=SUCCESS"]))
During the event loop the AthenaEventLoopMgr
will terminate the event loop if an Algorithm returns StatusCode::FAILURE
, and it will skip to the next event (without writing the current event out) if an Algorithm returns StatusCode::RECOVERABLE
. This default behaviour is controlled via the AthenaEventLoopMgr.FailureMode
property:
athena> from AthenaServices.AthenaServicesConf import AthenaEventLoopMgr
athena> help(AthenaEventLoopMgr)
| FailureMode = <member 'FailureMode' of 'AthenaEventLoopMgr' objects>
| Controls behaviour of event loop depending on return code of Algorithms.
| 0: all non-SUCCESSes terminate job.
| 1: RECOVERABLE skips to next event, FAILURE terminates job (DEFAULT).
| 2: RECOVERABLE and FAILURE skip to next event
|
Athena considers all messages issued via the MessageSvc
as informational only: a job will not stop if FATAL is issued. On the other hand production scripts (transforms) parse the output logs looking for FATAL
and ERROR
. Any such message is interpreted as a signal of a failed job. WARNINGS
in the event loop are also flagged but such jobs are not marked as failed.