MaCh3  2.8.0
Reference Guide
Macros | Functions
YamlHelper.h File Reference

Utility functions for handling YAML nodes. More...

#include <iostream>
#include <fstream>
#include <string>
#include <cxxabi.h>
#include <regex>
#include "Manager/MaCh3Exception.h"
#include "Manager/Core.h"
#include "TMacro.h"
#include "TList.h"
#include "TObjString.h"
#include "yaml-cpp/yaml.h"
Include dependency graph for YamlHelper.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define M3OpenConfig(filename)   LoadYamlConfig((filename), __FILE__, __LINE__)
 Macro to simplify calling LoadYaml with file and line info. More...
 
#define GetBounds(filename)   ParseBounds((filename), __FILE__, __LINE__)
 
#define Get2DBounds(filename)   Parse2DBounds((filename), __FILE__, __LINE__)
 

Functions

template<typename T >
bool CheckNodeExistsHelper ([[maybe_unused]] const T &node)
 Use this like this CheckNodeExists(config, "LikelihoodOptions", "TestStatistic"); KS: Base case for recursion. More...
 
template<typename T , typename... Args>
bool CheckNodeExistsHelper (const T &node, const std::string &key, Args... args)
 KS: Recursive function to traverse YAML nodes. More...
 
template<typename... Args>
bool CheckNodeExists (const YAML::Node &node, Args... args)
 KS: Wrapper function to call the recursive helper. More...
 
template<typename T >
T FindFromManagerHelper (const YAML::Node &node)
 
template<typename T , typename... Args>
T FindFromManagerHelper (const YAML::Node &node, const std::string &key, Args... args)
 Recursive function to traverse YAML nodes. More...
 
template<typename T , typename... Args>
T FindFromManager (const YAML::Node &node, Args... args)
 Wrapper function to call the recursive helper. More...
 
YAML::Node STRINGtoYAML (const std::string &yaml_string)
 Function to convert a YAML string to a YAML node. More...
 
std::string YAMLtoSTRING (const YAML::Node &node)
 KS: Convert a YAML node to a string representation. More...
 
std::string TMacroToString (const TMacro &macro)
 KS: Convert a ROOT TMacro object to a string representation. More...
 
YAML::Node TMacroToYAML (const TMacro &macro)
 KS: Convert a ROOT TMacro object to a YAML node. More...
 
TMacro YAMLtoTMacro (const YAML::Node &yaml_node, const std::string &name)
 Convert a YAML node to a ROOT TMacro object. More...
 
bool compareYAMLNodes (const YAML::Node &node1, const YAML::Node &node2, bool Mute=false)
 Compare if yaml nodes are identical. More...
 
template<typename TValue >
void OverrideConfig (YAML::Node node, std::string const &key, TValue val)
 Overrides the configuration settings based on provided arguments. More...
 
template<typename... Args>
void OverrideConfig (YAML::Node node, std::string const &key, Args... args)
 Overrides the configuration settings based on provided arguments. More...
 
std::string DemangleTypeName (const std::string &mangledName)
 Function to demangle type names. More...
 
template<typename Type >
Type Get (const YAML::Node &node, const std::string &File, const int Line)
 Get content of config file. More...
 
template<typename Type >
Type GetFromManager (const YAML::Node &node, const Type defval, const std::string &File, const int Line)
 Get content of config file if node is not found take default value specified. More...
 
YAML::Node LoadYamlConfig (const std::string &filename, const std::string &File, const int Line)
 Open YAML file. More...
 
const YAML::Node & Cnode (const YAML::Node &n)
 KS: Convenience wrapper to return a YAML node as-is. More...
 
YAML::Node MergeNodes (const YAML::Node &a, const YAML::Node &b)
 KS: Recursively merges two YAML nodes. More...
 
std::vector< double > ParseBounds (const YAML::Node &node, const std::string &File, const int Line)
 KS: Get bounds from YAML for example for selection cuts. More...
 
std::vector< std::vector< double > > Parse2DBounds (const YAML::Node &node, const std::string &File, const int Line)
 KS: Get 2D bounds from YAML for example for selection cuts. More...
 

Detailed Description

Utility functions for handling YAML nodes.

MaCh3 uses YAML in a specific way within its configuration system. These helper functions act as a safety layer on top of yaml-cpp, adding MaCh3-specific validation, consistency checks, and enhanced error reporting.

Note
you can read more about Yaml: here
Author
Kamil Skwarczynski
Luke Pickering

Definition in file YamlHelper.h.

Macro Definition Documentation

◆ Get2DBounds

#define Get2DBounds (   filename)    Parse2DBounds((filename), __FILE__, __LINE__)

Definition at line 591 of file YamlHelper.h.

◆ GetBounds

#define GetBounds (   filename)    ParseBounds((filename), __FILE__, __LINE__)

Definition at line 590 of file YamlHelper.h.

◆ M3OpenConfig

#define M3OpenConfig (   filename)    LoadYamlConfig((filename), __FILE__, __LINE__)

Macro to simplify calling LoadYaml with file and line info.

Definition at line 589 of file YamlHelper.h.

Function Documentation

◆ CheckNodeExists()

template<typename... Args>
bool CheckNodeExists ( const YAML::Node &  node,
Args...  args 
)

KS: Wrapper function to call the recursive helper.

Definition at line 59 of file YamlHelper.h.

59  {
60 // **********************
61  return CheckNodeExistsHelper(node, args...);
62 }
bool CheckNodeExistsHelper([[maybe_unused]] const T &node)
Use this like this CheckNodeExists(config, "LikelihoodOptions", "TestStatistic"); KS: Base case for r...
Definition: YamlHelper.h:39

◆ CheckNodeExistsHelper() [1/2]

template<typename T >
bool CheckNodeExistsHelper ( [[maybe_unused] ] const T &  node)

Use this like this CheckNodeExists(config, "LikelihoodOptions", "TestStatistic"); KS: Base case for recursion.

Definition at line 39 of file YamlHelper.h.

39  {
40 // **********************
41  return true; // Node exists, return true
42 }

◆ CheckNodeExistsHelper() [2/2]

template<typename T , typename... Args>
bool CheckNodeExistsHelper ( const T &  node,
const std::string &  key,
Args...  args 
)

KS: Recursive function to traverse YAML nodes.

Definition at line 47 of file YamlHelper.h.

47  {\
48 // **********************
49  if (!node[key]) {
50  MACH3LOG_TRACE("Node '{}' doesn't exist.", key);
51  return false;
52  }
53  return CheckNodeExistsHelper(node[key], args...);
54 }
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33

◆ Cnode()

const YAML::Node& Cnode ( const YAML::Node &  n)
inline

KS: Convenience wrapper to return a YAML node as-is.

Parameters
nInput YAML node.
Returns
Reference to the same YAML node.

Definition at line 418 of file YamlHelper.h.

418  {
419 // **********************
420  return n;
421 }

◆ compareYAMLNodes()

bool compareYAMLNodes ( const YAML::Node &  node1,
const YAML::Node &  node2,
bool  Mute = false 
)
inline

Compare if yaml nodes are identical.

Parameters
node1The first YAML node to compare.
node2The second YAML node to compare.
Muteallow to mute warning messages
Returns
true If the two nodes are equivalent in type and content.
false If the two nodes differ in structure or content.

Definition at line 185 of file YamlHelper.h.

185  {
186 // **********************
187  // Check if the types of the nodes match
188  if (node1.Type() != node2.Type()) {
189  return false;
190  }
191 
192  // Compare scalar types (like strings, numbers)
193  if (node1.IsScalar() && node2.IsScalar()) {
194  auto v1 = node1.as<std::string>();
195  auto v2 = node2.as<std::string>();
196  if (v1 != v2) {
197  if (!Mute) MACH3LOG_WARN("Scalar value mismatch: '{}' != '{}'", v1, v2);
198  return false;
199  }
200  return true;
201  }
202 
203  // Compare sequences (like YAML lists)
204  if (node1.IsSequence() && node2.IsSequence()) {
205  if (node1.size() != node2.size()) {
206  return false;
207  }
208  for (std::size_t i = 0; i < node1.size(); ++i) {
209  if (!compareYAMLNodes(node1[i], node2[i])) {
210  return false;
211  }
212  }
213  return true;
214  }
215 
216  // Compare maps (like YAML dictionaries)
217  if (node1.IsMap() && node2.IsMap()) {
218  if (node1.size() != node2.size()) {
219  MACH3LOG_WARN("Map size mismatch: {} != {}",
220  node1.size(), node2.size());
221  return false;
222  }
223  for (auto it1 = node1.begin(); it1 != node1.end(); ++it1) {
224  auto key = it1->first.as<std::string>();
225  if (!node2[key]) {
226  MACH3LOG_WARN("Key '{}' missing in second YAML", key);
227  return false;
228  }
229  if (!compareYAMLNodes(it1->second, node2[key])) {
230  MACH3LOG_WARN("Value mismatch at key '{}'", key);
231  return false;
232  }
233  }
234  return true;
235  }
236 
237  // Default case: if it's neither scalar, sequence, nor map, consider it unequal
238  if (!Mute) MACH3LOG_WARN("Unsupported YAML node type encountered");
239  return false;
240 }
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
bool compareYAMLNodes(const YAML::Node &node1, const YAML::Node &node2, bool Mute=false)
Compare if yaml nodes are identical.
Definition: YamlHelper.h:185

◆ DemangleTypeName()

std::string DemangleTypeName ( const std::string &  mangledName)
inline

Function to demangle type names.

Definition at line 275 of file YamlHelper.h.

275  {
276 // **********************
277  int status = 0;
278  char* demangledName = abi::__cxa_demangle(mangledName.c_str(), nullptr, nullptr, &status);
279  std::string result = (status == 0) ? demangledName : mangledName;
280  free(demangledName);
281  return result;
282 }

◆ FindFromManager()

template<typename T , typename... Args>
T FindFromManager ( const YAML::Node &  node,
Args...  args 
)

Wrapper function to call the recursive helper.

Definition at line 88 of file YamlHelper.h.

88  {
89 // **********************
90  return FindFromManagerHelper<T>(node, args...);
91 }

◆ FindFromManagerHelper() [1/2]

template<typename T >
T FindFromManagerHelper ( const YAML::Node &  node)

Use this like this FindFromManager<std::string>(config, "LikelihoodOptions", "TestStatistic"); Base case for recursion

Definition at line 68 of file YamlHelper.h.

68  {
69 // **********************
70  return node.as<T>(); // Convert YAML node to the specified type
71 }

◆ FindFromManagerHelper() [2/2]

template<typename T , typename... Args>
T FindFromManagerHelper ( const YAML::Node &  node,
const std::string &  key,
Args...  args 
)

Recursive function to traverse YAML nodes.

Definition at line 76 of file YamlHelper.h.

76  {
77 // **********************
78  if (!node[key]) {
79  MACH3LOG_ERROR("Node {} doesn't exist.", key);
80  throw MaCh3Exception(__FILE__, __LINE__);
81  return T();
82  }
83  return FindFromManagerHelper<T>(node[key], args...); // Recursive call
84 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
Custom exception class used throughout MaCh3.

◆ Get()

template<typename Type >
Type Get ( const YAML::Node &  node,
const std::string &  File,
const int  Line 
)

Get content of config file.

Parameters
nodeYaml node
Filename of file in which function is being called to make better error message
LineFile line in which function is being called to make better error message

Definition at line 290 of file YamlHelper.h.

290  {
291 // **********************
292  try {
293  // Attempt to convert the node to the expected type
294  return node.as<Type>();
295  } catch (const YAML::BadConversion& e) {
296  const std::string nodeAsString = YAMLtoSTRING(node);
297  MACH3LOG_ERROR("YAML type mismatch: {}", e.what());
298  MACH3LOG_ERROR("While trying to access variable \"{}\"", nodeAsString);
299  if (!node || node.IsNull()) {
300  MACH3LOG_ERROR("Requested node does not exist (null or undefined)");
301  }
302  throw MaCh3Exception(File , Line );
303  } catch (const YAML::InvalidNode& e) {
304  std::string key = "<unknown>";
305  const std::string msg = e.what();
306  const std::string search = "first invalid key: \"";
307  auto start = msg.find(search);
308  if (start != std::string::npos) {
309  start += search.length();
310  auto end = msg.find("\"", start);
311  if (end != std::string::npos) {
312  key = msg.substr(start, end - start);
313  }
314  }
315  MACH3LOG_ERROR("Invalid YAML node: {}", e.what());
316  MACH3LOG_ERROR("While trying to access key: {}", key);
317  throw MaCh3Exception(File , Line );
318  }
319 }
std::string YAMLtoSTRING(const YAML::Node &node)
KS: Convert a YAML node to a string representation.
Definition: YamlHelper.h:111

◆ GetFromManager()

template<typename Type >
Type GetFromManager ( const YAML::Node &  node,
const Type  defval,
const std::string &  File,
const int  Line 
)

Get content of config file if node is not found take default value specified.

Parameters
nodeYaml node
defvalDefault value which will be used in case node doesn't exist
Filename of file in which function is being called to make better error message
LineFile line in which function is being called to make better error message

Definition at line 328 of file YamlHelper.h.

328  {
329 // **********************
330  if (!node) {
331  return defval;
332  }
333  try {
334  // Attempt to convert the node to the expected type
335  return node.as<Type>();
336  } catch (const YAML::BadConversion& e) {
337  const std::string nodeAsString = YAMLtoSTRING(node);
338  MACH3LOG_ERROR("YAML type mismatch: {}", e.what());
339  MACH3LOG_ERROR("While trying to access variable {}", nodeAsString);
340  //const std::string expectedType = DemangleTypeName(typeid(Type).name());
341  //MACH3LOG_ERROR("Expected argument is {}", expectedType);
342  if(File == "") {
343  throw MaCh3Exception(__FILE__ , __LINE__);
344  } else {
345  throw MaCh3Exception(File , Line );
346  }
347  }
348 }

◆ LoadYamlConfig()

YAML::Node LoadYamlConfig ( const std::string &  filename,
const std::string &  File,
const int  Line 
)
inline

Open YAML file.

Parameters
filenamename of filename to open
Filename of file where function is called
Linenumber where function is called

Definition at line 355 of file YamlHelper.h.

355  {
356 // **********************
357  // KS: YAML can be dumb and not throw error if you pass toml for example...
358  if (!(filename.length() >= 5 && filename.compare(filename.length() - 5, 5, ".yaml") == 0) &&
359  !(filename.length() >= 4 && filename.compare(filename.length() - 4, 4, ".yml") == 0)) {
360  MACH3LOG_ERROR("Invalid file extension: {}", filename);
361  MACH3LOG_ERROR("I was expecting .yaml or .yml");
362  throw MaCh3Exception(File, Line);
363  }
364 
365  try {
366  YAML::Node yamlNode = YAML::LoadFile(filename);
367 
368  // Convert the YAML file to string
369  std::ifstream fileStream(filename);
370  std::stringstream buffer;
371  buffer << fileStream.rdbuf();
372  std::string fileContent = buffer.str();
373 
374  // Use regex to find any line starting with `-` but not followed by space, digit, or dot
375  // This excludes valid numeric negative values like -1760.0
376  std::regex linePattern(R"(^\s*-(?![\d\s\.]).*)");
377 
378  std::istringstream contentStream(fileContent);
379  std::string lineconfig;
380  int lineNumber = 1;
381 
382  // KS: Instead of boolean, track flow-style list nesting depth
383  int flowListDepth = 0;
384 
385  while (std::getline(contentStream, lineconfig)) {
386  // Ignore YAML document separator
387  if (lineconfig.find("---") != std::string::npos) {
388  lineNumber++;
389  continue;
390  }
391 
392  // Update flow list depth (increment for each '[' and decrement for each ']')
393  for (char c : lineconfig) {
394  if (c == '[') flowListDepth++;
395  else if (c == ']') flowListDepth = std::max(0, flowListDepth - 1);
396  }
397 
398  // Check lines only outside flow-style lists
399  if (flowListDepth == 0 && std::regex_match(lineconfig, linePattern)) {
400  MACH3LOG_ERROR("Warning: Missing space or tab after '-' at line {}: {}\n", lineNumber, lineconfig);
401  throw MaCh3Exception(File, Line);
402  }
403  lineNumber++;
404  }
405 
406  return yamlNode;
407  } catch (const std::exception& e) {
408  MACH3LOG_ERROR("{}\n", e.what());
409  MACH3LOG_ERROR("Can't open file {}\n", filename);
410  throw MaCh3Exception(File, Line);
411  }
412 }

◆ MergeNodes()

YAML::Node MergeNodes ( const YAML::Node &  a,
const YAML::Node &  b 
)
inline

KS: Recursively merges two YAML nodes.

If both nodes are maps, their keys are merged. Scalar or null values in b will override those in a. If b is null, a is returned unchanged.

Note
Based on https://stackoverflow.com/a/41337824
Parameters
aThe base YAML node.
bThe YAML node to merge into a.
Returns
A new YAML node representing the merged result.

Definition at line 434 of file YamlHelper.h.

434  {
435 // **********************
436  if (!b.IsMap()) {
437  // If b is not a map, merge result is b, unless b is null
438  return b.IsNull() ? a : b;
439  }
440  if (!a.IsMap()) {
441  // If a is not a map, merge result is b
442  return b;
443  }
444  if (!b.size()) {
445  // If a is a map, and b is an empty map, return a
446  return a;
447  }
448  // Create a new map 'c' with the same mappings as a, merged with b
449  auto c = YAML::Node(YAML::NodeType::Map);
450  for (auto n : a) {
451  if (n.first.IsScalar()) {
452  const std::string & key = n.first.Scalar();
453  auto t = (Cnode(b)[key]);
454  if (t) {
455  c[n.first] = MergeNodes(n.second, t);
456  continue;
457  }
458  }
459  c[n.first] = n.second;
460  }
461  // Add the mappings from 'b' not already in 'c'
462  for (auto n : b) {
463  if (!n.first.IsScalar() || !Cnode(c)[n.first.Scalar()]) {
464  c[n.first] = n.second;
465  }
466  }
467  return c;
468 }
YAML::Node MergeNodes(const YAML::Node &a, const YAML::Node &b)
KS: Recursively merges two YAML nodes.
Definition: YamlHelper.h:434
const YAML::Node & Cnode(const YAML::Node &n)
KS: Convenience wrapper to return a YAML node as-is.
Definition: YamlHelper.h:418

◆ OverrideConfig() [1/2]

template<typename... Args>
void OverrideConfig ( YAML::Node  node,
std::string const &  key,
Args...  args 
)

Overrides the configuration settings based on provided arguments.

This function allows you to set configuration options in a nested YAML node.

Parameters
nodeYAML node that will be modified
keyThe key in the YAML node to override
argsThe arguments to override the configuration. The last argument will be used as the value
Note
Example usage:
OverrideConfig(config, "General", "OutputFile", "Wooimbouttamakeanameformyselfere.root");
OverrideConfig(config, "General", "MyDouble", 5.3);
void OverrideConfig(YAML::Node node, std::string const &key, TValue val)
Overrides the configuration settings based on provided arguments.
Definition: YamlHelper.h:248

Definition at line 268 of file YamlHelper.h.

268  {
269 // **********************
270  OverrideConfig(node[key], args...);
271 }

◆ OverrideConfig() [2/2]

template<typename TValue >
void OverrideConfig ( YAML::Node  node,
std::string const &  key,
TValue  val 
)

Overrides the configuration settings based on provided arguments.

Parameters
nodeYAML node that will be modified
keyThe key in the YAML node to override
valThe value to assign to the key

Definition at line 248 of file YamlHelper.h.

248  {
249 // **********************
250  node[key] = val;
251 }

◆ Parse2DBounds()

std::vector<std::vector<double> > Parse2DBounds ( const YAML::Node &  node,
const std::string &  File,
const int  Line 
)
inline

KS: Get 2D bounds from YAML for example for selection cuts.

Parses a YAML node representing 2D selection bounds. Each element in the node must be a sequence of 1 or 2 scalar values. If a single value is given, it is interpreted as the center of a bin and expanded to [value - 0.5, value + 0.5]. If two values are given, they are used as-is. If an element is empty or null, default bounds are used.

This function is useful for interpreting kinematic or classification bounds specified in YAML configuration files.

Example YAML input:

bounds2D:
- [1]
- [0.2, 0.8]
- ["", "2.0"]

Resulting vector:

[ [0.5, 1.5],
[0.2, 0.8],
constexpr static const double KinematicLowBound
When parameter has no bound this serves as it. Lowest possible value the system.
Definition: Core.h:75
Parameters
nodeThe YAML node containing a sequence of bounds (each being a 1- or 2-element sequence).
FileThe name of the file calling this function (for error reporting).
LineThe line number in the file calling this function (for error reporting).
Returns
std::vector<std::vector<double>> A list of bound pairs for each selection region.

Definition at line 567 of file YamlHelper.h.

567  {
568 // **********************
569  std::vector<std::vector<double>> bounds;
570  if (!node || !node.IsSequence()) {
571  MACH3LOG_ERROR("Expected a sequence node for 2D bounds");
572  throw MaCh3Exception(File, Line);
573  }
574 
575  // Case 1: Single pair like [0.25, 0.5]
576  if (node.size() == 2 && node[0].IsScalar()) {
577  bounds.push_back(ParseBounds(node, File, Line));
578  } else { // Case 2: List of pairs like [[0.25, 0.5], [0.75, 1.0]]
579  for (std::size_t i = 0; i < node.size(); ++i) {
580  const YAML::Node& subnode = node[i];
581  bounds.push_back(ParseBounds(subnode, File, Line));
582  }
583  }
584 
585  return bounds;
586 }
std::vector< double > ParseBounds(const YAML::Node &node, const std::string &File, const int Line)
KS: Get bounds from YAML for example for selection cuts.
Definition: YamlHelper.h:483

◆ ParseBounds()

std::vector<double> ParseBounds ( const YAML::Node &  node,
const std::string &  File,
const int  Line 
)
inline

KS: Get bounds from YAML for example for selection cuts.

This function expects a YAML node of exactly two elements. If any of the elements is an empty string or null, it is replaced with a default kinematic bound. If the element is a non-empty string and cannot be converted to a double, an exception is thrown.

Parameters
nodeThe YAML node containing the bounds.
FileThe name of the file calling this function (for error context).
LineThe line number in the file calling this function.
Returns
std::vector<double> A vector of size 2 with the parsed bounds.

Definition at line 483 of file YamlHelper.h.

483  {
484 // **********************
485  std::vector<double> bounds;
486 
487  if (!node || !node.IsSequence() || (node.size() != 1 && node.size() != 2)) {
488  MACH3LOG_ERROR("Bounds must be a sequence of 1 or 2 elements, got size {}", static_cast<int>(node.size()));
489  throw MaCh3Exception(File, Line);
490  }
491 
492  if (node.size() == 1) {
493  const YAML::Node& val = node[0];
494 
495  if (!val || val.IsNull() || (val.IsScalar() && val.Scalar().empty())) {
496  MACH3LOG_ERROR("Single-element bounds must contain a valid numeric value.");
497  throw MaCh3Exception(File, Line);
498  } else if (val.IsScalar()) {
499  try {
500  const double center = val.as<double>();
501  if (std::floor(center) != center) {
502  MACH3LOG_ERROR("Invalid center value in Bounds[0]: '{}'. Expected an integer (e.g., 0 or 1).", static_cast<std::string>(val.Scalar()));
503  throw MaCh3Exception(File, Line);
504  }
505  bounds = {center - 0.5, center + 0.5};
506  } catch (const YAML::BadConversion& e) {
507  MACH3LOG_ERROR("Invalid value in Bounds[0]: '{}'. Expected a number.", static_cast<std::string>(val.Scalar()));
508  throw MaCh3Exception(File, Line);
509  }
510  } else {
511  MACH3LOG_ERROR("Invalid type in Bounds[0]");
512  throw MaCh3Exception(File, Line);
513  }
514  } else {
515  for (std::size_t i = 0; i < 2; ++i) {
516  const YAML::Node& val = node[i];
517 
518  if (!val || val.IsNull() || (val.IsScalar() && val.Scalar().empty())) {
519  bounds.push_back(i == 0 ? M3::KinematicLowBound : M3::KinematicUpBound);
520  } else if (val.IsScalar()) {
521  try {
522  bounds.push_back(val.as<double>());
523  } catch (const YAML::BadConversion& e) {
524  MACH3LOG_ERROR("Invalid value in Bounds[{}]: '{}'. Expected a number or empty string.",
525  static_cast<int>(i), static_cast<std::string>(val.Scalar()));
526  throw MaCh3Exception(File, Line);
527  }
528  } else {
529  MACH3LOG_ERROR("Invalid type in Bounds[{}]", static_cast<int>(i));
530  throw MaCh3Exception(File, Line);
531  }
532  }
533  }
534  return bounds;
535 }
constexpr static const double KinematicUpBound
When parameter has no bound this serves as it. Highest possible value the system.
Definition: Core.h:77

◆ STRINGtoYAML()

YAML::Node STRINGtoYAML ( const std::string &  yaml_string)
inline

Function to convert a YAML string to a YAML node.

Parameters
yaml_stringString which will be converted to yaml node

Definition at line 96 of file YamlHelper.h.

96  {
97 // **********************
98  try {
99  return YAML::Load(yaml_string);
100  } catch (const YAML::ParserException& e) {
101  MACH3LOG_ERROR("Error parsing YAML string: {}", e.what());
102  return YAML::Node();
103  }
104 }

◆ TMacroToString()

std::string TMacroToString ( const TMacro &  macro)
inline

KS: Convert a ROOT TMacro object to a string representation.

Parameters
macroThe ROOT TMacro object to convert.
Returns
std::string The string representation of the TMacro object.

Definition at line 122 of file YamlHelper.h.

122  {
123 // **********************
124  std::stringstream ss;
125 
126  // Retrieve lines from TMacro
127  TList* linesList = macro.GetListOfLines();
128  if (!linesList) {
129  MACH3LOG_ERROR("Failed to retrieve lines from TMacro.");
130  return "";
131  }
132 
133  TIter nextLine(linesList);
134  TObject *obj = nullptr;
135  while ((obj = nextLine())) {
136  TObjString* line = dynamic_cast<TObjString*>(obj);
137  if (!line) {
138  MACH3LOG_ERROR("Failed to cast object to TObjString.");
139  continue;
140  }
141  ss << line->GetString() << std::endl;
142  }
143 
144  return ss.str();
145 }

◆ TMacroToYAML()

YAML::Node TMacroToYAML ( const TMacro &  macro)
inline

KS: Convert a ROOT TMacro object to a YAML node.

Parameters
macroThe ROOT TMacro object to convert.
Returns
YAML::Node The YAML node representing the TMacro object.

Definition at line 151 of file YamlHelper.h.

151  {
152 // **********************
153  std::string yaml_string = TMacroToString(macro);
154 
155  // Convert the YAML string to a YAML node
156  YAML::Node yaml_node = STRINGtoYAML(yaml_string);
157 
158  return yaml_node;
159 }
YAML::Node STRINGtoYAML(const std::string &yaml_string)
Function to convert a YAML string to a YAML node.
Definition: YamlHelper.h:96
std::string TMacroToString(const TMacro &macro)
KS: Convert a ROOT TMacro object to a string representation.
Definition: YamlHelper.h:122

◆ YAMLtoSTRING()

std::string YAMLtoSTRING ( const YAML::Node &  node)
inline

KS: Convert a YAML node to a string representation.

Parameters
nodeThe YAML node to convert to a string.
Returns
std::string The string representation of the YAML node.
Warning
YAML is weird and drops " " for string so output may not be identical to yaml you provided

Definition at line 111 of file YamlHelper.h.

111  {
112 // **********************
113  YAML::Emitter emitter;
114  emitter << node;
115  return emitter.c_str();
116 }

◆ YAMLtoTMacro()

TMacro YAMLtoTMacro ( const YAML::Node &  yaml_node,
const std::string &  name 
)
inline

Convert a YAML node to a ROOT TMacro object.

Parameters
yaml_nodeThe YAML node to convert to a TMacro.
nameName of TMacro that will be saved
Returns
TMacro The TMacro object constructed from the YAML node.

Definition at line 166 of file YamlHelper.h.

166  {
167 // **********************
168  // Convert the YAML node to a string representation
169  std::string macro_string = YAMLtoSTRING(yaml_node);
170 
171  // Create a TMacro object with the collected lines
172  TMacro macro(name.c_str(), name.c_str());
173  macro.AddLine(macro_string.c_str());
174 
175  return macro;
176 }