|
| 1 | +# Configurable Parameters |
| 2 | + |
| 3 | +This is a short README for configurable parameters as offered by |
| 4 | +the ConfigurableParameter class. |
| 5 | + |
| 6 | +# Introduction |
| 7 | + |
| 8 | +The ConfigurableParameter class implements the demand |
| 9 | +* to have simple variables (under a compound namespace) be declared as 'knobs' |
| 10 | +of an algorithm in order to be able to change/configure their value without recompilation. |
| 11 | +* to have such declared variables be automatically registered in a parameter database or manager instance. |
| 12 | +* to be able to configure/change the parameter values in a textual way (for instance from the command line) |
| 13 | +* to provide automatic serialization / deserialization techniques (to text files or binary blobs) -- for instance to load from CCDB or to pass along parameter snapshots to other processing stages. |
| 14 | +* to keep track of who changes parameters (provenance tracking). |
| 15 | + |
| 16 | +# Example / HowTo: |
| 17 | + |
| 18 | +Imagine some algorithms `algorithmA` depends on 2 parameters `p1` and `p2` which you want to be able to configure. |
| 19 | + |
| 20 | +You would do two steps: |
| 21 | + 1. Declare a parameter class listing the parameters and their default values. |
| 22 | + ```c++ |
| 23 | + struct ParamA : ConfigurableParamHelper<ParamA> { |
| 24 | + int p1 = 10; |
| 25 | + double p2 = 1.23; |
| 26 | + // boilerplate stuff + make parameters known under key "A" |
| 27 | + O2ParamDef(ParamA, "A"); |
| 28 | + }; |
| 29 | +2. Access and use the parameters in the code. |
| 30 | + ```c++ |
| 31 | + void algorithmA() { |
| 32 | + // get the parameter singleton object |
| 33 | + auto& pa = ParamA::Instance(); |
| 34 | + // access the variables in your code |
| 35 | + doSomething(pa.p1, pa.p2); |
| 36 | + } |
| 37 | + ``` |
| 38 | + |
| 39 | +Thereafter, the parameter `ParamA` is automatically registered in a parameter registry and can be read/influenced/serialized through this. The main influencing functions are implemented as static functions on the `ConfigurableParam` class. For example, the following things will be possible: |
| 40 | +* get a value by string key, addressing a specific parameter: |
| 41 | + ``` |
| 42 | + auto p = ConfigurableParam::getValue<double>("A.p2"); |
| 43 | + ``` |
| 44 | + where the string keys are composed of a primary key and the variable name of the parameter. |
| 45 | +* set/modify a value by a key string |
| 46 | + ``` |
| 47 | + ConfigurableParam::setValue<double>("A.p2", 10); |
| 48 | + ``` |
| 49 | + where the string keys are composed of a primary key and the variable name of the parameter. |
| 50 | + Side note: This API allows to influence values from a string, for instance obtained from command line: |
| 51 | + ``` |
| 52 | + ConfigurableParam::fromString("A.p2=10,OtherParam.a=-1."); |
| 53 | + ``` |
| 54 | + The system will complain if a non-existing string key is used. |
| 55 | + |
| 56 | +* serialize the configuration to a ROOT snapshot or to formats such as JSON or INI |
| 57 | + ``` |
| 58 | + ConfigurableParam::toINI(filename); |
| 59 | + ConfigurableParam::toJSON(filename); // JSON repr. of param registry |
| 60 | + ConfigurableParam::toCCDB(filename); // CCDB snapshot of param registry |
| 61 | + ``` |
| 62 | +* retrieve parameters from CCDB snapshot |
| 63 | + ``` |
| 64 | + ConfigurableParam::fromCCDB(filename); |
| 65 | + ``` |
| 66 | +* **Provenance tracking**: The system can keep track of the origin of values. Typically, few stages of modification can be done: |
| 67 | + - default initialization of parameters from code (CODE) |
| 68 | + - initialization/overwritting from a (CCDB) snapshot file |
| 69 | + - overriding by user during runtime (RT) |
| 70 | +
|
| 71 | + The registry can keep track of who supplied the current (decisive) value for each parameter: CODE, CCDB or RT. If a parameter is not changed it keeps the state of the previous stage. |
| 72 | + |
| 73 | +# Further technical details |
| 74 | +
|
| 75 | +* Parameter classes are **read-only** singleton classes/structs. As long as the user follows the pattern to inherit from `ConfigurableParamHelper<T>` and to use the macro `O2ParamDef()` everything is implemented automatically. |
| 76 | +* We use the `ROOT C++` introspection facility to map the class layout to a textual configuration. Hence ROOT dictionaries are needed for parameter classes. |
| 77 | +* BOOST property trees are used for the mapping to JSON/INI files but this is an internal detail and might change in future. |
| 78 | +
|
| 79 | +# Limitations |
| 80 | +
|
| 81 | +* Parameter classes may only contain simple members! Currently the following types are supported |
| 82 | + * simple pods (for example `double x; char y;`) |
| 83 | + * simple char strings (`char *`) |
| 84 | + * fixed size arrays of pods using the ROOT way to serialize: |
| 85 | + ```c++ |
| 86 | + static constexpr int N=3; //! |
| 87 | + double array[N] = {1, 2, 3}; //[N] -- note the [N] after //!! |
| 88 | + ``` |
| 89 | + * array parameters need to be addressed textual with an index operator: |
| 90 | + ``` |
| 91 | + ConfigurableParam::fromString("ParamA.array[2]=10"); |
| 92 | + ``` |
| 93 | + It is planned to offer more flexible ways to set arrays (see below). |
| 94 | + * there is currently no support for pointer types or objects. Parameter classes may not be nested. |
| 95 | +* At the moment serialization works on the whole paramter registry (on the whole set of parameters). Everything is written to the same file or snapshot. |
| 96 | +
|
| 97 | +# Wish list / planned improvements |
| 98 | +
|
| 99 | +* Offer a more flexible way to set array types (to represent them in strings), for example |
| 100 | + ```c++ |
| 101 | + ConfigurableParam::fromString("ParamA.array = {5, 6, 7}"); |
| 102 | + ``` |
| 103 | +* Offer a better more flexible way to read from CCDB. |
| 104 | + * read from complete snapshots (give single file name) **or** read from different files reciding in paths corresponding to key/namespace. |
| 105 | +* Of a more flexible way to serialize, for example allowing to output configuration to different files. |
| 106 | +* Be able to change the configuration from a text file (next to current possibility from command line) |
| 107 | +* support for few important stl containers (std::array, std::vector) |
| 108 | +* a better way to define stages (CODE, CCDB, RT) and to transition between them; potentially more allowed stages |
| 109 | +* take away more boilerplate: Automatic creation of dictionaries for parameter classes. |
0 commit comments