28 std::complex<double> value,
30 const std::string& fileName) {
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();
39 if (fileExists && file.is_open()) {
41 bool isFirstLine =
true;
43 while (std::getline(file, line)) {
44 auto tokens =
split(line,
',');
49 data.push_back(tokens);
50 qMatchRowMap[std::stod(tokens[0])] = data.size() - 1;
54 for (
const auto& header : headers) {
55 if (header == coefficientName +
"_real" || header == coefficientName +
"_img") {
56 coefficientExists =
true;
63 headers.push_back(
"Q_match");
66 if (!coefficientExists) {
67 headers.push_back(coefficientName +
"_real");
68 headers.push_back(coefficientName +
"_img");
70 for (
auto& row : data) {
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"));
81 std::stringstream ss_r;
82 ss_r << std::scientific << value.real();
83 data[rowIndex][realIndex] = ss_r.str();
85 std::stringstream ss_i;
86 ss_i << std::scientific << value.imag();
87 data[rowIndex][imgIndex] = ss_i.str();
89 std::vector<std::string> newRow(headers.size(),
"NaN");
91 newRow[0] = std::to_string(Q_match);
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"));
96 std::stringstream ss_r;
97 ss_r << std::scientific << value.real();
98 newRow[realIndex] = ss_r.str();
100 std::stringstream ss_i;
101 ss_i << std::scientific << value.imag();
102 newRow[imgIndex] = ss_i.str();
104 data.push_back(newRow);
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));
116 std::ofstream outFile(tempFile, std::ios::trunc);
118 throw std::runtime_error(
"Cannot open temporary Wilson CSV: " + tempFile.string());
121 for (
size_t i = 0; i < headers.size(); ++i) {
122 outFile << headers[i];
123 if (i < headers.size() - 1) {
129 for (
const auto& row : data) {
130 for (
size_t i = 0; i < row.size(); ++i) {
132 if (i < row.size() - 1) {
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());
148 std::filesystem::rename(tempFile, destination, 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()
160 std::map<std::string, csl::InitSanitizer<real_t>*>& real,
161 std::map<std::string, csl::InitSanitizer<complex_t>*>& complex) {
164 std::map<std::string, std::complex<double>> complex_;
166 while (std::getline(inputFile, line)) {
167 std::istringstream iss(line);
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];
180 complex_[baseKey] = std::complex<double>(value, 0);
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];
187 complex_[baseKey] = std::complex<double>(0, value);
191 std::cerr <<
"Warning: Complex parameter " << baseKey <<
" not found in the map." << std::endl;
195 std::cout <<
"key : " << key << std::endl;
196 std::cout <<
"value : " << value << std::endl;
200 std::cerr <<
"Warning: Real parameter " << key <<
" not found in the map." << std::endl;