11 #include <analysis/VariableManager/Manager.h>
12 #include <analysis/dataobjects/Particle.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/utilities/Conversion.h>
16 #include <framework/utilities/GeneralCut.h>
18 #include <boost/algorithm/string.hpp>
26 Variable::Manager::~Manager() =
default;
37 std::set<std::string> aliasesSeen;
38 for (
auto aliasIter = m_alias.find(name); aliasIter != m_alias.end(); aliasIter = m_alias.find(name)) {
39 const auto [it, added] = aliasesSeen.insert(name);
41 B2FATAL(
"Encountered a loop in the alias definitions between the aliases "
42 << boost::algorithm::join(aliasesSeen,
", "));
44 name = aliasIter->second;
46 auto mapIter = m_variables.find(name);
47 if (mapIter == m_variables.end()) {
48 if (!createVariable(name))
return nullptr;
49 mapIter = m_variables.find(name);
50 if (mapIter == m_variables.end())
return nullptr;
52 return mapIter->second.get();
58 std::vector<const Variable::Manager::Var*> variable_pointers;
59 for (
auto& variable : variables) {
60 const Var* x = getVariable(variable);
62 B2WARNING(
"Couldn't find variable " << variable <<
" via the Variable::Manager. Check the name!");
64 variable_pointers.push_back(x);
66 return variable_pointers;
74 assertValidName(alias);
76 if (m_alias.find(alias) != m_alias.end()) {
77 if (variable == m_alias[alias]) {
return true; }
78 B2WARNING(
"An alias with the name '" << alias <<
"' exists and is set to '" << m_alias[alias] <<
"', setting it to '" << variable <<
79 "'. Be aware: only the last alias defined before processing the events will be used!");
80 m_alias[alias] = variable;
84 if (m_variables.find(alias) != m_variables.end()) {
85 B2ERROR(
"Variable with the name '" << alias <<
"' exists already, cannot add it as an alias!");
89 m_alias.insert(std::make_pair(alias, variable));
96 long unsigned int longest_alias_size = 0;
97 for (
const auto& a : m_alias) {
98 if (a.first.length() > longest_alias_size) {
99 longest_alias_size = a.first.length();
102 B2INFO(
"=====================================");
103 B2INFO(
"The following aliases are registered:");
104 for (
const auto& a : m_alias) {
105 B2INFO(std::string(a.first, 0, longest_alias_size) << std::string(longest_alias_size - a.first.length(),
106 ' ') <<
" --> " << a.second);
108 B2INFO(
"=====================================");
114 assertValidName(collection);
116 if (m_collection.find(collection) != m_collection.end()) {
117 B2WARNING(
"Another collection with the name'" << collection <<
"' is already set! I overwrite it!");
118 m_collection[collection] = variables;
122 if (m_variables.find(collection) != m_variables.end()) {
123 B2ERROR(
"Variable with the name '" << collection <<
"' exists already, won't add it as an collection!");
127 m_collection.insert(std::make_pair(collection, variables));
135 return m_collection[collection];
142 std::vector<std::string> temp;
144 for (
const auto& var : variables) {
145 auto it = m_collection.find(var);
146 if (it != m_collection.end()) {
147 temp.insert(temp.end(), it->second.begin(), it->second.end());
159 const static std::regex allowedNameRegex(
"^[a-zA-Z0-9_]*$");
161 if (!std::regex_match(name, allowedNameRegex)) {
162 B2FATAL(
"Variable '" << name <<
163 "' contains forbidden characters! Only alphanumeric characters plus underscores (_) are allowed for variable names.");
170 m_currentGroup = groupName;
175 std::match_results<std::string::const_iterator> results;
178 if (std::regex_match(name, results, std::regex(
"^([0-9]+\\.?[0-9]*)$"))) {
179 float float_number = std::stof(results[1]);
180 auto func = [float_number](
const Particle*) ->
double {
183 m_variables[name] = std::make_shared<Var>(name, func, std::string(
"Returns number ") + name);
188 if (std::regex_match(name, results, std::regex(
"^([a-zA-Z0-9_]*)\\((.*)\\)$"))) {
190 std::string functionName = results[1];
191 boost::algorithm::trim(functionName);
193 for (
auto& str : functionArguments) {
194 boost::algorithm::trim(str);
198 auto parameterIter = m_parameter_variables.find(functionName);
199 if (parameterIter != m_parameter_variables.end()) {
201 std::vector<double> arguments;
202 for (
auto& arg : functionArguments) {
204 number = Belle2::convertString<double>(arg);
205 arguments.push_back(number);
207 auto pfunc = parameterIter->second->function;
208 auto func = [pfunc, arguments](
const Particle * particle) ->
double {
return pfunc(particle, arguments); };
209 m_variables[name] = std::make_shared<Var>(name, func, parameterIter->second->description, parameterIter->second->group);
215 auto metaIter = m_meta_variables.find(functionName);
216 if (metaIter != m_meta_variables.end()) {
217 auto func = metaIter->second->function(functionArguments);
218 m_variables[name] = std::make_shared<Var>(name, func, metaIter->second->description, metaIter->second->group);
223 B2FATAL(
"Encountered bad variable name '" << name <<
"'. Maybe you misspelled it?");
229 const std::string& description)
232 B2FATAL(
"No function provided for variable '" << name <<
"'.");
235 assertValidName(name);
237 auto mapIter = m_variables.find(name);
238 if (mapIter == m_variables.end()) {
239 auto var = std::make_shared<Var>(name, f, description, m_currentGroup);
240 B2DEBUG(19,
"Registered Variable " << name);
241 m_variables[name] = var;
242 m_variablesInRegistrationOrder.push_back(var.get());
244 B2FATAL(
"A variable named '" << name <<
"' was already registered! Note that all variables need a unique name!");
249 const std::string& description)
252 B2FATAL(
"No function provided for variable '" << name <<
"'.");
255 auto mapIter = m_parameter_variables.find(name);
256 if (mapIter == m_parameter_variables.end()) {
257 auto var = std::make_shared<ParameterVar>(name, f, description, m_currentGroup);
258 std::string rawName = name.substr(0, name.find(
'('));
259 assertValidName(rawName);
260 B2DEBUG(19,
"Registered parameter Variable " << rawName);
261 m_parameter_variables[rawName] = var;
262 m_variablesInRegistrationOrder.push_back(var.get());
264 B2FATAL(
"A variable named '" << name <<
"' was already registered! Note that all variables need a unique name!");
269 const std::string& description)
272 B2FATAL(
"No function provided for variable '" << name <<
"'.");
275 auto mapIter = m_meta_variables.find(name);
276 if (mapIter == m_meta_variables.end()) {
277 auto var = std::make_shared<MetaVar>(name, f, description, m_currentGroup);
278 std::string rawName = name.substr(0, name.find(
'('));
279 assertValidName(rawName);
280 B2DEBUG(19,
"Registered meta Variable " << rawName);
281 m_meta_variables[rawName] = var;
282 m_variablesInRegistrationOrder.push_back(var.get());
284 B2FATAL(
"A variable named '" << name <<
"' was already registered! Note that all variables need a unique name!");
291 std::vector<std::string> names;
292 for (
const VarBase* var : m_variablesInRegistrationOrder) {
293 names.push_back(var->name);
300 std::vector<std::string> names;
301 for (
auto al : m_alias) names.push_back(al.first);
307 const Var* var = getVariable(varName);
309 throw std::runtime_error(
"Variable::Manager::evaluate(): variable '" + varName +
"' not found!");
313 return var->function(p);