MaCh3  2.6.1
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 (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 >
FindFromManagerHelper (const YAML::Node &node)
 
template<typename T , typename... Args>
FindFromManagerHelper (const YAML::Node &node, const std::string &key, Args... args)
 Recursive function to traverse YAML nodes. More...
 
template<typename T , typename... Args>
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 592 of file YamlHelper.h.

◆ GetBounds

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

Definition at line 591 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 590 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 60 of file YamlHelper.h.

60  {
61 // **********************
62  return CheckNodeExistsHelper(node, args...);
63 }
bool CheckNodeExistsHelper(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 ( 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  (void)node;
42  return true; // Node exists, return true
43 }

◆ 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 48 of file YamlHelper.h.

48  {\
49 // **********************
50  if (!node[key]) {
51  MACH3LOG_TRACE("Node '{}' doesn't exist.", key);
52  return false;
53  }
54  return CheckNodeExistsHelper(node[key], args...);
55 }
#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 419 of file YamlHelper.h.

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

◆ 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 186 of file YamlHelper.h.

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

◆ DemangleTypeName()

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

Function to demangle type names.

Definition at line 276 of file YamlHelper.h.

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

◆ FindFromManager()

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

Wrapper function to call the recursive helper.

Definition at line 89 of file YamlHelper.h.

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

◆ 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 69 of file YamlHelper.h.

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

◆ 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 77 of file YamlHelper.h.

77  {
78 // **********************
79  if (!node[key]) {
80  MACH3LOG_ERROR("Node {} doesn't exist.", key);
81  throw MaCh3Exception(__FILE__, __LINE__);
82  return T();
83  }
84  return FindFromManagerHelper<T>(node[key], args...); // Recursive call
85 }
#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 291 of file YamlHelper.h.

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

◆ 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 329 of file YamlHelper.h.

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

◆ 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 356 of file YamlHelper.h.

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

◆ 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 435 of file YamlHelper.h.

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

◆ 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:249

Definition at line 269 of file YamlHelper.h.

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

◆ 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 249 of file YamlHelper.h.

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

◆ 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 568 of file YamlHelper.h.

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

◆ 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 484 of file YamlHelper.h.

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

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

◆ 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 123 of file YamlHelper.h.

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

◆ 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 152 of file YamlHelper.h.

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

◆ 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 112 of file YamlHelper.h.

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

◆ 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 167 of file YamlHelper.h.

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