Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
csv_helper.cpp
Go to the documentation of this file.
1#include <fstream>
2#include <iostream>
3#include <sstream>
4#include <vector>
5#include <string>
6#include <map>
7#include <complex>
8#include <algorithm>
9#include <atomic>
10#include <chrono>
11#include <filesystem>
12#include <functional>
13#include <stdexcept>
14#include <thread>
15#include "csv_helper.h"
16
17std::vector<std::string> split(const std::string& s, char delimiter) {
18 std::vector<std::string> tokens;
19 std::string token;
20 std::istringstream tokenStream(s);
21 while (std::getline(tokenStream, token, delimiter)) {
22 tokens.push_back(token);
23 }
24 return tokens;
25}
26
27void writeWilsonCoefficients(const std::string& coefficientName,
28 std::complex<double> value,
29 double Q_match,
30 const std::string& fileName) {
31
32 std::ifstream file(fileName);
33 std::vector<std::vector<std::string>> data;
34 std::vector<std::string> headers;
35 std::map<double, int> qMatchRowMap;
36 bool coefficientExists = false;
37 bool fileExists = file.good();
38
39 if (fileExists && file.is_open()) {
40 std::string line;
41 bool isFirstLine = true;
42
43 while (std::getline(file, line)) {
44 auto tokens = split(line, ',');
45 if (isFirstLine) {
46 headers = tokens;
47 isFirstLine = false;
48 } else {
49 data.push_back(tokens);
50 qMatchRowMap[std::stod(tokens[0])] = data.size() - 1;
51 }
52 }
53
54 for (const auto& header : headers) {
55 if (header == coefficientName + "_real" || header == coefficientName + "_img") {
56 coefficientExists = true;
57 break;
58 }
59 }
60
61 file.close();
62 } else {
63 headers.push_back("Q_match");
64 }
65
66 if (!coefficientExists) {
67 headers.push_back(coefficientName + "_real");
68 headers.push_back(coefficientName + "_img");
69
70 for (auto& row : data) {
71 row.push_back("NaN");
72 row.push_back("NaN");
73 }
74 }
75
76 if (qMatchRowMap.find(Q_match) != qMatchRowMap.end()) {
77 int rowIndex = qMatchRowMap[Q_match];
78 int realIndex = std::distance(headers.begin(), std::find(headers.begin(), headers.end(), coefficientName + "_real"));
79 int imgIndex = std::distance(headers.begin(), std::find(headers.begin(), headers.end(), coefficientName + "_img"));
80
81 std::stringstream ss_r;
82 ss_r << std::scientific << value.real();
83 data[rowIndex][realIndex] = ss_r.str();
84
85 std::stringstream ss_i;
86 ss_i << std::scientific << value.imag();
87 data[rowIndex][imgIndex] = ss_i.str();
88 } else {
89 std::vector<std::string> newRow(headers.size(), "NaN");
90
91 newRow[0] = std::to_string(Q_match);
92
93 int realIndex = std::distance(headers.begin(), std::find(headers.begin(), headers.end(), coefficientName + "_real"));
94 int imgIndex = std::distance(headers.begin(), std::find(headers.begin(), headers.end(), coefficientName + "_img"));
95
96 std::stringstream ss_r;
97 ss_r << std::scientific << value.real();
98 newRow[realIndex] = ss_r.str();
99
100 std::stringstream ss_i;
101 ss_i << std::scientific << value.imag();
102 newRow[imgIndex] = ss_i.str();
103
104 data.push_back(newRow);
105 }
106
107 static std::atomic<unsigned long long> temp_counter {0};
108 const auto stamp = std::chrono::steady_clock::now().time_since_epoch().count();
109 const auto thread_hash = std::hash<std::thread::id>{}(std::this_thread::get_id());
110 const std::filesystem::path destination(fileName);
111 const std::filesystem::path tempFile = fileName + ".tmp."
112 + std::to_string(stamp) + "."
113 + std::to_string(thread_hash) + "."
114 + std::to_string(temp_counter.fetch_add(1, std::memory_order_relaxed));
115
116 std::ofstream outFile(tempFile, std::ios::trunc);
117 if (!outFile) {
118 throw std::runtime_error("Cannot open temporary Wilson CSV: " + tempFile.string());
119 }
120
121 for (size_t i = 0; i < headers.size(); ++i) {
122 outFile << headers[i];
123 if (i < headers.size() - 1) {
124 outFile << ",";
125 }
126 }
127 outFile << "\n";
128
129 for (const auto& row : data) {
130 for (size_t i = 0; i < row.size(); ++i) {
131 outFile << row[i];
132 if (i < row.size() - 1) {
133 outFile << ",";
134 }
135 }
136 outFile << "\n";
137 }
138
139 outFile.flush();
140 if (!outFile) {
141 std::error_code cleanup_ec;
142 std::filesystem::remove(tempFile, cleanup_ec);
143 throw std::runtime_error("Failed while writing Wilson CSV: " + tempFile.string());
144 }
145 outFile.close();
146
147 std::error_code ec;
148 std::filesystem::rename(tempFile, destination, ec);
149 if (ec) {
150 std::error_code cleanup_ec;
151 std::filesystem::remove(tempFile, cleanup_ec);
152 throw std::runtime_error(
153 "Cannot atomically publish Wilson CSV " + destination.string() + ": " + ec.message()
154 );
155 }
156}
157
158
159void readParams(std::ifstream& inputFile,
160 std::map<std::string, csl::InitSanitizer<real_t>*>& real,
161 std::map<std::string, csl::InitSanitizer<complex_t>*>& complex) {
162
163 std::string line;
164 std::map<std::string, std::complex<double>> complex_;
165
166 while (std::getline(inputFile, line)) {
167 std::istringstream iss(line);
168 std::string key;
169 double value;
170
171 if (std::getline(iss, key, ',') && iss >> value) {
172 if (key.size() > 4 && (key.substr(key.size() - 4) == "_rel" || key.substr(key.size() - 4) == "_img")) {
173 std::string baseKey = key.substr(0, key.size() - 4);
174 if (complex.find(baseKey) != complex.end()) {
175 if (key.substr(key.size() - 4) == "_rel") {
176 if (complex_.find(baseKey) != complex_.end()) {
177 complex_[baseKey] += std::complex<double>(value, 0);
178 *complex[baseKey] = complex_[baseKey];
179 } else {
180 complex_[baseKey] = std::complex<double>(value, 0);
181 }
182 } else if (key.substr(key.size() - 4) == "_img") {
183 if (complex_.find(baseKey) != complex_.end()) {
184 complex_[baseKey] += std::complex<double>(0, value);
185 *complex[baseKey] = complex_[baseKey];
186 } else {
187 complex_[baseKey] = std::complex<double>(0, value);
188 }
189 }
190 } else {
191 std::cerr << "Warning: Complex parameter " << baseKey << " not found in the map." << std::endl;
192 }
193
194 } else {
195 std::cout << "key : " << key << std::endl;
196 std::cout << "value : " << value << std::endl;
197 if (real.find(key) != real.end()) {
198 *real[key] = value;
199 } else {
200 std::cerr << "Warning: Real parameter " << key << " not found in the map." << std::endl;
201 }
202 }
203 }
204 }
205}
std::vector< std::string > split(const std::string &s, char delimiter)
Splits a string into parts using a single-character delimiter.
void writeWilsonCoefficients(const std::string &coefficientName, std::complex< double > value, double Q_match, const std::string &fileName)
void readParams(std::ifstream &inputFile, std::map< std::string, csl::InitSanitizer< real_t > * > &real, std::map< std::string, csl::InitSanitizer< complex_t > * > &complex)
double real(const scalar_t &z)
Definition scalar.cpp:83