pyvale 2025.7.1__cp311-cp311-macosx_14_0_arm64.whl → 2025.8.1__cp311-cp311-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyvale might be problematic. Click here for more details.
- pyvale/__init__.py +12 -92
- pyvale/blender/__init__.py +23 -0
- pyvale/{pyvaleexceptions.py → blender/blenderexceptions.py} +0 -3
- pyvale/{blenderlightdata.py → blender/blenderlightdata.py} +3 -3
- pyvale/{blendermaterialdata.py → blender/blendermaterialdata.py} +1 -1
- pyvale/{blenderrenderdata.py → blender/blenderrenderdata.py} +5 -3
- pyvale/{blenderscene.py → blender/blenderscene.py} +33 -30
- pyvale/{blendertools.py → blender/blendertools.py} +14 -10
- pyvale/dataset/__init__.py +7 -0
- pyvale/dataset/dataset.py +443 -0
- pyvale/dic/__init__.py +20 -0
- pyvale/dic/cpp/dicfourier.cpp +36 -4
- pyvale/dic/cpp/dicinterpolator.cpp +56 -1
- pyvale/dic/cpp/dicmain.cpp +24 -19
- pyvale/dic/cpp/dicoptimizer.cpp +6 -1
- pyvale/dic/cpp/dicscanmethod.cpp +32 -32
- pyvale/dic/cpp/dicsignalhandler.cpp +16 -0
- pyvale/dic/cpp/dicstrain.cpp +7 -3
- pyvale/dic/cpp/dicutil.cpp +79 -23
- pyvale/{dic2d.py → dic/dic2d.py} +51 -29
- pyvale/dic/dic2dconv.py +6 -0
- pyvale/dic/dic2dcpp.cpython-311-darwin.so +0 -0
- pyvale/{dicchecks.py → dic/dicchecks.py} +28 -16
- pyvale/dic/dicdataimport.py +370 -0
- pyvale/{dicregionofinterest.py → dic/dicregionofinterest.py} +169 -12
- pyvale/{dicresults.py → dic/dicresults.py} +4 -1
- pyvale/{dicstrain.py → dic/dicstrain.py} +9 -9
- pyvale/examples/basics/{ex1_1_basicscalars_therm2d.py → ex1a_basicscalars_therm2d.py} +12 -9
- pyvale/examples/basics/{ex1_2_sensormodel_therm2d.py → ex1b_sensormodel_therm2d.py} +17 -14
- pyvale/examples/basics/{ex1_3_customsens_therm3d.py → ex1c_customsens_therm3d.py} +27 -24
- pyvale/examples/basics/{ex1_4_basicerrors_therm3d.py → ex1d_basicerrors_therm3d.py} +32 -29
- pyvale/examples/basics/{ex1_5_fielderrs_therm3d.py → ex1e_fielderrs_therm3d.py} +19 -15
- pyvale/examples/basics/{ex1_6_caliberrs_therm2d.py → ex1f_caliberrs_therm2d.py} +20 -16
- pyvale/examples/basics/{ex1_7_spatavg_therm2d.py → ex1g_spatavg_therm2d.py} +19 -16
- pyvale/examples/basics/{ex2_1_basicvectors_disp2d.py → ex2a_basicvectors_disp2d.py} +13 -10
- pyvale/examples/basics/{ex2_2_vectorsens_disp2d.py → ex2b_vectorsens_disp2d.py} +19 -15
- pyvale/examples/basics/{ex2_3_sensangle_disp2d.py → ex2c_sensangle_disp2d.py} +21 -18
- pyvale/examples/basics/{ex2_4_chainfielderrs_disp2d.py → ex2d_chainfielderrs_disp2d.py} +31 -29
- pyvale/examples/basics/{ex2_5_vectorfields3d_disp3d.py → ex2e_vectorfields3d_disp3d.py} +21 -18
- pyvale/examples/basics/{ex3_1_basictensors_strain2d.py → ex3a_basictensors_strain2d.py} +16 -14
- pyvale/examples/basics/{ex3_2_tensorsens2d_strain2d.py → ex3b_tensorsens2d_strain2d.py} +17 -14
- pyvale/examples/basics/{ex3_3_tensorsens3d_strain3d.py → ex3c_tensorsens3d_strain3d.py} +25 -22
- pyvale/examples/basics/{ex4_1_expsim2d_thermmech2d.py → ex4a_expsim2d_thermmech2d.py} +17 -14
- pyvale/examples/basics/{ex4_2_expsim3d_thermmech3d.py → ex4b_expsim3d_thermmech3d.py} +37 -34
- pyvale/examples/basics/ex5_nomesh.py +24 -0
- pyvale/examples/dic/ex1_2_blenderdeformed.py +174 -0
- pyvale/examples/dic/ex1_region_of_interest.py +6 -3
- pyvale/examples/dic/ex2_plate_with_hole.py +21 -18
- pyvale/examples/dic/ex3_plate_with_hole_strain.py +8 -6
- pyvale/examples/dic/ex4_dic_blender.py +17 -15
- pyvale/examples/dic/ex5_dic_challenge.py +19 -14
- pyvale/examples/genanalyticdata/ex1_1_scalarvisualisation.py +16 -10
- pyvale/examples/genanalyticdata/ex1_2_scalarcasebuild.py +3 -3
- pyvale/examples/genanalyticdata/ex2_1_analyticsensors.py +29 -23
- pyvale/examples/genanalyticdata/ex2_2_analyticsensors_nomesh.py +67 -0
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +12 -9
- pyvale/examples/mooseherder/ex0_create_moose_config.py +65 -0
- pyvale/examples/mooseherder/ex1a_modify_moose_input.py +71 -0
- pyvale/examples/mooseherder/ex1b_modify_gmsh_input.py +69 -0
- pyvale/examples/mooseherder/ex2a_run_moose_once.py +80 -0
- pyvale/examples/mooseherder/ex2b_run_gmsh_once.py +64 -0
- pyvale/examples/mooseherder/ex2c_run_both_once.py +114 -0
- pyvale/examples/mooseherder/ex3_run_moose_seq_para.py +157 -0
- pyvale/examples/mooseherder/ex4_run_gmsh-moose_seq_para.py +176 -0
- pyvale/examples/mooseherder/ex5_run_moose_paramulti.py +136 -0
- pyvale/examples/mooseherder/ex6_read_moose_exodus.py +163 -0
- pyvale/examples/mooseherder/ex7a_read_moose_herd_results.py +153 -0
- pyvale/examples/mooseherder/ex7b_read_multi_herd_results.py +116 -0
- pyvale/examples/mooseherder/ex7c_read_multi_gmshmoose_results.py +127 -0
- pyvale/examples/mooseherder/ex7d_readconfig_multi_gmshmoose_results.py +143 -0
- pyvale/examples/mooseherder/ex8_read_existing_sweep_output.py +72 -0
- pyvale/examples/renderblender/ex1_1_blenderscene.py +24 -20
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +22 -18
- pyvale/examples/renderblender/ex2_1_stereoscene.py +36 -29
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +26 -20
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +24 -17
- pyvale/examples/renderrasterisation/ex_rastenp.py +14 -12
- pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +14 -15
- pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +13 -11
- pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +13 -11
- pyvale/mooseherder/__init__.py +32 -0
- pyvale/mooseherder/directorymanager.py +416 -0
- pyvale/mooseherder/exodusreader.py +763 -0
- pyvale/mooseherder/gmshrunner.py +163 -0
- pyvale/mooseherder/inputmodifier.py +236 -0
- pyvale/mooseherder/mooseconfig.py +226 -0
- pyvale/mooseherder/mooseherd.py +527 -0
- pyvale/mooseherder/mooserunner.py +303 -0
- pyvale/mooseherder/outputreader.py +22 -0
- pyvale/mooseherder/simdata.py +92 -0
- pyvale/mooseherder/simrunner.py +31 -0
- pyvale/mooseherder/sweepreader.py +356 -0
- pyvale/mooseherder/sweeptools.py +76 -0
- pyvale/sensorsim/__init__.py +82 -0
- pyvale/{camera.py → sensorsim/camera.py} +7 -7
- pyvale/{camerasensor.py → sensorsim/camerasensor.py} +7 -7
- pyvale/{camerastereo.py → sensorsim/camerastereo.py} +2 -2
- pyvale/{cameratools.py → sensorsim/cameratools.py} +4 -4
- pyvale/{cython → sensorsim/cython}/rastercyth.c +596 -596
- pyvale/{cython → sensorsim/cython}/rastercyth.cpython-311-darwin.so +0 -0
- pyvale/{cython → sensorsim/cython}/rastercyth.py +16 -17
- pyvale/{errorcalculator.py → sensorsim/errorcalculator.py} +1 -1
- pyvale/{errorintegrator.py → sensorsim/errorintegrator.py} +2 -2
- pyvale/{errorrand.py → sensorsim/errorrand.py} +4 -4
- pyvale/{errorsyscalib.py → sensorsim/errorsyscalib.py} +2 -2
- pyvale/{errorsysdep.py → sensorsim/errorsysdep.py} +2 -2
- pyvale/{errorsysfield.py → sensorsim/errorsysfield.py} +8 -8
- pyvale/{errorsysindep.py → sensorsim/errorsysindep.py} +3 -3
- pyvale/sensorsim/exceptions.py +8 -0
- pyvale/{experimentsimulator.py → sensorsim/experimentsimulator.py} +23 -3
- pyvale/{field.py → sensorsim/field.py} +1 -1
- pyvale/{fieldconverter.py → sensorsim/fieldconverter.py} +72 -19
- pyvale/sensorsim/fieldinterp.py +37 -0
- pyvale/sensorsim/fieldinterpmesh.py +124 -0
- pyvale/sensorsim/fieldinterppoints.py +55 -0
- pyvale/{fieldsampler.py → sensorsim/fieldsampler.py} +4 -4
- pyvale/{fieldscalar.py → sensorsim/fieldscalar.py} +28 -24
- pyvale/{fieldtensor.py → sensorsim/fieldtensor.py} +33 -31
- pyvale/{fieldvector.py → sensorsim/fieldvector.py} +33 -31
- pyvale/{imagedef2d.py → sensorsim/imagedef2d.py} +9 -5
- pyvale/{integratorfactory.py → sensorsim/integratorfactory.py} +6 -6
- pyvale/{integratorquadrature.py → sensorsim/integratorquadrature.py} +3 -3
- pyvale/{integratorrectangle.py → sensorsim/integratorrectangle.py} +3 -3
- pyvale/{integratorspatial.py → sensorsim/integratorspatial.py} +1 -1
- pyvale/{rastercy.py → sensorsim/rastercy.py} +5 -5
- pyvale/{rasternp.py → sensorsim/rasternp.py} +9 -9
- pyvale/{rasteropts.py → sensorsim/rasteropts.py} +1 -1
- pyvale/{renderer.py → sensorsim/renderer.py} +1 -1
- pyvale/{rendermesh.py → sensorsim/rendermesh.py} +5 -5
- pyvale/{renderscene.py → sensorsim/renderscene.py} +2 -2
- pyvale/{sensorarray.py → sensorsim/sensorarray.py} +1 -1
- pyvale/{sensorarrayfactory.py → sensorsim/sensorarrayfactory.py} +12 -12
- pyvale/{sensorarraypoint.py → sensorsim/sensorarraypoint.py} +10 -8
- pyvale/{sensordata.py → sensorsim/sensordata.py} +1 -1
- pyvale/{sensortools.py → sensorsim/sensortools.py} +2 -20
- pyvale/sensorsim/simtools.py +174 -0
- pyvale/{visualexpplotter.py → sensorsim/visualexpplotter.py} +3 -3
- pyvale/{visualimages.py → sensorsim/visualimages.py} +2 -2
- pyvale/{visualsimanimator.py → sensorsim/visualsimanimator.py} +4 -4
- pyvale/{visualsimplotter.py → sensorsim/visualsimplotter.py} +5 -5
- pyvale/{visualsimsensors.py → sensorsim/visualsimsensors.py} +12 -12
- pyvale/{visualtools.py → sensorsim/visualtools.py} +1 -1
- pyvale/{visualtraceplotter.py → sensorsim/visualtraceplotter.py} +2 -2
- pyvale/simcases/case17.geo +3 -0
- pyvale/simcases/case17.i +4 -4
- pyvale/simcases/run_1case.py +1 -9
- pyvale/simcases/run_all_cases.py +1 -1
- pyvale/simcases/run_build_case.py +1 -1
- pyvale/simcases/run_example_cases.py +1 -1
- pyvale/verif/__init__.py +12 -0
- pyvale/{analyticsimdatafactory.py → verif/analyticsimdatafactory.py} +2 -2
- pyvale/{analyticsimdatagenerator.py → verif/analyticsimdatagenerator.py} +2 -2
- pyvale/verif/psens.py +125 -0
- pyvale/verif/psensconst.py +18 -0
- pyvale/verif/psensmech.py +227 -0
- pyvale/verif/psensmultiphys.py +187 -0
- pyvale/verif/psensscalar.py +347 -0
- pyvale/verif/psenstensor.py +123 -0
- pyvale/verif/psensvector.py +116 -0
- {pyvale-2025.7.1.dist-info → pyvale-2025.8.1.dist-info}/METADATA +6 -7
- pyvale-2025.8.1.dist-info/RECORD +262 -0
- pyvale/dataset.py +0 -415
- pyvale/dic2dcpp.cpython-311-darwin.so +0 -0
- pyvale/dicdataimport.py +0 -247
- pyvale/simtools.py +0 -67
- pyvale-2025.7.1.dist-info/RECORD +0 -213
- /pyvale/{blendercalibrationdata.py → blender/blendercalibrationdata.py} +0 -0
- /pyvale/{dicspecklegenerator.py → dic/dicspecklegenerator.py} +0 -0
- /pyvale/{dicspecklequality.py → dic/dicspecklequality.py} +0 -0
- /pyvale/{dicstrainresults.py → dic/dicstrainresults.py} +0 -0
- /pyvale/{cameradata.py → sensorsim/cameradata.py} +0 -0
- /pyvale/{cameradata2d.py → sensorsim/cameradata2d.py} +0 -0
- /pyvale/{errordriftcalc.py → sensorsim/errordriftcalc.py} +0 -0
- /pyvale/{fieldtransform.py → sensorsim/fieldtransform.py} +0 -0
- /pyvale/{generatorsrandom.py → sensorsim/generatorsrandom.py} +0 -0
- /pyvale/{imagetools.py → sensorsim/imagetools.py} +0 -0
- /pyvale/{integratortype.py → sensorsim/integratortype.py} +0 -0
- /pyvale/{output.py → sensorsim/output.py} +0 -0
- /pyvale/{raster.py → sensorsim/raster.py} +0 -0
- /pyvale/{sensordescriptor.py → sensorsim/sensordescriptor.py} +0 -0
- /pyvale/{visualimagedef.py → sensorsim/visualimagedef.py} +0 -0
- /pyvale/{visualopts.py → sensorsim/visualopts.py} +0 -0
- /pyvale/{analyticmeshgen.py → verif/analyticmeshgen.py} +0 -0
- {pyvale-2025.7.1.dist-info → pyvale-2025.8.1.dist-info}/WHEEL +0 -0
- {pyvale-2025.7.1.dist-info → pyvale-2025.8.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.7.1.dist-info → pyvale-2025.8.1.dist-info}/top_level.txt +0 -0
pyvale/dic/cpp/dicmain.cpp
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include <pybind11/pybind11.h>
|
|
17
17
|
#include <pybind11/numpy.h>
|
|
18
18
|
#include <pybind11/stl.h>
|
|
19
|
+
#include <pybind11/iostream.h>
|
|
19
20
|
|
|
20
21
|
// Program Header files
|
|
21
22
|
#include "./dicinterpolator.hpp"
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
#include "./dicutil.hpp"
|
|
27
28
|
#include "./dicstrain.hpp"
|
|
28
29
|
#include "./dicfourier.hpp"
|
|
30
|
+
#include "./dicsignalhandler.hpp"
|
|
29
31
|
|
|
30
32
|
// cuda Header files
|
|
31
33
|
#include "../cuda/malloc.hpp"
|
|
@@ -39,6 +41,10 @@ void DICengine(const py::array_t<double>& img_ref_arr,
|
|
|
39
41
|
util::Config &conf,
|
|
40
42
|
util::SaveConfig &saveconf){
|
|
41
43
|
|
|
44
|
+
// Register signal handler for Ctrl+C and set debug_level
|
|
45
|
+
signal(SIGINT, signalHandler);
|
|
46
|
+
g_debug_level = conf.debug_level;
|
|
47
|
+
|
|
42
48
|
// ------------------------------------------------------------------------
|
|
43
49
|
// Initialisation
|
|
44
50
|
// ------------------------------------------------------------------------
|
|
@@ -59,28 +65,16 @@ void DICengine(const py::array_t<double>& img_ref_arr,
|
|
|
59
65
|
INFO_OUT("Subset Size:", conf.ss_size << " [px]");
|
|
60
66
|
INFO_OUT("Subset Step:", conf.ss_step << " [px]" );
|
|
61
67
|
INFO_OUT("Number of OMP threads:", omp_get_max_threads());
|
|
68
|
+
INFO_OUT("Debug level: ", conf.debug_level);
|
|
62
69
|
if (conf.scan_method=="RG") INFO_OUT("Reliability Guided Seed central px location: ", "("
|
|
63
70
|
<< conf.rg_seed.first+conf.ss_size/2 << ", " << conf.rg_seed.second+conf.ss_size/2 << ") [px] " )
|
|
64
71
|
|
|
65
|
-
// Register signal handler for Ctrl+C
|
|
66
|
-
signal(SIGINT, scanmethod::signalHandler);
|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
// get raw pointers
|
|
69
74
|
bool* img_roi = static_cast<bool*>(img_roi_arr.request().ptr);
|
|
70
75
|
double* img_ref = static_cast<double*>(img_ref_arr.request().ptr);
|
|
71
76
|
double* img_def_stack = static_cast<double*>(img_def_stack_arr.request().ptr);
|
|
72
77
|
|
|
73
|
-
// debugging
|
|
74
|
-
//for (int y = 0; y < conf.px_vert; y++){
|
|
75
|
-
// for (int x = 0; x < conf.px_hori; x++){
|
|
76
|
-
// std::cout << x << " " << y << " ";
|
|
77
|
-
// std::cout << img_ref[y*conf.px_hori + x] << " ";
|
|
78
|
-
// std::cout << img_def_stack[y*conf.px_hori + x] << " ";
|
|
79
|
-
// std::cout << img_roi[y*conf.px_hori+x] << std::endl;
|
|
80
|
-
// }
|
|
81
|
-
//}
|
|
82
|
-
//exit(0);
|
|
83
|
-
|
|
84
78
|
// ------------------------------------------------------------------------
|
|
85
79
|
// get a list of ss coordinates within RIO;
|
|
86
80
|
// ------------------------------------------------------------------------
|
|
@@ -108,8 +102,8 @@ void DICengine(const py::array_t<double>& img_ref_arr,
|
|
|
108
102
|
optimizer::init(conf.corr_crit, conf.shape_func);
|
|
109
103
|
|
|
110
104
|
// initialise the brute force scan
|
|
111
|
-
std::string brute_method = "EXPANDING_WAVEFRONT";
|
|
112
|
-
brute::init(conf.corr_crit, brute_method);
|
|
105
|
+
// std::string brute_method = "EXPANDING_WAVEFRONT";
|
|
106
|
+
// brute::init(conf.corr_crit, brute_method);
|
|
113
107
|
|
|
114
108
|
|
|
115
109
|
|
|
@@ -150,7 +144,6 @@ void DICengine(const py::array_t<double>& img_ref_arr,
|
|
|
150
144
|
|
|
151
145
|
if (!saveconf.at_end)
|
|
152
146
|
util::save_to_disk(img_num, saveconf, ssdata.back(), conf.num_def_img, conf.num_params, conf.filenames);
|
|
153
|
-
|
|
154
147
|
}
|
|
155
148
|
|
|
156
149
|
if (saveconf.at_end)
|
|
@@ -172,8 +165,16 @@ void build_info(){
|
|
|
172
165
|
}
|
|
173
166
|
|
|
174
167
|
|
|
168
|
+
void set_num_threads(int n) {
|
|
169
|
+
omp_set_num_threads(n);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
175
173
|
|
|
176
174
|
PYBIND11_MODULE(dic2dcpp, m) {
|
|
175
|
+
|
|
176
|
+
py::add_ostream_redirect(m, "ostream_redirect");
|
|
177
|
+
|
|
177
178
|
py::class_<util::Config>(m, "Config")
|
|
178
179
|
.def(py::init<>())
|
|
179
180
|
.def_readwrite("ss_step", &util::Config::ss_step)
|
|
@@ -194,7 +195,8 @@ PYBIND11_MODULE(dic2dcpp, m) {
|
|
|
194
195
|
.def_readwrite("num_params", &util::Config::num_params)
|
|
195
196
|
.def_readwrite("fft_mad", &util::Config::fft_mad)
|
|
196
197
|
.def_readwrite("fft_mad_scale", &util::Config::fft_mad_scale)
|
|
197
|
-
.def_readwrite("filenames", &util::Config::filenames)
|
|
198
|
+
.def_readwrite("filenames", &util::Config::filenames)
|
|
199
|
+
.def_readwrite("debug_level", &util::Config::debug_level);
|
|
198
200
|
|
|
199
201
|
py::class_<util::SaveConfig>(m, "SaveConfig")
|
|
200
202
|
.def(py::init<>())
|
|
@@ -202,12 +204,15 @@ PYBIND11_MODULE(dic2dcpp, m) {
|
|
|
202
204
|
.def_readwrite("binary", &util::SaveConfig::binary)
|
|
203
205
|
.def_readwrite("prefix", &util::SaveConfig::prefix)
|
|
204
206
|
.def_readwrite("delimiter", &util::SaveConfig::delimiter)
|
|
205
|
-
.def_readwrite("at_end", &util::SaveConfig::at_end)
|
|
207
|
+
.def_readwrite("at_end", &util::SaveConfig::at_end)
|
|
208
|
+
.def_readwrite("output_unconverged", &util::SaveConfig::output_unconverged)
|
|
209
|
+
.def_readwrite("shape_params", &util::SaveConfig::shape_params);
|
|
206
210
|
|
|
207
211
|
// Bind the engine function
|
|
208
212
|
m.def("build_info", &build_info, "build information");
|
|
209
213
|
m.def("dic_engine", &DICengine, "Run 2D analysis on input images with config");
|
|
210
214
|
m.def("strain_engine", &strain::engine, "Strain C++ calculations");
|
|
215
|
+
m.def("set_num_threads", &set_num_threads, "Set the number of OpenMP threads");
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
|
pyvale/dic/cpp/dicoptimizer.cpp
CHANGED
|
@@ -52,7 +52,7 @@ namespace optimizer {
|
|
|
52
52
|
double ftol = 0;
|
|
53
53
|
double xtol = 0;
|
|
54
54
|
opt.lambda = 0.001;
|
|
55
|
-
|
|
55
|
+
uint8_t converged = false;
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
// trying relative instead of global coordinates for the optimization
|
|
@@ -69,6 +69,9 @@ namespace optimizer {
|
|
|
69
69
|
optimize_cost(ss_ref, ss_def, interp_def, opt, global_x, global_y);
|
|
70
70
|
update_lambda(opt.costp, opt.costpdp, opt.p, opt.pdp, opt.lambda, opt.num_params);
|
|
71
71
|
|
|
72
|
+
// TODO: have a look at removing the two square roots in the below. Can we get away without
|
|
73
|
+
// it? cache is locally and perform the square root only once?
|
|
74
|
+
|
|
72
75
|
// relative change of all parameters
|
|
73
76
|
xtol = std::sqrt(std::inner_product(opt.dp.begin(), opt.dp.end(), opt.dp.begin(), 0.0)) /
|
|
74
77
|
std::sqrt(std::inner_product( opt.p.begin(), opt.p.end(), opt.p.begin(), 0.0));
|
|
@@ -78,6 +81,8 @@ namespace optimizer {
|
|
|
78
81
|
// variation on correlation coefficient
|
|
79
82
|
ftol = std::abs(opt.costpdp - opt.costp);
|
|
80
83
|
|
|
84
|
+
|
|
85
|
+
// TODO: convert ssd if statement into func pointer.
|
|
81
86
|
// convergence criteria
|
|
82
87
|
// - rel change in parameters is less than user precision
|
|
83
88
|
// - change in corr coeff is less than precision
|
pyvale/dic/cpp/dicscanmethod.cpp
CHANGED
|
@@ -23,19 +23,11 @@
|
|
|
23
23
|
#include "./indicators.hpp"
|
|
24
24
|
#include "./cursor_control.hpp"
|
|
25
25
|
#include "./dicfourier.hpp"
|
|
26
|
+
#include "./dicsignalhandler.hpp"
|
|
26
27
|
|
|
27
28
|
namespace scanmethod {
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
// for graceful exit
|
|
31
|
-
std::atomic<bool> stop_request(false);
|
|
32
|
-
|
|
33
|
-
void signalHandler(int signal) {
|
|
34
|
-
if (signal == SIGINT) {
|
|
35
|
-
stop_request = true;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
31
|
void image(const double *img_ref,
|
|
40
32
|
const Interpolator &interp_def,
|
|
41
33
|
const util::SubsetData &ssdata,
|
|
@@ -47,11 +39,11 @@ namespace scanmethod {
|
|
|
47
39
|
|
|
48
40
|
// progress bar
|
|
49
41
|
indicators::ProgressBar bar;
|
|
50
|
-
util::create_progress_bar(bar, conf.filenames
|
|
42
|
+
util::create_progress_bar(bar, conf.filenames[img_num], num_ss);
|
|
51
43
|
std::atomic<int> current_progress = 0;
|
|
52
|
-
|
|
44
|
+
int prev_pct = 0;
|
|
53
45
|
|
|
54
|
-
|
|
46
|
+
// loop over subsets within the ROI
|
|
55
47
|
#pragma omp parallel shared(stop_request)
|
|
56
48
|
{
|
|
57
49
|
|
|
@@ -103,10 +95,13 @@ namespace scanmethod {
|
|
|
103
95
|
|
|
104
96
|
// update progress bar
|
|
105
97
|
int progress = current_progress.fetch_add(1);
|
|
106
|
-
util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
98
|
+
if (omp_get_thread_num()==0) util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
107
99
|
|
|
108
100
|
}
|
|
109
101
|
}
|
|
102
|
+
|
|
103
|
+
int progress = current_progress;
|
|
104
|
+
util::update_progress_bar(bar, progress-1, num_ss, prev_pct);
|
|
110
105
|
bar.mark_as_completed();
|
|
111
106
|
indicators::show_console_cursor(true);
|
|
112
107
|
|
|
@@ -126,9 +121,9 @@ namespace scanmethod {
|
|
|
126
121
|
|
|
127
122
|
// progress bar
|
|
128
123
|
indicators::ProgressBar bar;
|
|
129
|
-
util::create_progress_bar(bar, conf.filenames
|
|
124
|
+
util::create_progress_bar(bar, conf.filenames[img_num], num_ss);
|
|
130
125
|
std::atomic<int> current_progress = 0;
|
|
131
|
-
|
|
126
|
+
int prev_pct = 0;
|
|
132
127
|
|
|
133
128
|
// initialise subsets
|
|
134
129
|
util::Subset ss_def(ss_size);
|
|
@@ -211,9 +206,11 @@ namespace scanmethod {
|
|
|
211
206
|
|
|
212
207
|
// update progress bar
|
|
213
208
|
int progress = current_progress.fetch_add(1);
|
|
214
|
-
util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
209
|
+
if (omp_get_thread_num()==0) util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
215
210
|
|
|
216
211
|
}
|
|
212
|
+
int progress = current_progress;
|
|
213
|
+
util::update_progress_bar(bar, progress-1, num_ss, prev_pct);
|
|
217
214
|
bar.mark_as_completed();
|
|
218
215
|
indicators::show_console_cursor(true);
|
|
219
216
|
}
|
|
@@ -242,15 +239,16 @@ namespace scanmethod {
|
|
|
242
239
|
const int ss_size = ssdata[last_size].size;
|
|
243
240
|
const int ss_step = ssdata[last_size].step;
|
|
244
241
|
|
|
245
|
-
|
|
242
|
+
//TODO: sort this function name out
|
|
246
243
|
fourier::mgwd(ssdata, img_ref, img_def, interp_def,
|
|
247
244
|
conf.fft_mad, conf.fft_mad_scale);
|
|
248
245
|
|
|
249
246
|
// progress bar
|
|
250
247
|
indicators::ProgressBar bar;
|
|
251
|
-
util::create_progress_bar(bar, conf.filenames
|
|
248
|
+
util::create_progress_bar(bar, conf.filenames[img_num], num_ss);
|
|
252
249
|
std::atomic<int> current_progress(0);
|
|
253
|
-
|
|
250
|
+
//int prev_pct(0);
|
|
251
|
+
int prev_pct = 0;
|
|
254
252
|
|
|
255
253
|
// quick check for the initial seed point
|
|
256
254
|
if (!rg::is_valid_point(seed_x, seed_y, ssdata[last_size])) {
|
|
@@ -259,7 +257,7 @@ namespace scanmethod {
|
|
|
259
257
|
|
|
260
258
|
// Initialize binary mask for computed points (initialized to 0)
|
|
261
259
|
std::vector<std::atomic<int>> computed_mask(ssdata[last_size].mask.size());
|
|
262
|
-
for (auto& val : computed_mask) val.store(0);
|
|
260
|
+
for (auto& val : computed_mask) val.store(0);
|
|
263
261
|
|
|
264
262
|
// queue for each thread
|
|
265
263
|
std::vector<std::priority_queue<rg::Point>> local_q(omp_get_max_threads());
|
|
@@ -287,7 +285,7 @@ namespace scanmethod {
|
|
|
287
285
|
if (conf.corr_crit=="SSD")
|
|
288
286
|
opt.opt_threshold = std::numeric_limits<double>::max();
|
|
289
287
|
|
|
290
|
-
brute::Parameters brute(conf.bf_threshold, conf.max_disp);
|
|
288
|
+
// brute::Parameters brute(conf.bf_threshold, conf.max_disp);
|
|
291
289
|
|
|
292
290
|
std::vector<std::unique_ptr<fourier::FFT>> fft_windows;
|
|
293
291
|
|
|
@@ -299,6 +297,8 @@ namespace scanmethod {
|
|
|
299
297
|
// number of iterations to make sure we get a good convergence.
|
|
300
298
|
// this is hardcoded for now. Could do with updating so that
|
|
301
299
|
// the seed location is checked ahead of the main correlation run.
|
|
300
|
+
|
|
301
|
+
// TODO: opt.seed_iter exposed to user.
|
|
302
302
|
opt.max_iter = 200;
|
|
303
303
|
|
|
304
304
|
// ---------------------------------------------------------------------------------------------------------------------------
|
|
@@ -336,9 +336,6 @@ namespace scanmethod {
|
|
|
336
336
|
|
|
337
337
|
computed_mask[idx].store(1);
|
|
338
338
|
|
|
339
|
-
// int progress = current_progress.fetch_add(1);
|
|
340
|
-
// util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
341
|
-
|
|
342
339
|
// loop over the neighbours for the initial seed point
|
|
343
340
|
for (size_t n = 0; n < ssdata[last_size].neigh[idx].size(); n++) {
|
|
344
341
|
|
|
@@ -369,7 +366,7 @@ namespace scanmethod {
|
|
|
369
366
|
util::append_results(img_num, nidx, nres, num_ss);
|
|
370
367
|
|
|
371
368
|
// update mask
|
|
372
|
-
computed_mask[
|
|
369
|
+
computed_mask[nidx].store(1);
|
|
373
370
|
|
|
374
371
|
// add this point to queue
|
|
375
372
|
// Protect push with mutex
|
|
@@ -390,6 +387,7 @@ namespace scanmethod {
|
|
|
390
387
|
// ---------------------------------------------------------------------------------------------------------------------------
|
|
391
388
|
#pragma omp barrier
|
|
392
389
|
|
|
390
|
+
// TODO: reset seed location using the last computed point
|
|
393
391
|
opt.max_iter = conf.max_iter;
|
|
394
392
|
|
|
395
393
|
std::vector<rg::Point> temp_neigh;
|
|
@@ -494,7 +492,7 @@ namespace scanmethod {
|
|
|
494
492
|
|
|
495
493
|
// update progress bar
|
|
496
494
|
int progress = current_progress.fetch_add(1);
|
|
497
|
-
util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
495
|
+
if (omp_get_thread_num()==0) util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
498
496
|
|
|
499
497
|
}
|
|
500
498
|
}
|
|
@@ -505,6 +503,8 @@ namespace scanmethod {
|
|
|
505
503
|
}
|
|
506
504
|
}
|
|
507
505
|
}
|
|
506
|
+
int progress = current_progress;
|
|
507
|
+
util::update_progress_bar(bar, progress-1, num_ss, prev_pct);
|
|
508
508
|
bar.mark_as_completed();
|
|
509
509
|
indicators::show_console_cursor(true);
|
|
510
510
|
|
|
@@ -532,9 +532,9 @@ namespace scanmethod {
|
|
|
532
532
|
|
|
533
533
|
// progress bar
|
|
534
534
|
indicators::ProgressBar bar;
|
|
535
|
-
util::create_progress_bar(bar, conf.filenames
|
|
535
|
+
util::create_progress_bar(bar, conf.filenames[img_num], num_ss);
|
|
536
536
|
std::atomic<int> current_progress = 0;
|
|
537
|
-
|
|
537
|
+
int prev_pct = 0;
|
|
538
538
|
|
|
539
539
|
// loop over subsets within the ROI
|
|
540
540
|
#pragma omp parallel shared(stop_request)
|
|
@@ -587,7 +587,7 @@ namespace scanmethod {
|
|
|
587
587
|
|
|
588
588
|
// update progress bar
|
|
589
589
|
int progress = current_progress.fetch_add(1);
|
|
590
|
-
util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
590
|
+
if (omp_get_thread_num()==0) util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
591
591
|
|
|
592
592
|
}
|
|
593
593
|
}
|
|
@@ -613,9 +613,9 @@ namespace scanmethod {
|
|
|
613
613
|
|
|
614
614
|
// progress bar
|
|
615
615
|
indicators::ProgressBar bar;
|
|
616
|
-
util::create_progress_bar(bar, conf.filenames
|
|
616
|
+
util::create_progress_bar(bar, conf.filenames[img_num], num_ss);
|
|
617
617
|
std::atomic<int> current_progress = 0;
|
|
618
|
-
|
|
618
|
+
int prev_pct = 0;
|
|
619
619
|
|
|
620
620
|
// loop over subsets within the ROI
|
|
621
621
|
#pragma omp parallel shared(stop_request)
|
|
@@ -666,7 +666,7 @@ namespace scanmethod {
|
|
|
666
666
|
|
|
667
667
|
// update progress bar
|
|
668
668
|
int progress = current_progress.fetch_add(1);
|
|
669
|
-
util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
669
|
+
if (omp_get_thread_num()==0) util::update_progress_bar(bar, progress, num_ss, prev_pct);
|
|
670
670
|
|
|
671
671
|
}
|
|
672
672
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// ================================================================================
|
|
2
|
+
// pyvale: the python validation engine
|
|
3
|
+
// License: MIT
|
|
4
|
+
// Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
+
// ================================================================================
|
|
6
|
+
|
|
7
|
+
#include "./dicsignalhandler.hpp"
|
|
8
|
+
#include <csignal>
|
|
9
|
+
|
|
10
|
+
std::atomic<bool> stop_request = false;
|
|
11
|
+
|
|
12
|
+
void signalHandler(int signal) {
|
|
13
|
+
if (signal == SIGINT) {
|
|
14
|
+
stop_request = true;
|
|
15
|
+
}
|
|
16
|
+
}
|
pyvale/dic/cpp/dicstrain.cpp
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
// STD library Header files
|
|
8
8
|
#include <cmath>
|
|
9
|
+
#include <omp.h>
|
|
9
10
|
#include <vector>
|
|
10
11
|
#include <iostream>
|
|
11
12
|
#include <iomanip>
|
|
@@ -70,8 +71,8 @@ namespace strain {
|
|
|
70
71
|
for (int img_num = 0; img_num < nimg; img_num++) {
|
|
71
72
|
|
|
72
73
|
indicators::ProgressBar bar;
|
|
73
|
-
util::create_progress_bar(bar, filenames
|
|
74
|
-
|
|
74
|
+
util::create_progress_bar(bar, filenames[img_num], nwindows);
|
|
75
|
+
int prev_pct = 0;
|
|
75
76
|
|
|
76
77
|
// loop over strain windows within the image
|
|
77
78
|
for (int sw = 0; sw < nwindows; sw++){
|
|
@@ -81,6 +82,9 @@ namespace strain {
|
|
|
81
82
|
results.x[sw] = x0;
|
|
82
83
|
results.y[sw] = y0;
|
|
83
84
|
|
|
85
|
+
// TODO: through a warning. NAN out the entire window.
|
|
86
|
+
// it should be up to the user whether they correct with
|
|
87
|
+
// outlier removal / smoothing.
|
|
84
88
|
results.valid_window[sw] = fill_window(ss_x, ss_y, u, v, img_num,
|
|
85
89
|
sw, window, nss_x,
|
|
86
90
|
nss_y, sw_size);
|
|
@@ -102,7 +106,7 @@ namespace strain {
|
|
|
102
106
|
deform_grad, eps, nwindows, img_num);
|
|
103
107
|
}
|
|
104
108
|
|
|
105
|
-
util::update_progress_bar(bar, sw, nwindows, prev_pct);
|
|
109
|
+
if (omp_get_thread_num() == 0) util::update_progress_bar(bar, sw, nwindows, prev_pct);
|
|
106
110
|
|
|
107
111
|
}
|
|
108
112
|
|
pyvale/dic/cpp/dicutil.cpp
CHANGED
|
@@ -30,7 +30,7 @@ namespace util {
|
|
|
30
30
|
std::vector<double> ftol_arr;
|
|
31
31
|
std::vector<double> xtol_arr;
|
|
32
32
|
std::vector<double> cost_arr;
|
|
33
|
-
std::vector<
|
|
33
|
+
std::vector<uint8_t> conv_arr;
|
|
34
34
|
bool at_end;
|
|
35
35
|
|
|
36
36
|
|
|
@@ -189,12 +189,16 @@ namespace util {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
// When partial count num of px in roi
|
|
192
|
+
// When partial count num of px in roi. if its outside
|
|
193
|
+
// the image its still not valid
|
|
193
194
|
else {
|
|
194
|
-
if (
|
|
195
|
-
is_valid_in_roi(px_x, px_y, px_hori, px_vert, img_roi)) {
|
|
195
|
+
if (is_valid_in_roi(px_x, px_y, px_hori, px_vert, img_roi)) {
|
|
196
196
|
valid_count++;
|
|
197
197
|
}
|
|
198
|
+
if (!is_valid_in_dims(px_x, px_y, px_hori, px_vert)) {
|
|
199
|
+
valid = false;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
198
202
|
}
|
|
199
203
|
}
|
|
200
204
|
|
|
@@ -202,7 +206,7 @@ namespace util {
|
|
|
202
206
|
}
|
|
203
207
|
|
|
204
208
|
// TODO: this is hardcoded so that atleast 70% of pixels in subset must be in ROI
|
|
205
|
-
if (partial) {
|
|
209
|
+
if (partial && valid) {
|
|
206
210
|
if (valid_count >= (ss_size*ss_size) * (0.70)) {
|
|
207
211
|
valid = true;
|
|
208
212
|
} else {
|
|
@@ -394,23 +398,44 @@ namespace util {
|
|
|
394
398
|
int idx = img * ssdata.num + i;
|
|
395
399
|
//int idx_p = num_params*idx;
|
|
396
400
|
|
|
401
|
+
// if the subset has not converged, set values to nan
|
|
402
|
+
if (!saveconf.output_unconverged && !conv_arr[idx]) {
|
|
403
|
+
u_arr[idx] = NAN;
|
|
404
|
+
v_arr[idx] = NAN;
|
|
405
|
+
for (int p = 0; p < num_params; p++){
|
|
406
|
+
p_arr[num_params*idx+p] = NAN;
|
|
407
|
+
}
|
|
408
|
+
cost_arr[idx] = NAN;
|
|
409
|
+
ftol_arr[idx] = NAN;
|
|
410
|
+
xtol_arr[idx] = NAN;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
|
|
397
414
|
double mag = std::sqrt(u_arr[idx]*u_arr[idx]+
|
|
398
415
|
v_arr[idx]*v_arr[idx]);
|
|
399
416
|
|
|
400
417
|
// convert from corner to centre subset coords
|
|
401
418
|
double ss_x = ssdata.coords[2*i ] + static_cast<double>(ssdata.size)/2.0 - 0.5;
|
|
402
419
|
double ss_y = ssdata.coords[2*i+1] + static_cast<double>(ssdata.size)/2.0 - 0.5;
|
|
420
|
+
|
|
403
421
|
|
|
404
422
|
write_int(outfile, ss_x);
|
|
405
423
|
write_int(outfile, ss_y);
|
|
406
424
|
write_dbl(outfile, u_arr[idx]);
|
|
407
425
|
write_dbl(outfile, v_arr[idx]);
|
|
408
426
|
write_dbl(outfile, mag);
|
|
409
|
-
|
|
427
|
+
write_uint8t(outfile, conv_arr[idx]);
|
|
410
428
|
write_dbl(outfile, cost_arr[idx]);
|
|
411
429
|
write_dbl(outfile, ftol_arr[idx]);
|
|
412
430
|
write_dbl(outfile, xtol_arr[idx]);
|
|
413
431
|
write_int(outfile, niter_arr[idx]);
|
|
432
|
+
|
|
433
|
+
if (saveconf.shape_params) {
|
|
434
|
+
for (int p = 0; p < num_params; p++){
|
|
435
|
+
write_dbl(outfile, p_arr[num_params*idx+p]);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
414
439
|
}
|
|
415
440
|
|
|
416
441
|
outfile.close();
|
|
@@ -429,7 +454,18 @@ namespace util {
|
|
|
429
454
|
outfile << "cost" << delimiter;
|
|
430
455
|
outfile << "ftol" << delimiter;
|
|
431
456
|
outfile << "xtol" << delimiter;
|
|
432
|
-
outfile << "num_iterations
|
|
457
|
+
outfile << "num_iterations";
|
|
458
|
+
|
|
459
|
+
// column headers for shape parameters
|
|
460
|
+
if (saveconf.shape_params) {
|
|
461
|
+
for (int p = 0; p < num_params; p++){
|
|
462
|
+
outfile << delimiter;
|
|
463
|
+
outfile << "shape_p" << p;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// newline after headers
|
|
468
|
+
outfile << "\n";
|
|
433
469
|
|
|
434
470
|
for (int i = 0; i < ssdata.num; i++) {
|
|
435
471
|
|
|
@@ -440,6 +476,18 @@ namespace util {
|
|
|
440
476
|
double ss_x = ssdata.coords[2*i ] + static_cast<double>(ssdata.size)/2.0 - 0.5;
|
|
441
477
|
double ss_y = ssdata.coords[2*i+1] + static_cast<double>(ssdata.size)/2.0 - 0.5;
|
|
442
478
|
|
|
479
|
+
// if the subset has not converged, set values to nan
|
|
480
|
+
if (!saveconf.output_unconverged && !conv_arr[idx]) {
|
|
481
|
+
u_arr[idx] = NAN;
|
|
482
|
+
v_arr[idx] = NAN;
|
|
483
|
+
for (int p = 0; p < num_params; p++){
|
|
484
|
+
p_arr[num_params*idx+p] = NAN;
|
|
485
|
+
}
|
|
486
|
+
cost_arr[idx] = NAN;
|
|
487
|
+
ftol_arr[idx] = NAN;
|
|
488
|
+
xtol_arr[idx] = NAN;
|
|
489
|
+
}
|
|
490
|
+
|
|
443
491
|
|
|
444
492
|
outfile << ss_x << delimiter;
|
|
445
493
|
outfile << ss_y << delimiter;
|
|
@@ -447,14 +495,24 @@ namespace util {
|
|
|
447
495
|
outfile << v_arr[idx] << delimiter;
|
|
448
496
|
outfile << sqrt(u_arr[idx]*u_arr[idx]+
|
|
449
497
|
v_arr[idx]*v_arr[idx]) << delimiter;
|
|
450
|
-
|
|
451
|
-
// outfile << p_arr[idx_p+p] << delimiter;
|
|
452
|
-
//}
|
|
453
|
-
outfile << conv_arr[idx] << delimiter;
|
|
498
|
+
outfile << static_cast<int>(conv_arr[idx]) << delimiter;
|
|
454
499
|
outfile << cost_arr[idx] << delimiter;
|
|
455
500
|
outfile << ftol_arr[idx] << delimiter;
|
|
456
501
|
outfile << xtol_arr[idx] << delimiter;
|
|
457
|
-
outfile << niter_arr[idx]
|
|
502
|
+
outfile << niter_arr[idx];
|
|
503
|
+
|
|
504
|
+
// write shape parameters if requested
|
|
505
|
+
if (saveconf.shape_params) {
|
|
506
|
+
for (int p = 0; p < num_params; p++){
|
|
507
|
+
outfile << delimiter;
|
|
508
|
+
outfile << p_arr[num_params*idx+p];
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// newline after each subset
|
|
513
|
+
outfile << "\n";
|
|
514
|
+
|
|
515
|
+
|
|
458
516
|
}
|
|
459
517
|
outfile.close();
|
|
460
518
|
}
|
|
@@ -532,8 +590,8 @@ namespace util {
|
|
|
532
590
|
}
|
|
533
591
|
|
|
534
592
|
void create_progress_bar(indicators::ProgressBar &bar,
|
|
535
|
-
const std::
|
|
536
|
-
const int
|
|
593
|
+
const std::string &bar_title,
|
|
594
|
+
const int num_ss){
|
|
537
595
|
//Hide cursor
|
|
538
596
|
indicators::show_console_cursor(false);
|
|
539
597
|
bar.set_option(indicators::option::BarWidth{50});
|
|
@@ -542,22 +600,20 @@ namespace util {
|
|
|
542
600
|
bar.set_option(indicators::option::Lead{"#"});
|
|
543
601
|
bar.set_option(indicators::option::Remainder{"-"});
|
|
544
602
|
bar.set_option(indicators::option::End{"]"});
|
|
545
|
-
bar.set_option(indicators::option::PrefixText{
|
|
603
|
+
bar.set_option(indicators::option::PrefixText{bar_title});
|
|
546
604
|
bar.set_option(indicators::option::ShowPercentage{true});
|
|
547
605
|
bar.set_option(indicators::option::ShowElapsedTime{true});
|
|
548
606
|
}
|
|
549
607
|
|
|
550
|
-
void update_progress_bar(indicators::ProgressBar &bar, int i, int num_ss,
|
|
551
|
-
int curr_pct = static_cast<float>(i) /
|
|
552
|
-
int expected = prev_pct.load();
|
|
608
|
+
void update_progress_bar(indicators::ProgressBar &bar, int i, int num_ss, int &prev_pct) {
|
|
609
|
+
int curr_pct = static_cast<int>((static_cast<float>(i) / num_ss) * 100.0f);
|
|
553
610
|
|
|
554
|
-
// Only update
|
|
555
|
-
if (curr_pct >
|
|
556
|
-
|
|
557
|
-
|
|
611
|
+
// Only update if we've passed a new percentage
|
|
612
|
+
if (curr_pct > prev_pct) {
|
|
613
|
+
prev_pct = curr_pct;
|
|
614
|
+
bar.set_progress(curr_pct);
|
|
558
615
|
}
|
|
559
616
|
}
|
|
560
617
|
|
|
561
618
|
|
|
562
|
-
|
|
563
619
|
}
|