23 std::ifstream file(json_path);
24 if (!file.is_open()) {
25 std::cerr <<
"[" <<
sensor_type_ <<
" Cal] Failed to open JSON: " << json_path << std::endl;
29 std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
34 root = nlohmann::json::parse(content);
35 }
catch (
const std::exception& e) {
36 std::cerr <<
"[" <<
sensor_type_ <<
" Cal] JSON parse error in " << json_path <<
": "
37 << e.what() << std::endl;
48 const std::string own_key =
49 sensor_type_ ==
"LC" ?
"lc_calibration_polynomials" :
"calibration_polynomials";
50 const nlohmann::json& poly =
51 (root.contains(own_key) && root[own_key].is_object() && !root[own_key].empty())
53 : (root.contains(
"calibration_polynomials") && root[
"calibration_polynomials"].is_object())
54 ? root[
"calibration_polynomials"]
56 if (!poly.is_object())
59 auto is_numeric = [](
const std::string& s) {
60 return !s.empty() && std::all_of(s.begin(), s.end(), [](
unsigned char c) {
61 return std::isdigit(c) != 0;
66 for (
const auto& [ch_str, arr] : poly.items()) {
67 if (!is_numeric(ch_str) || !arr.is_array() || arr.empty())
69 std::vector<double> coeffs;
71 for (
const auto& e : arr) {
76 coeffs.push_back(e.get<
double>());
78 if (!
ok || coeffs.empty())
80 const uint8_t channel_id =
static_cast<uint8_t
>(std::stoi(ch_str));
86 std::cout <<
"[" <<
sensor_type_ <<
" Cal] Loaded " << loaded
87 <<
" calibrations from JSON: " << json_path << std::endl;
93 std::ifstream file(csv_path);
94 if (!file.is_open()) {
95 std::cerr <<
"[" <<
sensor_type_ <<
" Cal] Failed to open CSV: " << csv_path << std::endl;
100 std::string header_line;
101 std::getline(file, header_line);
105 std::string pattern =
sensor_type_ +
"(\\d+)\\s+Coefficient\\s+(\\d+)";
106 std::regex col_regex(pattern, std::regex_constants::icase);
109 std::map<uint8_t, std::map<int, int>> channel_coeff_cols;
111 std::istringstream ss(header_line);
114 while (std::getline(ss, col,
',')) {
116 if (std::regex_search(col, m, col_regex)) {
117 uint8_t
ch =
static_cast<uint8_t
>(std::stoi(m[1].str()));
118 int coeff_idx = std::stoi(m[2].str());
119 channel_coeff_cols[
ch][coeff_idx] = col_idx;
126 std::vector<std::vector<std::string>> rows;
128 while (std::getline(file, line)) {
131 std::vector<std::string> row;
132 std::istringstream ss(line);
134 while (std::getline(ss, cell,
','))
141 const auto& last_row = rows.back();
143 for (
const auto& [
ch, coeff_map] : channel_coeff_cols) {
144 std::vector<double> coeffs(coeff_map.size(), 0.0);
146 for (
const auto& [ci, col] : coeff_map) {
147 if (col >=
static_cast<int>(last_row.size())) {
152 if (ci <
static_cast<int>(coeffs.size()))
153 coeffs[ci] = std::stod(last_row[col]);
159 if (
ok && !coeffs.empty()) {
166 <<
" calibrations from CSV: " << csv_path << std::endl;