CPPxDIC
C++ Digital Image Correlation library for fingertip 3D reconstruction
Loading...
Searching...
No Matches
config.cpp
Go to the documentation of this file.
1
5#include "config.h"
6#include "logging.h"
7#include <iostream>
8#include <filesystem>
9#include <fstream>
10#include <sstream>
11#include <algorithm>
12
14 // Set step_e defaults (matching uses larger radius)
15 step_e.radius = 60;
16}
17
19 // Set default paths if not explicitly set from config file
20 setDefaultPaths();
21 if (data_path.empty()) {
22 data_path = base_path + "/example_data";
23 }
24 if (dic_path.empty()) {
25 dic_path = base_path + "/analysis";
26 }
27
28 // Update material name from material_id
29 if (material_id >= 1 && material_id <= static_cast<int>(frictional_conditions.size())) {
30 material = frictional_conditions[material_id - 1]; // Convert to 0-based index
31 } else {
32 material = "unknown";
33 LOG_WARN << "Invalid material_id " << material_id;
34 }
35
36 LOG_INFO << "Variables updated. Material: " << material;
37}
38
39void Config::setDefaultPaths() {
40 // Set base path to current working directory or a reasonable default
41 if (std::filesystem::exists(base_path)) return;
42 try {
43 base_path = std::filesystem::current_path().string();
44 } catch (const std::exception& e) {
45 base_path = ".";
46 LOG_WARN << "Could not get current path, using '.' as base_path";
47 }
48}
49
50// Helper function to parse config value from line
51std::string Config::parseConfigValue(const std::string& line, const std::string& key) {
52 size_t eq_pos = line.find('=');
53 if (eq_pos == std::string::npos) return "";
54
55 std::string line_key = line.substr(0, eq_pos);
56 // Trim whitespace from key
57 line_key.erase(0, line_key.find_first_not_of(" \t"));
58 line_key.erase(line_key.find_last_not_of(" \t") + 1);
59
60 if (line_key != key) return "";
61
62 std::string value = line.substr(eq_pos + 1);
63 // Trim whitespace from value
64 value.erase(0, value.find_first_not_of(" \t"));
65 value.erase(value.find_last_not_of(" \t") + 1);
66
67 return value;
68}
69
70// Parse comma-separated string list
71std::vector<std::string> Config::parseStringList(const std::string& value) {
72 std::vector<std::string> result;
73 std::stringstream ss(value);
74 std::string item;
75 while (std::getline(ss, item, ',')) {
76 // Trim whitespace
77 item.erase(0, item.find_first_not_of(" \t"));
78 item.erase(item.find_last_not_of(" \t") + 1);
79 if (!item.empty()) {
80 result.push_back(item);
81 }
82 }
83 return result;
84}
85
86// Parse comma-separated int list
87std::vector<int> Config::parseIntList(const std::string& value) {
88 std::vector<int> result;
89 std::stringstream ss(value);
90 std::string item;
91 while (std::getline(ss, item, ',')) {
92 try {
93 result.push_back(std::stoi(item));
94 } catch (...) {
95 LOG_WARN << "Could not parse int value: " << item;
96 }
97 }
98 return result;
99}
100
101// Parse comma-separated double list
102std::vector<double> Config::parseDoubleList(const std::string& value) {
103 std::vector<double> result;
104 std::stringstream ss(value);
105 std::string item;
106 while (std::getline(ss, item, ',')) {
107 try {
108 result.push_back(std::stod(item));
109 } catch (...) {
110 LOG_WARN << "Could not parse double value: " << item;
111 }
112 }
113 return result;
114}
115
116// Parse boolean value
117bool Config::parseBool(const std::string& value) {
118 std::string lower_value = value;
119 std::transform(lower_value.begin(), lower_value.end(), lower_value.begin(), ::tolower);
120 return (lower_value == "true" || lower_value == "1" || lower_value == "yes");
121}
122
123// Load DIC parameters from file
124bool Config::loadFromDicParamsFile(const std::string& filepath) {
125 if (!std::filesystem::exists(filepath)) {
126 LOG_INFO << "DIC params file not found: " << filepath << ", using defaults";
127 return false;
128 }
129
130 std::ifstream file(filepath);
131 if (!file.is_open()) {
132 LOG_WARN << "Could not open DIC params file: " << filepath;
133 return false;
134 }
135
136 LOG_INFO << "Loading DIC parameters from: " << filepath;
137
138 std::string line;
139 while (std::getline(file, line)) {
140 // Skip empty lines and comments
141 if (line.empty() || line[0] == '#') continue;
142
143 // Remove leading/trailing whitespace
144 line.erase(0, line.find_first_not_of(" \t"));
145 if (line.empty() || line[0] == '#') continue;
146
147 // Parse each parameter
148 std::string value;
149
150 // Global parameters
151 if (!(value = parseConfigValue(line, "frictional_conditions")).empty()) {
152 frictional_conditions = parseStringList(value);
153 } else if (!(value = parseConfigValue(line, "num_pair")).empty()) {
154 num_pair = std::stoi(value);
155 } else if (!(value = parseConfigValue(line, "mirrored_num_pair")).empty()) {
156 mirrored_num_pair = std::stoi(value);
157 } else if (!(value = parseConfigValue(line, "mirrored_cam_order")).empty()) {
158 mirrored_cam_order = parseIntList(value);
159 } else if (!(value = parseConfigValue(line, "robot_sample_freq")).empty()) {
160 robot_sample_freq = std::stod(value);
161 } else if (!(value = parseConfigValue(line, "vid_sample_freq")).empty()) {
162 vid_sample_freq = std::stod(value);
163 }
164 // Path definitions
165 else if (!(value = parseConfigValue(line, "base_path")).empty()) {
166 base_path = value;
167 } else if (!(value = parseConfigValue(line, "data_path")).empty()) {
168 if (!value.empty()) data_path = value;
169 } else if (!(value = parseConfigValue(line, "dic_path")).empty()) {
170 if (!value.empty()) dic_path = value;
171 }
172 // Processing flags
173 else if (!(value = parseConfigValue(line, "im_filter_mode")).empty()) {
174 im_filter_mode = parseBool(value);
175 } else if (!(value = parseConfigValue(line, "im_saturation_mode")).empty()) {
176 im_saturation_mode = parseBool(value);
177 } else if (!(value = parseConfigValue(line, "force_frame_window")).empty()) {
178 force_frame_window = parseBool(value);
179 } else if (!(value = parseConfigValue(line, "automatic_process")).empty()) {
180 automatic_process = parseBool(value);
181 } else if (!(value = parseConfigValue(line, "parallel_processing")).empty()) {
182 parallel_processing = parseBool(value);
183 } else if (!(value = parseConfigValue(line, "debug_mode")).empty()) {
184 debug_mode = parseBool(value);
185 } else if (!(value = parseConfigValue(line, "log_level")).empty()) {
186 log_level = value;
187 } else if (!(value = parseConfigValue(line, "log_file")).empty()) {
188 log_file = value;
189 }
190 // DIC analysis parameters
191 else if (!(value = parseConfigValue(line, "subject_id")).empty()) {
192 subject_id = value;
193 } else if (!(value = parseConfigValue(line, "phase_id")).empty()) {
194 phase_id = value;
195 } else if (!(value = parseConfigValue(line, "material_id")).empty()) {
196 material_id = std::stoi(value);
197 } else if (!(value = parseConfigValue(line, "nfcond_set")).empty()) {
198 nfcond_set = parseIntList(value);
199 } else if (!(value = parseConfigValue(line, "spddxlcond_set")).empty()) {
200 spddxlcond_set = parseDoubleList(value);
201 } else if (!(value = parseConfigValue(line, "calib_folder_set")).empty()) {
202 calib_folder_set = value;
203 } else if (!(value = parseConfigValue(line, "ref_trial_id")).empty()) {
204 ref_trial_id = std::stoi(value);
205 }
206 // Frame settings
207 else if (!(value = parseConfigValue(line, "idx_frame_start")).empty()) {
208 idx_frame_start = std::stoi(value);
209 } else if (!(value = parseConfigValue(line, "idx_frame_end")).empty()) {
210 idx_frame_end = std::stoi(value);
211 } else if (!(value = parseConfigValue(line, "frame_jump")).empty()) {
212 frame_jump = std::stoi(value);
213 }
214 // Units and calibration
215 else if (!(value = parseConfigValue(line, "units_per_pixel")).empty()) {
216 units_per_pixel = std::stod(value);
217 } else if (!(value = parseConfigValue(line, "subregion_radius")).empty()) {
218 subregion_radius = std::stoi(value);
219 }
220 // Units and calibration
221 else if (!(value = parseConfigValue(line, "limit_grayscale")).empty()) {
222 limit_grayscale = std::stoi(value);
223 }
224 // Output control
225 else if (!(value = parseConfigValue(line, "fileversion")).empty()) {
226 fileversion = value;
227 } else if (!(value = parseConfigValue(line, "data_format")).empty()) {
228 data_format = value;
229 }
230 // Step D parameters
231 else if (!(value = parseConfigValue(line, "step_d_analysis_type")).empty()) {
232 step_d.analysis_type = value;
233 } else if (!(value = parseConfigValue(line, "step_d_radius")).empty()) {
234 step_d.radius = std::stoi(value);
235 } else if (!(value = parseConfigValue(line, "step_d_spacing")).empty()) {
236 step_d.spacing = std::stoi(value);
237 } else if (!(value = parseConfigValue(line, "step_d_cutoff_diffnorm")).empty()) {
238 step_d.cutoff_diffnorm = std::stod(value);
239 } else if (!(value = parseConfigValue(line, "step_d_cutoff_iteration")).empty()) {
240 step_d.cutoff_iteration = std::stoi(value);
241 } else if (!(value = parseConfigValue(line, "step_d_total_threads")).empty()) {
242 step_d.total_threads = std::stoi(value);
243 } else if (!(value = parseConfigValue(line, "step_d_high_strain_enabled")).empty()) {
244 step_d.high_strain_enabled = parseBool(value);
245 } else if (!(value = parseConfigValue(line, "step_d_seed_type")).empty()) {
246 step_d.seed_type = value;
247 } else if (!(value = parseConfigValue(line, "step_d_auto_update")).empty()) {
248 step_d.auto_update = parseBool(value);
249 } else if (!(value = parseConfigValue(line, "step_d_step_ref_change")).empty()) {
250 step_d.step_ref_change = std::stoi(value);
251 } else if (!(value = parseConfigValue(line, "step_d_initial_seed")).empty()) {
252 step_d.initial_seed = parseIntList(value);
253 }
254 // Step E parameters
255 else if (!(value = parseConfigValue(line, "step_e_analysis_type")).empty()) {
256 step_e.analysis_type = value;
257 } else if (!(value = parseConfigValue(line, "step_e_radius")).empty()) {
258 step_e.radius = std::stoi(value);
259 } else if (!(value = parseConfigValue(line, "step_e_spacing")).empty()) {
260 step_e.spacing = std::stoi(value);
261 } else if (!(value = parseConfigValue(line, "step_e_cutoff_diffnorm")).empty()) {
262 step_e.cutoff_diffnorm = std::stod(value);
263 } else if (!(value = parseConfigValue(line, "step_e_cutoff_iteration")).empty()) {
264 step_e.cutoff_iteration = std::stoi(value);
265 } else if (!(value = parseConfigValue(line, "step_e_total_threads")).empty()) {
266 step_e.total_threads = std::stoi(value);
267 } else if (!(value = parseConfigValue(line, "step_e_high_strain_enabled")).empty()) {
268 step_e.high_strain_enabled = parseBool(value);
269 } else if (!(value = parseConfigValue(line, "step_e_seed_type")).empty()) {
270 step_e.seed_type = value;
271 } else if (!(value = parseConfigValue(line, "step_e_auto_update")).empty()) {
272 step_e.auto_update = parseBool(value);
273 } else if (!(value = parseConfigValue(line, "step_e_step_ref_change")).empty()) {
274 step_e.step_ref_change = std::stoi(value);
275 } else if (!(value = parseConfigValue(line, "step_e_initial_seed")).empty()) {
276 step_e.initial_seed = parseIntList(value);
277 }
278 // Step F parameters
279 else if (!(value = parseConfigValue(line, "step_f_analysis_type")).empty()) {
280 step_f.analysis_type = value;
281 } else if (!(value = parseConfigValue(line, "step_f_radius")).empty()) {
282 step_f.radius = std::stoi(value);
283 } else if (!(value = parseConfigValue(line, "step_f_spacing")).empty()) {
284 step_f.spacing = std::stoi(value);
285 } else if (!(value = parseConfigValue(line, "step_f_cutoff_diffnorm")).empty()) {
286 step_f.cutoff_diffnorm = std::stod(value);
287 } else if (!(value = parseConfigValue(line, "step_f_cutoff_iteration")).empty()) {
288 step_f.cutoff_iteration = std::stoi(value);
289 } else if (!(value = parseConfigValue(line, "step_f_total_threads")).empty()) {
290 step_f.total_threads = std::stoi(value);
291 } else if (!(value = parseConfigValue(line, "step_f_high_strain_enabled")).empty()) {
292 step_f.high_strain_enabled = parseBool(value);
293 } else if (!(value = parseConfigValue(line, "step_f_seed_type")).empty()) {
294 step_f.seed_type = value;
295 } else if (!(value = parseConfigValue(line, "step_f_auto_update")).empty()) {
296 step_f.auto_update = parseBool(value);
297 } else if (!(value = parseConfigValue(line, "step_f_step_ref_change")).empty()) {
298 step_f.step_ref_change = std::stoi(value);
299 } else if (!(value = parseConfigValue(line, "step_f_initial_seed")).empty()) {
300 step_f.initial_seed = parseIntList(value);
301 }
302 // Step E specific parameters (3D reconstruction)
303 else if (!(value = parseConfigValue(line, "step_e_ray_bvh")).empty()) {
304 step_e_ray_bvh = parseBool(value);
305 } else if (!(value = parseConfigValue(line, "step_e_stitch_mode")).empty()) {
306 std::string m = value; std::transform(m.begin(), m.end(), m.begin(), ::tolower);
307 if (m == "geometric" || m == "simple") step_e_stitch_mode = m;
308 else LOG_WARN << "Unknown step_e_stitch_mode '" << value << "' (geometric|simple), keeping " << step_e_stitch_mode;
309 } else if (!(value = parseConfigValue(line, "step_e_distortion_removal")).empty()) {
310 step_e_distortion_removal = parseBool(value);
311 } else if (!(value = parseConfigValue(line, "step_d_replacebadcorr")).empty()) {
312 step_d_replacebadcorr = parseBool(value);
313 }
314 // Camera pairs mapping (format: "1,2;4,3" for pair1=(1,2), pair2=(4,3))
315 else if (!(value = parseConfigValue(line, "camera_pairs")).empty()) {
316 camera_pairs.clear();
317 // Parse semicolon-separated pairs, each pair is "cam1,cam2"
318 std::istringstream pairs_stream(value);
319 std::string pair_str;
320 while (std::getline(pairs_stream, pair_str, ';')) {
321 auto comma_pos = pair_str.find(',');
322 if (comma_pos != std::string::npos) {
323 int c1 = std::stoi(pair_str.substr(0, comma_pos));
324 int c2 = std::stoi(pair_str.substr(comma_pos + 1));
325 camera_pairs.push_back({c1, c2});
326 }
327 }
328 }
329 // Step F specific parameters (deformation analysis)
330 else if (!(value = parseConfigValue(line, "step_f_temporal_filtering")).empty()) {
331 step_f_temporal_filtering = parseBool(value);
332 } else if (!(value = parseConfigValue(line, "step_f_freq_filt")).empty()) {
333 step_f_freq_filt = std::stod(value);
334 } else if (!(value = parseConfigValue(line, "step_f_compute_rbm")).empty()) {
335 step_f_compute_rbm = parseBool(value);
336 }
337 }
338
339 file.close();
340 LOG_INFO << "DIC parameters loaded from file";
341 return true;
342}
343
344// Load NCorr parameters from file (overrides DIC params where applicable)
345bool Config::loadFromNcorrParamsFile(const std::string& filepath) {
346 if (!std::filesystem::exists(filepath)) {
347 LOG_INFO << "NCorr params file not found: " << filepath << ", skipping";
348 return false;
349 }
350
351 std::ifstream file(filepath);
352 if (!file.is_open()) {
353 LOG_WARN << "Could not open NCorr params file: " << filepath;
354 return false;
355 }
356
357 LOG_INFO << "Loading NCorr parameters from: " << filepath;
358
359 std::string line;
360 while (std::getline(file, line)) {
361 // Skip empty lines and comments
362 if (line.empty() || line[0] == '#') continue;
363
364 line.erase(0, line.find_first_not_of(" \t"));
365 if (line.empty() || line[0] == '#') continue;
366
367 std::string value;
368
369 if (!(value = parseConfigValue(line, "units_per_pixel")).empty()) {
370 units_per_pixel = std::stod(value);
371 } else if (!(value = parseConfigValue(line, "radius")).empty()) {
372 subregion_radius = std::stoi(value);
373 } else if (!(value = parseConfigValue(line, "debug")).empty()) {
374 debug_mode = parseBool(value);
375 } else if (!(value = parseConfigValue(line, "threads")).empty()) {
376 ncorr_threads = std::stoi(value);
377 } else if (!(value = parseConfigValue(line, "maxCorrCoeff")).empty()) {
378 maxCorrCoeff = std::stod(value);
379 } else if (!(value = parseConfigValue(line, "scalefactor")).empty()) {
380 ncorr_scalefactor = std::stoi(value);
381 } else if (!(value = parseConfigValue(line, "interp")).empty()) {
382 ncorr_interp = value;
383 } else if (!(value = parseConfigValue(line, "subregion")).empty()) {
384 ncorr_subregion = value;
385 } else if (!(value = parseConfigValue(line, "dic_config")).empty()) {
386 ncorr_dic_config = value;
387 } else if (!(value = parseConfigValue(line, "cutoff_corrcoef")).empty()) {
388 ncorr_cutoff_corrcoef = std::stod(value);
389 } else if (!(value = parseConfigValue(line, "roi_update_mode")).empty()) {
390 ncorr_roi_update_mode = value;
391 } else if (!(value = parseConfigValue(line, "accumulation_mode")).empty()) {
393 } else if (!(value = parseConfigValue(line, "save_disps_steps")).empty()) {
394 ncorr_save_disps_steps = parseBool(value);
395 } else if (!(value = parseConfigValue(line, "perspective_interp")).empty()) {
396 ncorr_perspective_interp = parseBool(value);
397 } else if (!(value = parseConfigValue(line, "units")).empty()) {
398 ncorr_units = value;
399 } else if (!(value = parseConfigValue(line, "seeds_are_optimized")).empty()) {
400 ncorr_seeds_are_optimized = parseBool(value);
401 } else if (!(value = parseConfigValue(line, "cutoff_max_diffnorm")).empty()) {
402 ncorr_cutoff_max_diffnorm = std::stod(value);
403 } else if (!(value = parseConfigValue(line, "cutoff_max_corrcoef")).empty()) {
404 ncorr_cutoff_max_corrcoef = std::stod(value);
405 } else if (!(value = parseConfigValue(line, "matching_cutoff_max_corrcoef")).empty()) {
406 ncorr_matching_cutoff_max_corrcoef = std::stod(value);
407 } else if (!(value = parseConfigValue(line, "use_exact_matlab")).empty()) {
408 ncorr_use_exact_matlab = parseBool(value);
409 } else if (!(value = parseConfigValue(line, "no_update")).empty()) {
410 ncorr_no_update = parseBool(value);
411 } else if (!(value = parseConfigValue(line, "fixed_step_ref")).empty()) {
412 ncorr_fixed_step_ref = std::stoi(value);
413 } else if (!(value = parseConfigValue(line, "dic_engine")).empty()) {
414 dic_engine = value;
415 } else if (!(value = parseConfigValue(line, "cuncorr_seed_search")).empty()) {
416 cuncorr_seed_search = std::stoi(value);
417 }
418 }
419
420 file.close();
421 LOG_INFO << "NCorr parameters loaded from file";
422 return true;
423}
424
425// Load visualization parameters from file
426bool Config::loadFromVisualizationParamsFile(const std::string& filepath) {
427 if (!std::filesystem::exists(filepath)) {
428 LOG_INFO << "Visualization params file not found: " << filepath << ", using defaults";
429 return false;
430 }
431
432 std::ifstream file(filepath);
433 if (!file.is_open()) {
434 LOG_WARN << "Could not open visualization params file: " << filepath;
435 return false;
436 }
437
438 LOG_INFO << "Loading visualization parameters from: " << filepath;
439
440 std::string line;
441 while (std::getline(file, line)) {
442 // Skip empty lines and comments
443 if (line.empty() || line[0] == '#') continue;
444
445 line.erase(0, line.find_first_not_of(" \t"));
446 if (line.empty() || line[0] == '#') continue;
447
448 std::string value;
449
450 // Visualization settings
451 if (!(value = parseConfigValue(line, "showvisu")).empty()) {
452 showvisu = parseBool(value);
453 } else if (!(value = parseConfigValue(line, "mapLogic")).empty()) {
454 mapLogic = parseBool(value);
455 } else if (!(value = parseConfigValue(line, "plotopt")).empty()) {
456 plotopt = parseStringList(value);
457 } else if (!(value = parseConfigValue(line, "deftype")).empty()) {
458 deftype = value;
459 } else if (!(value = parseConfigValue(line, "viewplot")).empty()) {
460 viewplot = value;
461 } else if (!(value = parseConfigValue(line, "contactAreaLogic")).empty()) {
462 contactAreaLogic = parseBool(value);
463 } else if (!(value = parseConfigValue(line, "gapLogic")).empty()) {
464 gapLogic = parseBool(value);
465 } else if (!(value = parseConfigValue(line, "maxCorrCoeff")).empty()) {
466 maxCorrCoeff = std::stod(value);
467 } else if (!(value = parseConfigValue(line, "format")).empty()) {
468 format = value;
469 }
470 // Filtering settings
471 else if (!(value = parseConfigValue(line, "smoothTimeLogic")).empty()) {
472 smoothTimeLogic = parseBool(value);
473 } else if (!(value = parseConfigValue(line, "filterFreq")).empty()) {
474 filterFreq = std::stod(value);
475 } else if (!(value = parseConfigValue(line, "smoothSpaceLogic")).empty()) {
476 smoothSpaceLogic = parseBool(value);
477 } else if (!(value = parseConfigValue(line, "smoothPar_n")).empty()) {
478 smoothPar_n = std::stoi(value);
479 } else if (!(value = parseConfigValue(line, "smoothPar_sigma")).empty()) {
480 smoothPar_sigma = std::stod(value);
481 }
482 // Additional plot settings
483 else if (!(value = parseConfigValue(line, "showRobotLogic")).empty()) {
484 showRobotLogic = parseBool(value);
485 } else if (!(value = parseConfigValue(line, "showImgLogic")).empty()) {
486 showImgLogic = parseBool(value);
487 } else if (!(value = parseConfigValue(line, "camNbr")).empty()) {
488 camNbr = std::stoi(value);
489 } else if (!(value = parseConfigValue(line, "tracesLogic")).empty()) {
490 tracesLogic = parseBool(value);
491 }
492 // Plot appearance
493 else if (!(value = parseConfigValue(line, "FaceAlpha")).empty()) {
494 FaceAlpha = std::stod(value);
495 } else if (!(value = parseConfigValue(line, "lineColor")).empty()) {
496 lineColor = value;
497 } else if (!(value = parseConfigValue(line, "quiverScaleFactor")).empty()) {
498 quiverScaleFactor = std::stod(value);
499 }
500 // Export settings
501 else if (!(value = parseConfigValue(line, "export_format")).empty()) {
502 export_format = value;
503 } else if (!(value = parseConfigValue(line, "export_each_frame")).empty()) {
504 export_each_frame = parseBool(value);
505 } else if (!(value = parseConfigValue(line, "export_frame_list")).empty()) {
506 export_frame_list = parseIntList(value);
507 }
508 // VTK export options
509 else if (!(value = parseConfigValue(line, "vtk_format")).empty()) {
510 vtk_format = value;
511 } else if (!(value = parseConfigValue(line, "vtk_include_scalars")).empty()) {
512 vtk_include_scalars = parseBool(value);
513 } else if (!(value = parseConfigValue(line, "vtk_include_vectors")).empty()) {
514 vtk_include_vectors = parseBool(value);
515 }
516 // PLY export options
517 else if (!(value = parseConfigValue(line, "ply_format")).empty()) {
518 ply_format = value;
519 } else if (!(value = parseConfigValue(line, "ply_include_colors")).empty()) {
520 ply_include_colors = parseBool(value);
521 }
522 // CSV export options
523 else if (!(value = parseConfigValue(line, "csv_delimiter")).empty()) {
524 csv_delimiter = value;
525 } else if (!(value = parseConfigValue(line, "csv_include_header")).empty()) {
526 csv_include_header = parseBool(value);
527 }
528 // Video options
529 else if (!(value = parseConfigValue(line, "generate_videos")).empty()) {
530 generate_videos = parseBool(value);
531 } else if (!(value = parseConfigValue(line, "video_fps")).empty()) {
532 video_fps = std::stoi(value);
533 } else if (!(value = parseConfigValue(line, "video_codec")).empty()) {
534 video_codec = value;
535 } else if (!(value = parseConfigValue(line, "video_quality")).empty()) {
536 // Accept both a numeric 0-100 value and the named presets shipped in
537 // visualization_params.txt ("high"/"medium"/"low"); a bare stoi on the
538 // default "high" used to throw and abort the run before any DIC work.
539 std::string q = value;
540 std::transform(q.begin(), q.end(), q.begin(), ::tolower);
541 if (q == "high" || q == "best") {
542 video_quality = 95;
543 } else if (q == "medium" || q == "normal") {
544 video_quality = 75;
545 } else if (q == "low") {
546 video_quality = 50;
547 } else {
548 try {
549 video_quality = std::stoi(q);
550 } catch (const std::exception&) {
551 LOG_WARN << "Invalid video_quality '" << value << "', keeping " << video_quality;
552 }
553 }
554 } else if (!(value = parseConfigValue(line, "video_alpha")).empty()) {
555 video_alpha = std::stod(value);
556 }
557 // Colormap options
558 else if (!(value = parseConfigValue(line, "colormap")).empty()) {
559 colormap = value;
560 } else if (!(value = parseConfigValue(line, "colormap_range_mode")).empty()) {
561 colormap_range_mode = value;
562 } else if (!(value = parseConfigValue(line, "colormap_min")).empty()) {
563 colormap_min = std::stod(value);
564 } else if (!(value = parseConfigValue(line, "colormap_max")).empty()) {
565 colormap_max = std::stod(value);
566 } else if (!(value = parseConfigValue(line, "colormap_levels")).empty()) {
567 colormap_levels = std::stoi(value);
568 }
569 // Statistics options
570 else if (!(value = parseConfigValue(line, "generate_summary_stats")).empty()) {
571 generate_summary_stats = parseBool(value);
572 } else if (!(value = parseConfigValue(line, "stats_format")).empty()) {
573 stats_format = value;
574 } else if (!(value = parseConfigValue(line, "stats_per_frame")).empty()) {
575 stats_per_frame = parseBool(value);
576 } else if (!(value = parseConfigValue(line, "stats_spatial")).empty()) {
577 stats_spatial = parseBool(value);
578 } else if (!(value = parseConfigValue(line, "stats_temporal")).empty()) {
579 stats_temporal = parseBool(value);
580 }
581 // Advanced visualization options
582 else if (!(value = parseConfigValue(line, "mesh_decimation")).empty()) {
583 mesh_decimation = std::stod(value);
584 } else if (!(value = parseConfigValue(line, "mesh_smoothing")).empty()) {
585 mesh_smoothing = parseBool(value);
586 } else if (!(value = parseConfigValue(line, "mesh_smoothing_iterations")).empty()) {
587 mesh_smoothing_iterations = std::stoi(value);
588 } else if (!(value = parseConfigValue(line, "show_axes")).empty()) {
589 show_axes = parseBool(value);
590 } else if (!(value = parseConfigValue(line, "show_colorbar")).empty()) {
591 show_colorbar = parseBool(value);
592 } else if (!(value = parseConfigValue(line, "show_grid")).empty()) {
593 show_grid = parseBool(value);
594 } else if (!(value = parseConfigValue(line, "background_color")).empty()) {
595 background_color = value;
596 }
597 }
598
599 file.close();
600 LOG_INFO << "Visualization parameters loaded from file";
601 return true;
602}
603
604// Load a single unified config file (config-file tier of the override chain).
605// Reuses the three existing per-file loaders; each only reacts to its own keys, so a
606// unified file containing any mix of DIC / NCorr / visualization keys is parsed correctly.
607bool Config::loadFromConfigFile(const std::string& filepath) {
608 if (!std::filesystem::exists(filepath)) {
609 LOG_INFO << "Config file not found: " << filepath
610 << ", using compiled defaults / per-file params";
611 return false;
612 }
613 LOG_INFO << "Loading unified config file: " << filepath;
614 // Order does not matter: the loaders key on disjoint parameter names.
615 loadFromDicParamsFile(filepath);
616 loadFromNcorrParamsFile(filepath);
618 return true;
619}
620
621// Override subject from command line
622void Config::overrideSubject(const std::string& subject) {
623 subject_id = subject;
624 LOG_INFO << "Subject overridden to: " << subject_id;
625}
626
627// Override reference trial from command line
629 ref_trial_id = trial;
630 LOG_INFO << "Reference trial overridden to: " << ref_trial_id;
631}
StepConfig step_e
Definition config.h:139
double smoothPar_sigma
Definition config.h:106
std::string dic_engine
Definition config.h:211
int mirrored_num_pair
Definition config.h:40
bool vtk_include_vectors
Definition config.h:217
bool showRobotLogic
Definition config.h:109
bool gapLogic
Definition config.h:97
int ref_trial_id
Definition config.h:75
bool generate_videos
Definition config.h:228
bool mesh_smoothing
Definition config.h:250
std::string dic_path
Definition config.h:48
bool step_e_distortion_removal
Definition config.h:157
void overrideSubject(const std::string &subject)
Definition config.cpp:622
std::string colormap
Definition config.h:235
std::vector< int > export_frame_list
Definition config.h:122
bool showvisu
Definition config.h:83
bool im_filter_mode
Definition config.h:51
double colormap_max
Definition config.h:238
bool mapLogic
Definition config.h:91
bool ncorr_perspective_interp
Definition config.h:185
bool step_f_compute_rbm
Definition config.h:165
std::string ncorr_roi_update_mode
Definition config.h:182
double vid_sample_freq
Definition config.h:43
bool step_e_ray_bvh
Definition config.h:156
std::string stats_format
Definition config.h:243
std::vector< int > mirrored_cam_order
Definition config.h:41
bool ncorr_seeds_are_optimized
Definition config.h:195
std::string viewplot
Definition config.h:94
int ncorr_threads
Definition config.h:202
std::string subject_id
Definition config.h:65
bool tracesLogic
Definition config.h:112
std::string format
Definition config.h:99
StepConfig step_f
Definition config.h:144
double colormap_min
Definition config.h:237
std::string step_e_stitch_mode
Definition config.h:151
bool ply_include_colors
Definition config.h:221
std::string ply_format
Definition config.h:220
void updateVariables()
Definition config.cpp:18
double step_f_freq_filt
Definition config.h:164
std::string material
Definition config.h:258
bool contactAreaLogic
Definition config.h:96
std::string ncorr_units
Definition config.h:190
bool loadFromDicParamsFile(const std::string &filepath="dic_params.txt")
Definition config.cpp:124
bool loadFromConfigFile(const std::string &filepath="config/default.cfg")
Load a single unified config file (the middle tier of the override chain).
Definition config.cpp:607
std::vector< std::pair< int, int > > camera_pairs
Definition config.h:37
int idx_frame_start
Definition config.h:78
int material_id
Definition config.h:67
std::string vtk_format
Definition config.h:215
int video_quality
Definition config.h:231
bool parallel_processing
Definition config.h:62
bool ncorr_save_disps_steps
Definition config.h:184
std::string export_format
Definition config.h:120
bool stats_temporal
Definition config.h:246
bool step_f_temporal_filtering
Definition config.h:163
int num_pair
Definition config.h:34
double filterFreq
Definition config.h:103
void overrideRefTrial(int trial)
Definition config.cpp:628
bool smoothTimeLogic
Definition config.h:102
double ncorr_cutoff_max_corrcoef
Definition config.h:197
std::string background_color
Definition config.h:255
bool show_colorbar
Definition config.h:253
std::vector< std::string > plotopt
Definition config.h:92
bool debug_mode
Definition config.h:84
int colormap_levels
Definition config.h:239
int ncorr_scalefactor
Definition config.h:171
bool loadFromNcorrParamsFile(const std::string &filepath="ncorr_params.txt")
Definition config.cpp:345
int subregion_radius
Definition config.h:131
std::string phase_id
Definition config.h:66
double video_alpha
Definition config.h:232
std::string colormap_range_mode
Definition config.h:236
int limit_grayscale
Definition config.h:135
bool smoothSpaceLogic
Definition config.h:104
int frame_jump
Definition config.h:80
int video_fps
Definition config.h:229
std::string base_path
Definition config.h:46
std::string fileversion
Definition config.h:125
int mesh_smoothing_iterations
Definition config.h:251
bool show_axes
Definition config.h:252
std::string csv_delimiter
Definition config.h:224
bool generate_summary_stats
Definition config.h:242
std::vector< int > nfcond_set
Definition config.h:68
std::string calib_folder_set
Definition config.h:72
bool ncorr_no_update
Definition config.h:175
double quiverScaleFactor
Definition config.h:117
double maxCorrCoeff
Definition config.h:98
Config()
Configuration implementation for CPPXDIC.
Definition config.cpp:13
bool automatic_process
Definition config.h:61
std::string ncorr_accumulation_mode
Definition config.h:183
bool vtk_include_scalars
Definition config.h:216
bool csv_include_header
Definition config.h:225
bool im_saturation_mode
Definition config.h:56
StepConfig step_d
Definition config.h:138
std::string ncorr_dic_config
Definition config.h:174
bool showImgLogic
Definition config.h:110
bool loadFromVisualizationParamsFile(const std::string &filepath="visualization_params.txt")
Definition config.cpp:426
int camNbr
Definition config.h:111
bool stats_spatial
Definition config.h:245
double robot_sample_freq
Definition config.h:42
std::string deftype
Definition config.h:93
bool ncorr_use_exact_matlab
Definition config.h:203
std::string log_level
Definition config.h:87
int idx_frame_end
Definition config.h:79
std::string ncorr_subregion
Definition config.h:173
std::string data_path
Definition config.h:47
std::string video_codec
Definition config.h:230
double ncorr_cutoff_max_diffnorm
Definition config.h:196
bool force_frame_window
Definition config.h:60
std::vector< double > spddxlcond_set
Definition config.h:69
std::vector< std::string > frictional_conditions
Definition config.h:33
bool step_d_replacebadcorr
Definition config.h:159
bool export_each_frame
Definition config.h:121
bool show_grid
Definition config.h:254
std::string ncorr_interp
Definition config.h:172
double mesh_decimation
Definition config.h:249
std::string data_format
Definition config.h:168
std::string log_file
Definition config.h:88
int ncorr_fixed_step_ref
Definition config.h:179
double FaceAlpha
Definition config.h:115
double units_per_pixel
Definition config.h:130
int smoothPar_n
Definition config.h:105
int cuncorr_seed_search
Definition config.h:212
std::string lineColor
Definition config.h:116
double ncorr_matching_cutoff_max_corrcoef
Definition config.h:201
double ncorr_cutoff_corrcoef
Definition config.h:181
bool stats_per_frame
Definition config.h:244
Lightweight, dependency-free logging facility for CPPxDIC.
#define LOG_WARN
Definition logging.h:171
#define LOG_INFO
Definition logging.h:170
double cutoff_diffnorm
Definition config.h:20
std::vector< int > initial_seed
Definition config.h:27
bool auto_update
Definition config.h:25
int cutoff_iteration
Definition config.h:21
int spacing
Definition config.h:19
std::string analysis_type
Definition config.h:17
std::string seed_type
Definition config.h:24
bool high_strain_enabled
Definition config.h:23
int total_threads
Definition config.h:22
int radius
Definition config.h:18
int step_ref_change
Definition config.h:26