The components implemented in C++ have possibility to alter their function depending on configurable properties.
In order to define configurable property a following line needs to be added to the class definition (in the .h
file).
private:
...
Gaudi::Property<int> m_conf {this, "Conf", 10, "Changes this and that"};
where:
m_conf
is an attribute that can be used in the same way as the type it is based on (int
here),"Conf"
is the name with which this configuration parameter is visible in python (good to name it similarly to name of the class attribute, i.e. m_conf
here),10
is the default value (i.e. if nothing is set in python the m_conf
will assume this value),Similarly the tools/services should be made configurable
ToolHandle< ToolInterfaceClass > m_myTool {this, "myTool",
"ToolImplementation/ToolName", "Tool for this and that"};
ToolHandleArray< ToolInterfaceClass > m_myTools {this, "myTools",
{}, "Tool for this and that"};
ServiceHandle< ServiceInterface > m_aAvc {this, "aSvc",
"Implementation/Name", "Service that does this and that"};
Meaning of these arguments is similar to the ones mentioned above.
The default value can be left empty. In such case the handle can be tested at runtime and in this way the the optional use of the component (here tool) can be implemented using m_myTool.isEnabled()
method.
(This is a better option than adding additional additional flags like useMyTool
.)
In case when multiple tools are needed the second option should be used.
Other category of configurable properties is related to input & output data. They are declared with Read/Write Handle Keys.
SG::ReadHandleKey<TypeA> m_inputKey{this, "inputKey",
"DefaultValue", "Input for"};
SG::WriteHandleKey<TypeB> m_outputKey{this, "outputKey",
"DefaultValue", "Output for"};
// below the default is empty list of outputs
SG::ReadHandleKeyArray<TypeA> m_inputKeys{this, "inputKeys",
{}, "Input for"};
SG::WriteHandleKeyArray<TypeB> m_outputKeys{this, "outputKeys",
{}, "Output for"};
for which meaning is identical as above.
The set of types that the Gaudi::Property
supports covers most of POD types (integers, floating point numbers, std::string).
Also the std::vector
and std::vector<std::vector<POD>>
of the these types are almost all supported. Python representation of it is the list and nested list correspondingly.
For configurations that are mappings the std::map
can be used of which python counterpart is the dictionary.
The support for a more advanced types can be enabled with additional include:
#include "Gaudi/Parsers/Factory.h"
...
// by default the support for nested vectors of unsigned integers is not there
Gaudi::Property< std::vector<std::vector<unsigned>> > m_prop
{ this, "Name", {}, "doc" };
Be aware that the library containing such a property is bigger.
The C++ type of the property is available in python. It is used to verify the values that are assigned to the properties. For instance when the property is a floating point number a string can not be assigned to it. An attempt to do so cause a configuration error.
Another operation that is performed on properties is unification performed during the ComponentAccumulators merging. Difference in the values is considered an error unless the property is equipped with unification directive (semantics). If it is desired (or at least correct) for the property to be merged an additional argument needs to be supplied in its definition C++. For example if the property is a list and the unification process should result in list with all values merged without a repetitions the following is needed:
Gaudi::Property<std::vector<std::string>> m_pro
{ this, "Prop", {}, "Doc", "OrderedSet<T>"};
The last argument request an appropriate semantics to be used when handling this property. Behaviors for various semantics are defined in AtlasSemantics.py