CbmRoot
Loading...
Searching...
No Matches
CbmConfigBase.h
Go to the documentation of this file.
1/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Oleg Golosov [committer] */
4
5#pragma once
6
7#include "CbmDefs.h"
8
9#include <Logger.h>
10
11#include <TSystem.h>
12
13// Add the define statement teporarily to silence the compiler
14// warnings till the problem is fixed in boost
15#define BOOST_BIND_GLOBAL_PLACEHOLDERS 1
16#include <boost/property_tree/json_parser.hpp>
17
18#include <cassert>
19#include <iostream>
20#include <map>
21#include <regex>
22#include <set>
23
24namespace pt = boost::property_tree;
25
26template<class Config_t, class Obj_t>
28private:
29public:
30 using TagSet_t = std::set<std::string>;
31
32 virtual ~CbmConfigBase() = default;
33
34 static bool Load(Obj_t& obj, const std::string& path)
35 {
36 pt::ptree tree;
37 LoadFromFile(path, tree);
38 if (!Load(obj, tree)) return false;
39 return true;
40 }
41
42 static bool Load(Obj_t& obj, const pt::ptree& tree)
43 {
44 SetLogLevel(tree);
45 auto moduleTree {tree.get_child_optional(Config_t::GetModuleTag())};
46 if (!moduleTree) {
47 LOG(error) << "CbmConfig: module tag not found:" << Config_t::GetModuleTag();
48 return false;
49 }
50 if (!Validate(moduleTree.get())) return false;
51 if (!Config_t::LoadImpl(obj, moduleTree.get())) return false;
52 return true;
53 }
54
55 static void LoadFromFile(const std::string& path, pt::ptree& tree)
56 {
57 std::string absPath = path;
58 if (absPath.at(0) != '/') absPath = gSystem->GetWorkingDirectory() + "/" + path;
59 LOG(info) << "CbmConfig: loading config from file: " << absPath << std::endl;
60 pt::read_json(path, tree);
61 }
62
63 static bool Validate(const pt::ptree& tree)
64 {
65 const auto validationSet {Config_t::GetValidationTags()};
66 TagSet_t treeSet;
67 ParseTree(tree, "", treeSet);
68
69 std::vector<std::string> diff;
70 std::set_difference(treeSet.begin(), treeSet.end(), validationSet.begin(), validationSet.end(),
71 std::inserter(diff, diff.begin()));
72
73 if (!diff.empty()) {
74 LOG(error) << "CbmConfig: Invalid tags: ";
75 for (auto s : diff)
76 std::cout << s << ", ";
77 std::cout << std::endl;
79 return false;
80 }
81 return true;
82 }
83
84 static void ParseTree(const pt::ptree& pt, std::string key, TagSet_t& treeSet)
85 {
86 std::string nkey;
87
88 if (!key.empty()) {
89 nkey = key;
90 if (nkey.back() != '.') nkey += ".";
91 LOG(debug) << "CbmConfig: key: " << key << "\tnkey: " << nkey;
92 }
93
94 if (pt.empty() /* && !pt.data().empty()*/) {
95 if (key.back() == '.') key.pop_back();
96 LOG(debug) << "CbmConfig: Insert: " << key;
97 if (key.find("#") < key.size()) //used for comments
98 return;
99 else
100 treeSet.insert(key);
101 }
102
103 for (auto node : pt) {
104 LOG(debug) << "CbmConfig: Try: " << nkey + node.first;
105 ParseTree(node.second, nkey + node.first, treeSet);
106 }
107 }
108
109 static void PrintAvailableTags()
110 {
111 auto tags = Config_t::GetValidationTags();
112 std::cout << "\nAvailable config tags:\n";
113 for (auto& tag : tags)
114 std::cout << tag << std::endl;
115 }
116
117 static ECbmModuleId stringToECbmModuleId(std::string s)
118 {
119 std::map<std::string, ECbmModuleId> stringToModuleId = {
120 {"cave", ECbmModuleId::kCave}, {"magnet", ECbmModuleId::kMagnet}, {"pipe", ECbmModuleId::kPipe},
121 {"target", ECbmModuleId::kTarget}, {"mvd", ECbmModuleId::kMvd}, {"sts", ECbmModuleId::kSts},
122 {"rich", ECbmModuleId::kRich}, {"much", ECbmModuleId::kMuch}, {"trd", ECbmModuleId::kTrd},
123 {"tof", ECbmModuleId::kTof}, {"psd", ECbmModuleId::kPsd}, {"fsd", ECbmModuleId::kFsd},
124 {"hodo", ECbmModuleId::kHodo}, {"shield", ECbmModuleId::kShield}, {"bmon", ECbmModuleId::kBmon},
125 {"platform", ECbmModuleId::kPlatform}};
126
127 if (stringToModuleId.find(s) == stringToModuleId.end()) {
128 LOG(error) << "CbmConfig: detector subsystem not recognized: " << s;
129 std::cout << "list of available detector subsystems:\n";
130 for (auto& p : stringToModuleId)
131 std::cout << p.first << std::endl;
132 assert(0);
134 }
135 else
136 return stringToModuleId.at(s);
137 }
138
139 static std::string GetStringValue(boost::optional<std::string> opt) { return ParseString(opt.get()); }
140
141 static std::string GetStringValue(pt::ptree tree, std::string key, std::string fallback)
142 {
143 return ParseString(tree.get<std::string>(key, fallback));
144 }
145
146 static std::string ParseString(std::string s)
147 {
148 std::regex rgx("\\$\\{?\\w+\\}?");
149 std::smatch match;
150 while (s.find("$") < s.size()) {
151 std::regex_search(s, match, rgx);
152 std::string varString = match[0];
153 std::string varName = std::regex_replace(varString, std::regex("\\$|\\{|\\}"), "");
154 const char* varValue = gSystem->Getenv(varName.c_str());
155 if (!varValue) varValue = "";
156 s.replace(s.find(varString), varString.size(), varValue);
157 }
158 return s;
159 }
160
161 static void SetLogLevel(const pt::ptree& moduleTree)
162 {
163 auto logScreenLevel = moduleTree.get_optional<std::string>("logScreenLevel");
164 if (logScreenLevel) fair::Logger::SetConsoleSeverity(logScreenLevel.get().c_str());
165 auto logVerbosityLevel = moduleTree.get_optional<std::string>("logVerbosityLevel");
166 if (logVerbosityLevel) fair::Logger::SetVerbosity(logVerbosityLevel.get().c_str());
167 }
168};
ECbmModuleId
Definition CbmDefs.h:39
@ kMvd
Micro-Vertex Detector.
@ kPipe
Beam pipe.
@ kHodo
Hodoscope (for test beam times)
@ kTrd
Transition Radiation Detector.
@ kShield
Beam pipe shielding in MUCH section.
@ kMagnet
Magnet.
@ kTof
Time-of-flight Detector.
@ kNotExist
If not found.
@ kTarget
Target.
@ kPsd
Projectile spectator detector.
@ kSts
Silicon Tracking System.
@ kPlatform
RICH rail platform.
@ kMuch
Muon detection system.
@ kFsd
Forward spectator detector.
@ kRich
Ring-Imaging Cherenkov Detector.
static void LoadFromFile(const std::string &path, pt::ptree &tree)
static std::string GetStringValue(pt::ptree tree, std::string key, std::string fallback)
static void SetLogLevel(const pt::ptree &moduleTree)
static void ParseTree(const pt::ptree &pt, std::string key, TagSet_t &treeSet)
static bool Load(Obj_t &obj, const std::string &path)
static std::string ParseString(std::string s)
std::set< std::string > TagSet_t
static void PrintAvailableTags()
static bool Load(Obj_t &obj, const pt::ptree &tree)
virtual ~CbmConfigBase()=default
static bool Validate(const pt::ptree &tree)
static std::string GetStringValue(boost::optional< std::string > opt)
static ECbmModuleId stringToECbmModuleId(std::string s)