17#include <TDataMember.h>
20#include <TEnumConstant.h>
25#include <fairlogger/Logger.h>
26#include <boost/property_tree/ptree.hpp>
27#include <boost/functional/hash.hpp>
43 std::ostringstream out;
49 size_t len =
label.size() - prefix.size() - 5;
55 out <<
"[ " + prov +
" ]";
57 out <<
"\t\t[ " + prov +
" ]";
65 out << pdm.
toString(
"",
false) <<
"\n";
73 return strcmp(dm.GetTrueTypeName(),
"string") == 0;
82 return dm.GetTrueTypeName();
84 return dm.GetFullTypeName();
92 std::function<
void(
const TDataMember*,
int,
int)>&& callback)
94 auto memberlist = cl->GetListOfDataMembers();
95 for (
int i = 0;
i < memberlist->GetEntries(); ++
i) {
96 auto dm = (TDataMember*)memberlist->At(
i);
98 auto isValidComplex = [dm]() {
99 return isString(*dm) || dm->IsEnum();
103 if (dm->Property() & kIsStatic) {
107 if (dm->IsaPointer()) {
108 LOG(warning) <<
"Pointer types not supported in ConfigurableParams: " << dm->GetFullTypeName() <<
" " << dm->GetName();
112 TClass*
c = dm->GetClass();
113 if (!
c || !
c->HasDictionary()) {
114 LOG(warning) <<
"Skipping container parameter '" << dm->GetName() <<
"' of type " << dm->GetTrueTypeName() <<
" - ROOT dictionary not found.";
120 if (!dm->IsBasic() && !isValidComplex()) {
121 LOG(warning) <<
"Generic complex types not supported in ConfigurableParams: " << dm->GetFullTypeName() <<
" " << dm->GetName();
125 const auto dim = dm->GetArrayDim();
128 LOG(warning) <<
"We support at most 1 dimensional arrays in ConfigurableParams: " << dm->GetFullTypeName() <<
" " << dm->GetName();
132 const auto size = (dim == 1) ? dm->GetMaxIndex(dim - 1) : 1;
144 std::stringstream namestream;
145 namestream << dm->GetName();
147 namestream <<
"[" <<
index <<
"]";
149 return namestream.str();
155 auto dt = dm.GetDataType();
161 auto tname = dm.GetFullTypeName();
162 if (strcmp(tname,
"string") == 0 || strcmp(tname,
"std::string") == 0) {
163 return sizeof(std::string);
165 LOG(error) <<
"ENCOUNTERED AN UNSUPPORTED TYPE " << tname <<
"IN A CONFIGURABLE PARAMETER";
176 if (
auto dt = dm.GetDataType()) {
179 if (dt->GetType() == EDataType::kChar_t) {
182 }
else if (dt->GetType() == EDataType::kUChar_t) {
192 const auto enumtype = TEnum::GetEnum(dm.GetTypeName());
193 assert(enumtype !=
nullptr);
194 const auto constantlist = enumtype->GetConstants();
195 assert(constantlist !=
nullptr);
197 for (
int i = 0;
i < constantlist->GetEntries(); ++
i) {
198 const auto e = (TEnumConstant*)(constantlist->At(
i));
200 return std::string(e->GetName());
206 return std::string(
val);
211 return ((std::string*)
pointer)->c_str();
218 LOG(error) <<
"COULD NOT REPRESENT AS STRING: " << dm.GetFullTypeName();
219 return std::string();
224std::vector<ParamDataMember>* _ParamHelper::getDataMembersImpl(std::string
const& mainkey, TClass* cl,
void* obj,
225 std::map<std::string, ConfigurableParam::EParamProvenance>
const* provmap,
size_t globaloffset)
227 std::vector<ParamDataMember>*
members =
new std::vector<ParamDataMember>;
229 auto toDataMember = [&
members, obj, mainkey, provmap, globaloffset](
const TDataMember* dm,
int index,
int size) {
231 char*
pointer = ((
char*)obj) + dm->GetOffset() +
index * TS + globaloffset;
235 std::string prov =
"";
236 auto iter = provmap->find(mainkey +
"." +
name);
237 if (iter != provmap->end()) {
257 switch (dt->GetType()) {
262 return typeid(
unsigned char);
265 return typeid(short);
268 return typeid(
unsigned short);
274 return typeid(
unsigned int);
280 return typeid(
unsigned long);
283 return typeid(float);
286 return typeid(double);
289 return typeid(double);
295 return typeid(
long long);
298 return typeid(
unsigned long long);
306 if (strcmp(tname,
"string") == 0 || strcmp(tname,
"std::string") == 0) {
307 return typeid(std::string);
309 LOG(error) <<
"ENCOUNTERED AN UNSUPPORTED TYPE " << tname <<
"IN A CONFIGURABLE PARAMETER";
310 return typeid(
"ERROR");
315void _ParamHelper::fillKeyValuesImpl(std::string
const& mainkey, TClass* cl,
void* obj, boost::property_tree::ptree*
tree,
316 std::map<std::string, std::pair<std::type_info const&, void*>>* keytostoragemap,
319 boost::property_tree::ptree localtree;
320 using mapped_t = std::pair<std::type_info const&, void*>;
321 auto fillMap = [obj, &mainkey, &localtree, &keytostoragemap, &enumRegistry, globaloffset](
const TDataMember* dm,
int index,
int size) {
323 auto dt = dm->GetDataType();
325 char*
pointer = ((
char*)obj) + dm->GetOffset() + (
index * TS) + globaloffset;
326 const auto key = mainkey +
"." +
name;
330 pointer = ((
char*)obj) + dm->GetOffset() + globaloffset;
332 TClass* containerClass = dm->GetClass();
333 if (!containerClass) {
334 containerClass = TClass::GetClass(dm->GetFullTypeName());
336 if (!containerClass) {
337 LOG(error) <<
"Cannot get TClass for container " << typeName;
340 const std::type_info* tinfo = containerClass->GetTypeInfo();
342 keytostoragemap->insert(std::pair<std::string, mapped_t>(
345 LOG(error) <<
"Cannot get type_info for container " << typeName;
355 enumRegistry->
add(
key, dm);
359 keytostoragemap->insert(std::pair<std::string, mapped_t>(
key, mapped_t(ti,
pointer)));
362 tree->add_child(mainkey, localtree);
367void _ParamHelper::printMembersImpl(std::string
const& mainkey, std::vector<ParamDataMember>
const*
members,
bool showProv,
bool useLogger,
bool withPadding,
bool showHash)
370 _ParamHelper::outputMembersImpl(std::cout, mainkey,
members, showProv, useLogger, withPadding, showHash);
373void _ParamHelper::outputMembersImpl(std::ostream& out, std::string
const& mainkey, std::vector<ParamDataMember>
const*
members,
bool showProv,
bool useLogger,
bool withPadding,
bool showHash)
381 for (
auto& member : *
members) {
382 maxpad = std::max(maxpad, member.name.size() + member.value.size());
387 std::string shash = std::format(
"{:07x}", getHashImpl(mainkey,
members));
388 shash = shash.substr(0, 7);
390 LOG(info) << mainkey <<
" [Hash#" << shash <<
"]";
392 out << mainkey <<
" [Hash#" << shash <<
"]\n";
396 for (
auto& member : *
members) {
398 LOG(info) << member.toString(mainkey, showProv, maxpad);
400 out << member.toString(mainkey, showProv, maxpad) <<
"\n";
405size_t _ParamHelper::getHashImpl(std::string
const& mainkey, std::vector<ParamDataMember>
const*
members)
408 boost::hash_combine(
hash, mainkey);
409 for (
auto& member : *
members) {
410 boost::hash_combine(
hash, member.value);
420 for (
int i = 0;
i < sizeinbytes /
sizeof(
char); ++
i) {
421 if (block1[
i] != block2[
i]) {
430void _ParamHelper::assignmentImpl(std::string
const& mainkey, TClass* cl,
void* to,
void* from,
431 std::map<std::string, ConfigurableParam::EParamProvenance>* provmap,
size_t globaloffset)
433 auto assignifchanged = [to, from, &mainkey, provmap, globaloffset](
const TDataMember* dm,
int index,
int size) {
436 char* pointerto = ((
char*)to) + dm->GetOffset() +
index * TS + globaloffset;
437 char* pointerfrom = ((
char*)from) + dm->GetOffset() +
index * TS + globaloffset;
440 auto updateProv = [&mainkey,
name, provmap]() {
441 auto key = mainkey +
"." +
name;
442 auto iter = provmap->find(
key);
443 if (iter != provmap->end()) {
446 LOG(warn) <<
"KEY " <<
key <<
" NOT FOUND WHILE UPDATING PARAMETER PROVENANCE";
464 std::string&
target = *(std::string*)pointerto;
465 std::string
const&
origin = *(std::string*)pointerfrom;
485void _ParamHelper::syncCCDBandRegistry(
const std::string& mainkey, TClass* cl,
void* to,
void* from,
486 std::map<std::string, ConfigurableParam::EParamProvenance>* provmap,
size_t globaloffset)
488 auto sync = [to, from, &mainkey, provmap, globaloffset](
const TDataMember* dm,
int index,
int size) {
491 char* pointerto = ((
char*)to) + dm->GetOffset() +
index * TS + globaloffset;
492 char* pointerfrom = ((
char*)from) + dm->GetOffset() +
index * TS + globaloffset;
495 auto key = mainkey +
"." +
name;
496 auto proviter = provmap->find(
key);
502 auto updateProv = [&proviter]() {
514 std::string&
target = *(std::string*)pointerto;
515 std::string
const&
origin = *(std::string*)pointerfrom;
535void _ParamHelper::printWarning(std::type_info
const& tinfo)
537 LOG(warning) <<
"Registered parameter class with name " << tinfo.name()
538 <<
" has no ROOT dictionary and will not be available in the configurable parameter system";
header::DataOrigin origin
size_t getSizeOfUnderlyingType(const TDataMember &dm)
void loopOverMembers(TClass *cl, void *obj, std::function< void(const TDataMember *, int, int)> &&callback)
std::string getName(const TDataMember *dm, int index, int size)
std::string asString(TDataMember const &dm, char *pointer)
bool isString(TDataMember const &dm)
std::type_info const & nameToTypeInfo(const char *tname, TDataType const *dt)
std::string getContainerTypeName(TDataMember const &dm)
bounded_vector< int > members
static std::string registeredContainerAsString(const std::string &typeName, const void *source)
static bool areRegisteredContainersEqual(const std::string &typeName, const void *lhs, const void *rhs)
static void registerContainerType(const std::string &key, const std::string &typeName)
static bool isRegisteredContainerType(const std::string &typeName)
static bool assignRegisteredContainer(const std::string &typeName, void *target, const void *source)
static std::string toString(EParamProvenance p)
void add(const std::string &key, const TDataMember *dm)
GLsizei const GLchar *const * string
GLuint const GLchar * name
GLsizei const GLfloat * value
GLuint GLsizei const GLchar * label
GLenum GLenum GLsizei len
bool isContainer(const std::string &typeName)
bool isMemblockDifferent(void const *block1, void const *block2)
std::ostream & operator<<(std::ostream &out, ConfigurableParam const ¶m)
std::string to_string(gsl::span< T, Size > span)
std::string toString(std::string const &prefix, bool showProv, size_t padding=0) const
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))