Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
FileWriter.cpp
Go to the documentation of this file.
1#include "FileWriter.h"
2
3#include <algorithm>
4#include <cctype>
5#include <filesystem>
6#include <stdexcept>
7#include <utility>
8
9#include "JsonParser.h"
10#include "LhaParser.h"
11#include "MemoryManager.h"
12#include "ParamBlockWriter.h"
13#include "Parameters.h"
14#include "YamlParser.h"
15
16namespace {
17
18std::string lower_extension(const std::string& destination) {
19 std::string extension = std::filesystem::path(destination).extension().string();
20 std::transform(extension.begin(), extension.end(), extension.begin(),
21 [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
22 return extension;
23}
24
25void ensure_parent_directory(const std::string& destination) {
26 const auto parent = std::filesystem::path(destination).parent_path();
27 if (!parent.empty()) {
28 std::error_code error;
29 std::filesystem::create_directories(parent, error);
30 if (error) {
31 throw std::runtime_error(
32 "FileWriter: cannot create output directory '" + parent.string() +
33 "': " + error.message()
34 );
35 }
36 }
37}
38
39std::shared_ptr<BlockAccessor> source_for_parameter(
40 const ParamId& parameter_id,
41 const std::shared_ptr<BlockAccessor>& fallback
42) {
43 if (!parameter_id.type.has_value()) {
44 return fallback;
45 }
46
47 auto parameters = Parameters::GetInstance(parameter_id.type.value());
48 if (!parameters || !parameters->get_block_accessor()) {
49 throw std::invalid_argument(
50 "FileWriter: no parameter repository is available for the requested ParamId"
51 );
52 }
53 return parameters->get_block_accessor();
54}
55
56} // namespace
57
58std::shared_ptr<BlockAccessor> FileWriter::resolve_source(std::shared_ptr<BlockAccessor> src) {
59 if (src) {
60 return src;
61 }
62
63 auto* memory_manager = MemoryManager::GetInstance();
64 if (!memory_manager || !memory_manager->is_ready()) {
65 throw std::logic_error(
66 "FileWriter: HyperIso must be initialized before exporting the current database"
67 );
68 }
69 return memory_manager->extract_block_accessor();
70}
71
72void FileWriter::write_accessor(
73 const std::string& dest,
74 const std::shared_ptr<BlockAccessor>& src
75) {
76 if (!src) {
77 throw std::invalid_argument("FileWriter: source BlockAccessor is null");
78 }
79
80 ensure_parent_directory(dest);
81
82 std::error_code remove_error;
83 std::filesystem::remove(dest, remove_error);
84 if (remove_error) {
85 throw std::runtime_error(
86 "FileWriter: cannot replace output file '" + dest + "': " +
87 remove_error.message()
88 );
89 }
90
91 auto node = std::make_shared<DBNode>();
92 ParamBlockWriter().write(node, src);
93
94 const std::string extension = lower_extension(dest);
95 if (extension == ".json") {
96 JSONParser().writeToFile(dest, node);
97 } else if (extension == ".yaml" || extension == ".yml") {
98 YAMLParser().writeToFile(dest, node);
99 } else if (extension == ".lha" || extension == ".slha" || extension == ".flha") {
100 LhaParser().writeToFile(dest, node);
101 } else {
102 throw std::invalid_argument(
103 "FileWriter: unsupported output extension '" + extension +
104 "'; expected .json, .yaml, .yml, .lha, .slha or .flha"
105 );
106 }
107
108 std::error_code error;
109 const bool exists = std::filesystem::is_regular_file(dest, error);
110 if (error || !exists) {
111 throw std::runtime_error("FileWriter: output file was not created: " + dest);
112 }
113}
114
115void FileWriter::write(const std::string& dest, std::shared_ptr<BlockAccessor> src) {
116 write_accessor(dest, resolve_source(std::move(src)));
117}
118
120 const std::string& dest,
121 const std::vector<BlockName>& block_names,
122 std::shared_ptr<BlockAccessor> src
123) {
124 if (block_names.empty()) {
125 throw std::invalid_argument("FileWriter: block_names must not be empty");
126 }
127
128 const auto source = resolve_source(std::move(src));
129 auto selected = std::make_shared<BlockAccessor>();
130
131 for (const auto& block_name : block_names) {
132 if (!source->contains(block_name)) {
133 throw std::invalid_argument(
134 "FileWriter: requested block '" + block_name.canonical() + "' does not exist"
135 );
136 }
137 selected->emplace(block_name, source->at(block_name)->deep_clone_plain());
138 }
139
140 write_accessor(dest, selected);
141}
142
144 const std::string& dest,
145 const std::vector<ParamId>& parameter_ids,
146 std::shared_ptr<BlockAccessor> src
147) {
148 if (parameter_ids.empty()) {
149 throw std::invalid_argument("FileWriter: parameter_ids must not be empty");
150 }
151
152 const auto fallback = resolve_source(std::move(src));
153 auto selected = std::make_shared<BlockAccessor>();
154
155 for (const auto& parameter_id : parameter_ids) {
156 const auto source = source_for_parameter(parameter_id, fallback);
157 if (!source->has_param(parameter_id.block, parameter_id.code)) {
158 throw std::invalid_argument(
159 "FileWriter: requested parameter '" + parameter_id.block.canonical() +
160 "/" + parameter_id.code.to_string() + "' does not exist"
161 );
162 }
163
164 if (!selected->contains(parameter_id.block)) {
165 auto block = std::make_shared<Block>();
166 block->blockname = parameter_id.block;
167
168 const auto source_block = source->at(parameter_id.block);
169 if (source_block->has_scale()) {
170 block->set_scale(source_block->get_scale());
171 }
172 selected->emplace(parameter_id.block, block);
173 }
174
175 auto destination_block = selected->at(parameter_id.block);
176 if (!destination_block->contains(parameter_id.code)) {
177 const auto source_parameter = source->getParameter(
178 parameter_id.block,
179 parameter_id.code
180 );
181 destination_block->store(
182 parameter_id.code,
183 std::make_shared<Parameter>(*source_parameter)
184 );
185 }
186 }
187
188 write_accessor(dest, selected);
189}
Export the current HyperIso parameter database to JSON, YAML or LHA.
Lightweight JSON parser/serializer for DBNode trees.
Parser for LHA / FLHA-style files into LhaBlock structures and DBNode trees.
Manages memory caching, parameter blocks, and LHA reader instances.
Write parameter blocks from a BlockAccessor into a DBNode.
Model-dependent parameter repository and initialization strategies.
Lightweight YAML parser/serializer for DBNode trees.
const std::string & canonical() const
Definition BlockName.cpp:26
void write_blocks(const std::string &dest, const std::vector< BlockName > &block_names, std::shared_ptr< BlockAccessor > src=nullptr)
Export only the requested blocks.
void write_parameters(const std::string &dest, const std::vector< ParamId > &parameter_ids, std::shared_ptr< BlockAccessor > src=nullptr)
Export only the requested block/id parameters.
void write(const std::string &dest, std::shared_ptr< BlockAccessor > src=nullptr) override
Export all blocks from an accessor or from the current database.
JSON implementation of the IParser interface.
Definition JsonParser.h:42
void writeToFile(const std::string &filename, const std::shared_ptr< DBNode > &root) const override
Serializes a DBNode tree to a JSON file.
Parser for LHA/FLHA files, producing blocks and a DBNode representation.
Definition LhaParser.h:113
void writeToFile(const std::string &filename, const std::shared_ptr< DBNode > &root) const
Serializes a DBNode structure back to an LHA-like file.
static MemoryManager * GetInstance()
Retrieves the singleton instance of MemoryManager.
Writer class to populate a DbNode from a BlockAccessor.
void write(std::shared_ptr< DBNode > dest, std::shared_ptr< BlockAccessor > src) override
Write node parameters from a BlockAccessor into the given destination node.
static std::shared_ptr< Parameters > GetInstance(ParameterType id=ParameterType::SM)
Returns the singleton-like repository for a given parameter type.
YAML implementation of the IParser interface.
Definition YamlParser.h:39
void writeToFile(const std::string &filename, const std::shared_ptr< DBNode > &root) const override
Writes a DBNode hierarchy to a YAML file.
std::string to_string() const
Returns the canonical string representation of this LhaID.
Definition LhaID.cpp:19
Composite identifier for a single parameter.
Definition ParamID.h:57
std::optional< ParameterType > type
Optional high-level parameter category.
Definition ParamID.h:65
BlockName block
Name of the block where the parameter is stored.
Definition ParamID.h:73
LhaID code
Index or multi-index of the parameter inside the block.
Definition ParamID.h:82