MaCh3  2.4.2
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=1)
 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 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 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 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 = 1 
)

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: {}\n", filename);
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);
std::string config
Definition: ProcessMCMC.cpp:30
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 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 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 }