Skip to content

Commit 1573020

Browse files
committed
Provenance tracking of parameters
Introducing provenance tracking of parameters which allows to query who gave the decisive modification/setting of the value. (If CCDB does not change default value it will stay default). For the moment 3 categories: default code, CCDB, runtime (such as command line) Example output: ``` mCUTGAM : 100 [ CCDB ] mCUTELE : 1 [ CODE ] mCUTNEU : -100 [ RT ] mCUTHAD : 0.001 [ CODE ] ``` This will allow to see which parameters have changed by whom and the mechanism can be easily extented.
1 parent a4305a7 commit 1573020

File tree

4 files changed

+180
-70
lines changed

4 files changed

+180
-70
lines changed

Common/SimConfig/include/SimConfig/ConfigurableParam.h

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,21 @@ namespace conf
2929
//
3030
// A configurable parameter is a simple class, defining
3131
// a few (pod) properties/members which are registered
32-
// in a global (boost) property tree.
32+
// in a global (boost) property tree / structure.
3333
//
3434
// The features that we provide here are:
35-
// a) Automatic translation from C++ data description to INI/JSON/XML
35+
// *) Automatic translation from C++ data description to INI/JSON/XML
3636
// format via ROOT introspection and boost property trees and
3737
// the possibility to readably save the configuration
38-
// b) Automatic integration of sub-classes into a common configuration
39-
// c) Be able to query properties from high level interfaces (just knowing
40-
// d) Be able to set properties from high-level interfaces (and modifying the underlying
38+
// *) Serialization/Deserialization into ROOT binary blobs (for the purpose
39+
// of writing/retrieving parameters from CCDB)
40+
// *) Automatic integration of sub-classes into a common configuration
41+
// *) Be able to query properties from high level interfaces (just knowing
42+
// *) Be able to set properties from high-level interfaces (and modifying the underlying
4143
// C++ object)
42-
// e) Automatic ability to modify parameters from the command-line
44+
// *) Automatic ability to modify parameters from the command-line
45+
// *) Keeping track of the provenance of individual parameter values; The user is able
46+
// to see whether is parameter is defaulted-code-value/coming-from-CCDB/coming-from-comandline
4347
//
4448
// Note that concrete parameter sub-classes **must** be implemented
4549
// by inheriting from ConfigurableParamHelper and not from this class.
@@ -79,11 +83,23 @@ namespace conf
7983
class ConfigurableParam
8084
{
8185
public:
86+
enum EParamProvenance {
87+
kCODE /* from default code initialization */,
88+
kCCDB /* overwritten from CCDB */,
89+
kRT /* changed during runtime via API call setValue (for example command line) */
90+
/* can add more modes here */
91+
};
92+
static std::string toString(EParamProvenance p)
93+
{
94+
static std::array<std::string, 3> names = { "CODE", "CCDB", "RT" };
95+
return names[(int)p];
96+
}
97+
8298
//
8399
virtual std::string getName() const = 0; // print the name of the configurable Parameter
84100

85-
// print the current keys and values to screen
86-
virtual void printKeyValues() = 0;
101+
// print the current keys and values to screen (optionally with provenance information)
102+
virtual void printKeyValues(bool showprov = true) const = 0;
87103

88104
static void printAllRegisteredParamNames();
89105
static void printAllKeyValuePairs();
@@ -107,7 +123,10 @@ class ConfigurableParam
107123
auto key = mainkey + "." + subkey;
108124
if (sPtree->get_optional<std::string>(key).is_initialized()) {
109125
sPtree->put(key, x);
110-
updateThroughStorageMap(mainkey, subkey, typeid(T), (void*)&x);
126+
auto changed = updateThroughStorageMap(mainkey, subkey, typeid(T), (void*)&x);
127+
if (changed) {
128+
sValueProvenanceMap->find(key)->second = kRT; // set to runtime
129+
}
111130
}
112131
}
113132

@@ -117,7 +136,10 @@ class ConfigurableParam
117136
{
118137
if (sPtree->get_optional<std::string>(key).is_initialized()) {
119138
sPtree->put(key, valuestring);
120-
updateThroughStorageMapWithConversion(key, valuestring);
139+
auto changed = updateThroughStorageMapWithConversion(key, valuestring);
140+
if (changed) {
141+
sValueProvenanceMap->find(key)->second = kRT; // set to runtime
142+
}
121143
}
122144
}
123145

@@ -144,9 +166,9 @@ class ConfigurableParam
144166
// registering the concrete parameters
145167
ConfigurableParam();
146168

147-
static void updatePropertyTree();
148-
static void updateThroughStorageMap(std::string, std::string, std::type_info const&, void*);
149-
static void updateThroughStorageMapWithConversion(std::string, std::string);
169+
static void initPropertyTree();
170+
static bool updateThroughStorageMap(std::string, std::string, std::type_info const&, void*);
171+
static bool updateThroughStorageMapWithConversion(std::string, std::string);
150172

151173
virtual ~ConfigurableParam() = default;
152174

@@ -157,6 +179,9 @@ class ConfigurableParam
157179
// (internal use to easily sync updates, this is ok since parameter classes are singletons)
158180
static std::map<std::string, std::pair<int, void*>>* sKeyToStorageMap;
159181

182+
// keep track of provenance of parameters and values
183+
static std::map<std::string, ConfigurableParam::EParamProvenance>* sValueProvenanceMap;
184+
160185
void setRegisterMode(bool b) { sRegisterMode = b; }
161186

162187
private:
@@ -174,7 +199,7 @@ class ConfigurableParam
174199
// a helper macro for boilerplate code in parameter classes
175200
#define O2ParamDef(classname, key) \
176201
public: \
177-
classname(TRootIOCtor *) {} \
202+
classname(TRootIOCtor*) {} \
178203
private: \
179204
static constexpr char const* const sKey = key; \
180205
static classname sInstance; \

Common/SimConfig/include/SimConfig/ConfigurableParamHelper.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,22 @@ namespace o2
2424
namespace conf
2525
{
2626

27-
// just a (non-templated) Helper with exclusively private functions
27+
// just a (non-templated) helper with exclusively private functions
2828
// used by ConfigurableParamHelper
2929
class _ParamHelper
3030
{
3131
private:
32-
static void printParametersImpl(TClass* cl, void*);
32+
static void printParametersImpl(std::string mainkey, TClass* cl, void*,
33+
std::map<std::string, ConfigurableParam::EParamProvenance> const* provmap);
3334

3435
static void fillKeyValuesImpl(std::string mainkey, TClass* cl, void*, boost::property_tree::ptree*,
3536
std::map<std::string, std::pair<int, void*>>*);
3637

3738
static void printWarning(std::type_info const&);
3839

40+
static void assignmentImpl(std::string mainkey, TClass* cl, void* to, void* from,
41+
std::map<std::string, ConfigurableParam::EParamProvenance>* provmap);
42+
3943
template <typename P>
4044
friend class ConfigurableParamHelper;
4145
};
@@ -57,7 +61,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
5761
}
5862

5963
// one of the key methods, using introspection to print itself
60-
void printKeyValues() final
64+
void printKeyValues(bool showprov) const final
6165
{
6266
// just a helper line to make sure P::sInstance is looked-up
6367
// and that compiler complains about missing static sInstance of type P
@@ -71,9 +75,10 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
7175
_ParamHelper::printWarning(typeid(P));
7276
return;
7377
}
74-
_ParamHelper::printParametersImpl(cl, (void*)this);
78+
_ParamHelper::printParametersImpl(getName(), cl, (void*)this, showprov ? sValueProvenanceMap : nullptr);
7579
}
7680

81+
// fills the data structures with the initial default values
7782
void putKeyValues(boost::property_tree::ptree* tree) final
7883
{
7984
auto cl = TClass::GetClass(typeid(P));
@@ -92,9 +97,8 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
9297
P* readback = nullptr;
9398
file->GetObject(getName().c_str(), readback);
9499
if (readback != nullptr) {
95-
// ATTENTION: override existing singleton object
96-
// It would be better to have a way of reading INTO an existing object
97-
std::memcpy((void*)this, readback, sizeof(P));
100+
_ParamHelper::assignmentImpl(getName(), TClass::GetClass(typeid(P)), (void*)this, (void*)readback,
101+
sValueProvenanceMap);
98102
delete readback;
99103
}
100104
setRegisterMode(true);

0 commit comments

Comments
 (0)