Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
DBManager.cpp
Go to the documentation of this file.
1#include "DBManager.h"
2
3ParserFactory::Type DBManager::deduce_parser_type(fs::path file_path) {
4 auto input_extension = file_path.extension().string();
5 for (const auto& allowed_exts : DBManager::EXTENSIONS) {
6 if (allowed_exts.second.contains(input_extension))
7 return allowed_exts.first;
8 }
9
10 LOG_ERROR("FileError", "Cannot read file with extension", input_extension);
11}
12
13void DBManager::add_default_lha_prototypes(fs::path file_path) {
14 auto input_extension = file_path.extension().string();
15
16 auto insert_if_absent = [&](const Prototype& p) {
17 auto it = std::find_if(lha_prototypes.begin(), lha_prototypes.end(),
18 [&](const Prototype& q){ return q.blockName == p.blockName; });
19 if (it == lha_prototypes.end()) {
20 lha_prototypes.insert(p);
21 }
22 };
23
24 for (const auto& p : LHA_BLOCKS) insert_if_absent(p);
25
26 if (input_extension == ".slha") {
27 for (const auto& p : SLHA_BLOCKS) insert_if_absent(p);
28 } else if (input_extension == ".flha") {
29 for (const auto& p : FLHA_BLOCKS) insert_if_absent(p);
30 } else if (input_extension == ".lha") {
31 // The generic .lha extension is used by both SLHA-like spectrum
32 // generators (including 2HDMC) and FLHA files. Accept both
33 // standard prototype sets so valid mixed-format metadata such as
34 // FMODSEL does not generate unsupported-block warnings.
35 for (const auto& p : SLHA_BLOCKS) insert_if_absent(p);
36 for (const auto& p : FLHA_BLOCKS) insert_if_absent(p);
37 }
38}
39
40void DBManager::sanitize_file(const fs::path& file_path) {
41 if (!fs::exists(file_path)) {
42 throw std::runtime_error("File does not exist: " + file_path.string());
43 }
44
45 if (fs::is_empty(file_path)) {
46 throw std::runtime_error("File is empty: " + file_path.string());
47 }
48
49 std::ifstream file(file_path);
50 if (!file.is_open()) {
51 throw std::runtime_error("Unable to open file: " + file_path.string());
52 }
53
54 char c;
55 while (file.get(c)) {
56 if (static_cast<unsigned char>(c) < 0x09 && c != '\n' && c != '\r' && c != '\t') {
57 throw std::runtime_error("File may contain invalid characters.");
58 }
59 }
60}
61
62std::shared_ptr<DBNode> DBManager::read_from_file(fs::path file_path) {
63 sanitize_file(file_path);
64 ParserFactory::Type parser_type = deduce_parser_type(file_path);
65 auto parser = ParserFactory::createParser(parser_type);
66 if (parser_type == ParserFactory::Type::LHA) {
67 add_default_lha_prototypes(file_path);
68 std::dynamic_pointer_cast<LhaParser>(parser)->set_prototypes(this->lha_prototypes);
69 }
70 auto root = parser->readFromFile(file_path);
71 sanitize_tree(root);
72 return root;
73}
74
75void DBManager::sanitize_tree(const std::shared_ptr<DBNode>& root, const std::vector<BlockName>& required_keys) {
76 if (!root) {
77 throw std::runtime_error("Tree is null.");
78 }
79
80 if (root->countChildren() == 0) {
81 throw std::runtime_error("Tree is empty.");
82 }
83
84 for (const auto& key : required_keys) {
85 if (!root->contains(key)) {
86 throw std::runtime_error("Missing required key in tree: " + key);
87 }
88 }
89}
90
91
92void DBManager::write_to_file(fs::path file_path, std::shared_ptr<DBNode> root) {
93 sanitize_tree(root, { "SMINPUTS" });
94 ParserFactory::Type parser_type = deduce_parser_type(file_path);
95 auto parser = ParserFactory::createParser(parser_type);
96 parser->writeToFile(file_path, root);
97 sanitize_file(file_path);
98}
99
100void DBManager::add_lha_prototype(BlockName blockName, size_t itemCount, size_t valueIdx, int scaleIdx, int rgIdx, int binIdx, bool globalScale) {
101 blockName.to_upper();
102 Prototype new_prototype = Prototype{blockName, itemCount, valueIdx, scaleIdx, rgIdx, binIdx, globalScale};
103
104 auto it = std::find_if(DBManager::lha_prototypes.begin(),
105 DBManager::lha_prototypes.end(),
106 [blockName] (const Prototype& p) { return p.blockName == blockName; });
107
108 if (it != DBManager::lha_prototypes.end()) {
109 if (*it == new_prototype) {
110 LOG_WARN("Trying to add an already existing prototype for block", blockName);
111 return;
112 } else {
113 LOG_ERROR("ValueError", "Cannot add different prototype for existing block", blockName);
114 }
115 }
116
117 DBManager::lha_prototypes.emplace(new_prototype);
118}
High-level interface to load and save DBNodetrees from/to various file formats.
const std::unordered_set< Prototype > SLHA_BLOCKS
const std::unordered_set< Prototype > FLHA_BLOCKS
const std::unordered_set< Prototype > LHA_BLOCKS
#define LOG_ERROR(type,...)
Macro for logging error messages and terminating the application.
Definition Logger.h:41
#define LOG_WARN(...)
Macro for logging warning messages.
Definition Logger.h:40
Block identifier with alias support.
Definition BlockName.h:59
void to_upper()
Converts all aliases to upper-case in-place.
Definition BlockName.cpp:92
Front-end for reading and writing structured data as DBNodetrees.
Definition DBManager.h:46
void add_lha_prototype(BlockName blockName, size_t itemCount=2, size_t valueIdx=1, int scaleIdx=-1, int rgIdx=-1, int binIdx=-1, bool globalScale=false)
Adds or overrides an LHA block prototype used by LhaParser.
void write_to_file(fs::path file_path, std::shared_ptr< DBNode > root)
Writes a DBNodetree to disk using the appropriate format.
Definition DBManager.cpp:92
std::shared_ptr< DBNode > read_from_file(fs::path file_path)
Reads a structured file and returns its DBNoderepresentation.
Definition DBManager.cpp:62
static std::shared_ptr< IParser > createParser(Type type)
Creates a parser instance of the specified type.
Represents the structure of an LHA block, specifying columns for values, scales, and renormalization ...
BlockName blockName