Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
lha_elements.cpp
Go to the documentation of this file.
1#include "lha_elements.h"
2
3template <typename U>
5 static U convert(const std::string& str) {
6 static_assert(std::is_same_v<U, void>, "Unsupported conversion");
7 }
8};
9
10template <>
11struct StringConverter<double> {
12 static double convert(const std::string& str) {
13 try {
14 return std::stod(str);
15 } catch (const std::invalid_argument&) {
16 throw std::runtime_error("Invalid double: '" + str + "'");
17 } catch (const std::out_of_range&) {
18 throw std::runtime_error("Out-of-range double: '" + str + "'");
19 }
20 }
21};
22
23
24template <>
25struct StringConverter<std::string> {
26 static std::string convert(const std::string& str) {
27 return str;
28 }
29};
30
31static inline void normalize_indices(const Prototype& p,
32 const std::vector<std::string>& line,
33 size_t& vIdx, int& sIdx, int& rIdx, int& bIdx)
34{
35 vIdx = p.valueIdx < line.size() ? p.valueIdx : (line.empty() ? 0 : line.size() - 1);
36
37 sIdx = (p.scaleIdx >= 0 && static_cast<size_t>(p.scaleIdx) < line.size()) ? p.scaleIdx : -1;
38 rIdx = (p.rgIdx >= 0 && static_cast<size_t>(p.rgIdx) < line.size()) ? p.rgIdx : -1;
39 bIdx = (p.binIdx >= 0 && static_cast<size_t>(p.binIdx) < line.size()) ? p.binIdx : -1;
40}
41
42template<typename T>
43LhaElement<T>::LhaElement(const Prototype& prototype, const std::vector<std::string>& line)
44 : AbstractElement(encodeId(prototype, line))
45{
46 size_t vIdx; int sIdx, rIdx, bIdx;
47 normalize_indices(prototype, line, vIdx, sIdx, rIdx, bIdx);
48
49 if (prototype.globalScale) {
50 if (line.empty()) throw std::runtime_error("Global-scale block: empty line in " + prototype.blockName);
51 this->Q.emplace(std::stod(line.at(0)));
52 } else if (sIdx != -1) {
53 this->Q.emplace(std::stod(line.at(sIdx)));
54 }
55 if (rIdx != -1) {
56 this->rScheme.emplace(static_cast<RenormalizationScheme>(std::stoi(line.at(rIdx))));
57 }
58
59 if (bIdx != -1) {
60 this->bin.emplace(std::pair(std::stod(line.at(bIdx)), std::stod(line.at(bIdx + 1))));
61 }
62
63 if (vIdx >= line.size())
64 throw std::runtime_error("valueIdx out of range in " + prototype.blockName);
65 this->value = StringConverter<T>::convert(line.at(vIdx));
66}
67
68template <typename T>
69LhaID LhaElement<T>::encodeId(const Prototype& prototype, const std::vector<std::string>& line) {
70 size_t vIdx; int sIdx, rIdx, bIdx;
71 normalize_indices(prototype, line, vIdx, sIdx, rIdx, bIdx);
72
73 std::vector<long> sub_ids;
74 for (size_t i = 0; i < line.size(); ++i) {
75 if (i == vIdx || static_cast<int>(i) == sIdx || static_cast<int>(i) == rIdx) continue;
76 if (bIdx != -1 && (static_cast<int>(i) == bIdx || static_cast<int>(i) == bIdx + 1)) continue;
77 if (prototype.globalScale && i == 0) continue;
78
79 const auto& s = line[i];
80 if (s.find_first_of(".eEdD") != std::string::npos) continue;
81
82 try {
83 sub_ids.emplace_back(std::stol(s));
84 } catch (...) {
85 LOG_WARN("Non-integer ID token in ", prototype.blockName, ": '", s, "'");
86 }
87 }
88 return LhaID(sub_ids);
89}
90
91template <typename T>
92std::string LhaElement<T>::toString() const {
93 std::stringstream stream;
94 stream << this->getId() << '\t' << this->getValue();
95 if (Q.has_value()) {
96 stream << '\t' << this->getScale();
97 }
98 if (rScheme.has_value()) {
99 stream << '\t' << static_cast<int>(this->getScheme());
100 }
101 stream << "\n";
102 return stream.str();
103}
104
105template <typename T>
106std::shared_ptr<DBNode> LhaElement<T>::toDBNode() const {
107 DBNode node;
108 node.set(this->getValue(), "central_value");
109 if (Q.has_value()) {
110 node.set(this->getScale(), "scale");
111 }
112 if (rScheme.has_value()) {
113 node.set(static_cast<int>(this->getScheme()), "renormalization_scheme");
114 }
115 if (bin.has_value()) {
116 auto bin = this->getBinning();
117 node.set(bin.first, "bin_low");
118 node.set(bin.second, "bin_high");
119 }
120 return std::make_shared<DBNode>(node);
121}
122
123std::shared_ptr<AbstractElement> LhaElementFactory::createElement(const Prototype& prototype, const std::vector<std::string>& line) {
124 if (prototype.blockName == "FCINFO" || prototype.blockName == "FMODSEL" || prototype.blockName == "SPINFO") {
125 return std::make_shared<LhaElement<std::string>>(prototype, line);
126 } else {
127 return std::make_shared<LhaElement<double>>(prototype, line);
128 }
129}
130
131// The template definitions live in this translation unit. Export the concrete
132// specializations used by the parser and public API so every compiler emits the
133// symbols needed by callers in other translation units.
134template class LhaElement<double>;
135template class LhaElement<std::string>;
#define LOG_WARN(...)
Macro for logging warning messages.
Definition Logger.h:40
Abstract base class for a single element of an LHA/FLHA block.
void set(T value, Key &&key, Rest &&... rest)
Sets a value in the node using a sequence of keys.
static std::shared_ptr< AbstractElement > createElement(const Prototype &prototype, const std::vector< std::string > &line)
Creates an element of the appropriate type for a given line.
Template concrete implementation of an LHA/FLHA block element.
std::string toString() const override
Returns a line-like string representation of the element.
LhaElement(const Prototype &prototype, const std::vector< std::string > &line)
Constructs an LhaElement from a prototype and a line of data.
std::shared_ptr< DBNode > toDBNode() const override
Converts the element to a DBNode representation.
RenormalizationScheme
Enumeration of possible renormalization schemes for LHA elements.
Hash specialization for SymbolId<Tag>.
Definition BlockName.h:353
Represents an identifier of a LHA element, possibly containing several sub-ids.
Definition LhaID.h:56
Represents the structure of an LHA block, specifying columns for values, scales, and renormalization ...
BlockName blockName
static double convert(const std::string &str)
static std::string convert(const std::string &str)
static U convert(const std::string &str)