From e3fd17167a7eb25ad202e8f0b2cb6f5b7d2218b6 Mon Sep 17 00:00:00 2001 From: CyrilThebault Date: Wed, 14 Aug 2024 11:14:47 -0600 Subject: [PATCH 1/6] Allow different metrics for calibration and add a stopping criteria for Ostrich --- .DS_Store | Bin 0 -> 8196 bytes demo1/.DS_Store | Bin 0 -> 6148 bytes demo1/control_active.txt | 39 +++++---- demo1/model/.DS_Store | Bin 0 -> 6148 bytes demo1/model/settings/.DS_Store | Bin 0 -> 6148 bytes demo1/save_best.sh | 4 +- demo2/control_active.txt | 43 +++++----- demo3/control_active.txt | 39 +++++---- demo3/save_best.sh | 2 + demo4/control_active.txt | 44 +++++----- scripts/calculate_sim_stats.py | 150 +++++++++++++++++++++++++++++++-- scripts/create_ostIn.py | 7 +- scripts/stopping_criteria.py | 95 +++++++++++++++++++++ 13 files changed, 338 insertions(+), 85 deletions(-) create mode 100644 .DS_Store create mode 100644 demo1/.DS_Store create mode 100644 demo1/model/.DS_Store create mode 100644 demo1/model/settings/.DS_Store create mode 100755 scripts/stopping_criteria.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c1c75e437c36ba2f3faaa76b3cc83f73641f870d GIT binary patch literal 8196 zcmeHM%TB^T6urYkKw`o|6Wld%i?O^G#7%?v1J>w54N^ks)Oevfw^ zC=^+d7=!mFbI&j{r|mgOr@aLLSbOYN0m=Z7$0o2;#PmamdC^uPrAKxV8S(+D&LkW< zK6h5u(f~O?4v+)n069Po{0#^2nJpr}=DDwCDU$=_z`t}r><ymTdnfH6nmDitiOZ#U$h2Nx&wajM4 zI5uY$W7?`?w`w+)nu ztk@EU;03a9N5%> zv^qdp)c@z}zyEJ~8sd`!nih;^|-Nx>w`aYR{; fBYyp1h3XY{QR)`}Q^dUgnK#3gqRR=x+Al*OH literal 0 HcmV?d00001 diff --git a/demo1/.DS_Store b/demo1/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..99ab241969f2bc1af6c8c4e81594dad9b84bca1a GIT binary patch literal 6148 zcmeHK%}T>S5Z>*NZ7D(y3VK`cS}|36C|*LWFJMFuDm5WNgK4%jsXdfJ?)pN$h|lB9 z?gm;69!2a7?0&QJvzz%K`@W--Rv&=5H)6@unUSIqBvZ!~vWAl=r3_beA)?&tH&^=EfDx|T8tO5G1` z;%G6p_AX?a`*9l0R6-m^5ORMTr=eW9a-N2n%JsCP12VP_m&??Vlk= # (01) Path where parameter estimation is stored. e.g., /____/demo1 +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. -max_iterations | 10 # (04) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -WarmStart | no # (05) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. +loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (06) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (07) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (08) Name of the SUMMA master configuration file. -summa_exe_path | # (09) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. +summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (10) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (11) Name of the mizuRoute configuration file. -route_exe_path | # (12) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. +route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (13) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (14) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (15) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (16) Path of observed streamflow data. -obs_unit | cfs # (17) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (18) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (19) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (20) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. +obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/demo1/model/.DS_Store b/demo1/model/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6cda19bc3db6677169ab183febf554912a889fad GIT binary patch literal 6148 zcmeHK%}T>S5Z-O8O({YS3VI88t(Yo36fYsx7cim+m70)HgE3p0)Er77cYPsW#OHBl zcO#Z4coMNQW%iq$pDg>O>|_~Z+?|Jg#!SYT0gBk@!0?4&9JMA5?Lp-788J)Qgk?dI zO>5cY_=^nSyE9nEB9_DN)B6h&5kTxUm?m+S+x8o8G+P^+ZIEvJ*1H#lm;3oVbN$&h z&Mt&Vg39)T%Qz~==Ju&bb3aa_nJkFI2vTmY;xrV6E9PmK$y!eZIv`_nZ?QNU+Jl~T zU@v>tVt5Q@-yRH>%Z{x+vg9VD{Xe<@VqXP!~e8hMQ5e00#OCVYr9gU?z zh=6ca3aCoCzG84y4t`7LIT}las+@7TGCW7G%=Hb0%hkbe$#ljYg)|Za#K0;8O*J*K z|DSz-|6eVl88JW%{3`}{Yvhew*plw8wasC#wLtGcQ82Gm_)!9eY{ig^t#}ty3ivHF W03D5`Lhyjlhk&Gk24dh>8F&YCWleDa literal 0 HcmV?d00001 diff --git a/demo1/model/settings/.DS_Store b/demo1/model/settings/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e71ed0b66eadd9b7bca96858313653f0ede101b7 GIT binary patch literal 6148 zcmeHK%}T>S5T0$TZ74zx3VI88t(Yo3h?h|73pAn!mD<<8l_GHimumPZkN?5Y6Ss@fBU6PXV5DN8;E=ZU_24OH= z%4Wx3WPsMrf+0lkj4StL{nAko%K)Qq!6=T>%yr*Isa)CEtfJJbxBi2i`dL4lr0xFr zntB&f#zA5CgUcwK_U!F5nPmMa3CF4+8ibf~a}^~6Ic>{HGDuaeuLBlJ&)%EOj!xWG z!#Qy04QF<8jAqkqwdQlHwzGeD+U-5Y!$iJlJ_Y`IO12CZ@QTKYsXh7QB$mlNMvKa# zf{__u2AF|0VZdyEwfdUOm#4`LFatklfc6ImmC!SoYgAhYHgtWYc!iJzZF)-(ItD$1 zxkikj2wjS(ONDu22wjeT$K-hibB($jgc=#YV@4L{g(B4G=yy~)2u~xo%m6d6$Us?l zZ94zYzkmNP7IBXmUpq727Z-+4{uXVv;Y7A literal 0 HcmV?d00001 diff --git a/demo1/save_best.sh b/demo1/save_best.sh index 1968e4d..c5251eb 100755 --- a/demo1/save_best.sh +++ b/demo1/save_best.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Save use-specifed files every time a best paraemter set is discovered. +# Save use-specifed files every time a best parameter set is discovered. # ----------------------------------------------------------------------------------------- # ----------------------------- User specified input -------------------------------------- @@ -104,5 +104,7 @@ cp $stat_output $outDir/ cp $calib_path/Ost*.txt $outDir/ cp $calib_path/timetrack.log $outDir/ +python ../scripts/stopping_criteria.py $control_file + exit 0 diff --git a/demo2/control_active.txt b/demo2/control_active.txt index 3c45583..b880566 100644 --- a/demo2/control_active.txt +++ b/demo2/control_active.txt @@ -5,30 +5,33 @@ # Note on path specification. If deviating from default paths, a full path must be specified. E.g. '/home/user/non-default/path' ## ---- PART 1. Paramerter estimation settings ---- -calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo2 -object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in summa. -initial_option | UseInitialParamValues # (03) Initial value option: UseInitialParamValues or UseRandomParamValues. -max_iterations | 10 # (04) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -WarmStart | no # (05) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 +object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. +ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. +objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. +loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (06) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (07) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (08) Name of the SUMMA master configuration file. -summa_exe_path | # (09) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. +summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (10) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (11) Name of the mizuRoute configuration file. -route_exe_path | # (12) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. +route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (13) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (14) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (15) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file | ./obs_flow.BowRiveratBanff.cfs.csv # (16) Path of observed streamflow data. -obs_unit | cfs # (17) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (18) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (19) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (20) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. +obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/demo3/control_active.txt b/demo3/control_active.txt index 5a39182..b880566 100644 --- a/demo3/control_active.txt +++ b/demo3/control_active.txt @@ -5,30 +5,33 @@ # Note on path specification. If deviating from default paths, a full path must be specified. E.g. '/home/user/non-default/path' ## ---- PART 1. Paramerter estimation settings ---- -calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo3 +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. -max_iterations | 10 # (04) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -WarmStart | no # (05) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. +loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (06) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (07) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (08) Name of the SUMMA master configuration file. -summa_exe_path | # (09) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. +summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (10) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (11) Name of the mizuRoute configuration file. -route_exe_path | # (12) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. +route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (13) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (14) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (15) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (16) Path of observed streamflow data. -obs_unit | cfs # (17) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (18) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (19) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (20) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. +obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/demo3/save_best.sh b/demo3/save_best.sh index 1968e4d..bc72248 100755 --- a/demo3/save_best.sh +++ b/demo3/save_best.sh @@ -104,5 +104,7 @@ cp $stat_output $outDir/ cp $calib_path/Ost*.txt $outDir/ cp $calib_path/timetrack.log $outDir/ +python ../scripts/stopping_criteria.py $control_file + exit 0 diff --git a/demo4/control_active.txt b/demo4/control_active.txt index 2ab2d68..b880566 100644 --- a/demo4/control_active.txt +++ b/demo4/control_active.txt @@ -5,31 +5,33 @@ # Note on path specification. If deviating from default paths, a full path must be specified. E.g. '/home/user/non-default/path' ## ---- PART 1. Paramerter estimation settings ---- -calib_path | # (01) Path where parameter -estimation is stored. e.g., /____/demo4 -object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in summa. -initial_option | UseInitialParamValues # (03) Initial value option: UseInitialParamValues or UseRandomParamValues. -max_iterations | 10 # (04) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -WarmStart | no # (05) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 +object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. +ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. +objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. +loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. +WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (06) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (07) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (08) Name of the SUMMA master configuration file. -summa_exe_path | # (09) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. +summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (10) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (11) Name of the mizuRoute configuration file. -route_exe_path | # (12) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. +route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (13) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (14) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (15) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file | ./obs_flow.BowRiveratBanff.cfs.csv # (16) Path of observed streamflow data. -obs_unit | cfs # (17) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (18) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (19) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (20) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. +obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/scripts/calculate_sim_stats.py b/scripts/calculate_sim_stats.py index 63e309a..dcc3027 100755 --- a/scripts/calculate_sim_stats.py +++ b/scripts/calculate_sim_stats.py @@ -17,10 +17,59 @@ def process_command_line(): args = parser.parse_args() return(args) -def get_modified_KGE(obs,sim): - '''Modified KGE reference: Kling, Harald, Martin Fuchs, and Maria Paulin. \ +def get_KGE(obs,sim, transfo = 1): + obs = np.array(obs) + sim = np.array(sim) + + isNotNA = np.invert(np.logical_or(np.isnan(obs), np.isnan(sim))) + + obs = obs[isNotNA] + sim = sim[isNotNA] + + if transfo < 0: + epsilon = np.mean(obs)/100 + else: + epsilon = 0 + + obs = (epsilon + obs) ** transfo + sim = (epsilon + sim) ** transfo + + sd_sim = np.std(sim, ddof=1) + sd_obs = np.std(obs, ddof=1) + + m_sim = np.mean(sim) + m_obs = np.mean(obs) + + r = (np.corrcoef(sim,obs))[0,1] + var = float(sd_sim)/float(sd_obs) + bias = float(m_sim)/float(m_obs) + + kge = 1.0-np.sqrt((r-1)**2 +(var-1)**2 + (bias-1)**2) + + return kge + + +def get_KGEp(obs,sim, transfo = 1): + ''' KGE' reference: Kling, Harald, Martin Fuchs, and Maria Paulin. \ "Runoff conditions in the upper Danube basin under an ensemble of climate change scenarios." \ Journal of hydrology 424 (2012): 264-277.''' + + obs = np.array(obs) + sim = np.array(sim) + + isNotNA = np.invert(np.logical_or(np.isnan(obs), np.isnan(sim))) + + obs = obs[isNotNA] + sim = sim[isNotNA] + + if transfo < 0: + epsilon = np.mean(obs)/100 + else: + epsilon = 0 + + obs = (epsilon + obs) ** transfo + sim = (epsilon + sim) ** transfo + sd_sim = np.std(sim, ddof=1) sd_obs = np.std(obs, ddof=1) @@ -31,8 +80,79 @@ def get_modified_KGE(obs,sim): relvar = (float(sd_sim)/float(m_sim))/(float(sd_obs)/float(m_obs)) bias = float(m_sim)/float(m_obs) - kge = 1.0-np.sqrt((r-1)**2 +(relvar-1)**2 + (bias-1)**2) - return kge + kgep = 1.0-np.sqrt((r-1)**2 +(relvar-1)**2 + (bias-1)**2) + + return kgep + + +def get_NSE(obs,sim, transfo = 1): + + obs = np.array(obs) + sim = np.array(sim) + + isNotNA = np.invert(np.logical_or(np.isnan(obs), np.isnan(sim))) + + obs = obs[isNotNA] + sim = sim[isNotNA] + + if transfo < 0: + epsilon = np.mean(obs)/100 + else: + epsilon = 0 + + obs = (epsilon + obs) ** transfo + sim = (epsilon + sim) ** transfo + + nse = 1-(np.sum(np.subtract(obs,sim)**2)/np.sum(np.subtract(obs, np.mean(sim))**2)) + + return nse + +def get_MAE(obs,sim, transfo = 1): + + obs = np.array(obs) + sim = np.array(sim) + + isNotNA = np.invert(np.logical_or(np.isnan(obs), np.isnan(sim))) + + obs = obs[isNotNA] + sim = sim[isNotNA] + + if transfo < 0: + epsilon = np.mean(obs)/100 + else: + epsilon = 0 + + obs = (epsilon + obs) ** transfo + sim = (epsilon + sim) ** transfo + + mae = np.mean(np.abs(np.subtract(obs,sim))) + + return mae + +def get_RMSE(obs,sim, transfo = 1): + + obs = np.array(obs) + sim = np.array(sim) + + isNotNA = np.invert(np.logical_or(np.isnan(obs), np.isnan(sim))) + + obs = obs[isNotNA] + sim = sim[isNotNA] + + if transfo < 0: + epsilon = np.mean(obs)/100 + else: + epsilon = 0 + + obs = (epsilon + obs) ** transfo + sim = (epsilon + sim) ** transfo + + rmse = np.sqrt(np.mean(np.square(np.subtract(obs,sim)))) + + return rmse + + + def read_from_control(control_file, setting): ''' Function to extract a given setting from the control_file.''' @@ -139,10 +259,28 @@ def read_from_summa_route_config(config_file, setting): df_merge = pd.concat([df_obs_eval, df_sim_eval], axis=1) df_merge = df_merge.dropna() + # --- Read objective function + + obj_fun = read_from_control(control_file, 'objective_function') + # future improvement: q_trans = read_from_control(control_file, 'streamflow_transformation') + q_trans = 1 # --- Calculate diagnostics --- - kge = get_modified_KGE(obs=df_merge['obs'].values, sim=df_merge['sim'].values) + + if obj_fun == 'KGE': + score = get_KGE(obs=df_merge['obs'].values, sim=df_merge['sim'].values, transfo = q_trans) + elif obj_fun == 'KGEp': + score = get_KGEp(obs=df_merge['obs'].values, sim=df_merge['sim'].values, transfo = q_trans) + elif obj_fun == 'NSE': + score = get_NSE(obs=df_merge['obs'].values, sim=df_merge['sim'].values, transfo = q_trans) + elif obj_fun == 'MAE': + score = get_MAE(obs=df_merge['obs'].values, sim=df_merge['sim'].values, transfo = q_trans) + elif obj_fun == 'RMSE': + score = get_RMSE(obs=df_merge['obs'].values, sim=df_merge['sim'].values, transfo = q_trans) + else: + print('Objective function not found') + sys.exit() # #### 3. Save f = open(stat_output, 'w+') - f.write('%.6f' %kge + '\t#KGE\n') + f.write('%.6f' %score + '\t#'+obj_fun+'\n') f.close() diff --git a/scripts/create_ostIn.py b/scripts/create_ostIn.py index 1117ec4..9aaa559 100755 --- a/scripts/create_ostIn.py +++ b/scripts/create_ostIn.py @@ -68,7 +68,12 @@ def read_from_control(control_file, setting): multp_bounds_arr = np.loadtxt(multp_bounds, dtype='str', delimiter=',') # MultiplierName,InitialValue,LowerLimit,UpperLimit. multp_num = len(multp_bounds_arr) - # #### 2. Write ostIn.txt based on ostIn.tpl + # #### 2. Remove OstQuit.txt if exists (file to aboard Ostrich run) + ostquit_file = os.path.join(calib_path, 'OstQuit.txt') + if os.path.exists(ostquit_file): + os.remove(ostquit_file) + + # #### 3. Write ostIn.txt based on ostIn.tpl # Identify ostIn template and txt file. ostIn_src = os.path.join(calib_path, read_from_control(control_file, 'ostIn_tpl')) ostIn_dst = os.path.join(calib_path, 'ostIn.txt') diff --git a/scripts/stopping_criteria.py b/scripts/stopping_criteria.py new file mode 100755 index 0000000..db271e0 --- /dev/null +++ b/scripts/stopping_criteria.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# coding: utf-8 + +# #### Calculate stopping criteria for model calibration. + +# import packages +import os, sys, datetime, argparse +import pandas as pd +import xarray as xr + +# define functions +def process_command_line(): + '''Parse the commandline''' + parser = argparse.ArgumentParser(description='Script to calculate model evaluation statistics KGE.') + parser.add_argument('control_file', help='path of the active control file.') + args = parser.parse_args() + return(args) + + + +def read_from_control(control_file, setting): + ''' Function to extract a given setting from the control_file.''' + # Open 'control_active.txt' and locate the line with setting + with open(control_file) as ff: + for line in ff: + line = line.strip() + if line.startswith(setting): + break + # Extract the setting's value + substring = line.split('|',1)[1].split('#',1)[0].strip() + # Return this value + return substring + +def read_from_ostoutput(ostoutput_file, kstop): + '''Function to extract a given setting from the summa or mizuRoute configuration file.''' + # Open fileManager.txt or route_control and locate the line with setting + count = 0 + with open(ostoutput_file) as ff: + lines = ff.readlines() + for line in lines: + count += 1 + if line.startswith('Optimal Parameter Set'): + break + # Extract the objective function value + + mylines = lines[(count-2-kstop):(count-2)] + of_values = [] + last_trial = 0 + for myline in mylines: + + if len(myline.split()) != 0 and myline.split()[0].isnumeric(): + of_values.append(float(myline.split()[1])) + last_trial = int(myline.split()[0]) + + # Return this value + return of_values, last_trial + +# main +if __name__ == '__main__': + + # an example: python stopping_criteria.py ../control_active.txt + + # ------------------------------ Prepare --------------------------------- + # Process command line + # Check args + if len(sys.argv) < 2: + print("Usage: %s " % sys.argv[0]) + sys.exit(0) + # Otherwise continue + args = process_command_line() + control_file = args.control_file + + # Read calibration path from control_file + calib_path = read_from_control(control_file, 'calib_path') + + # OstModel0.txt + ostoutput_file = os.path.join(calib_path, 'OstOutput0.txt') + + + # Read arguments for stopping criteria + maxn = int(read_from_control(control_file, 'max_iterations')) + kstop = int(read_from_control(control_file, 'loop_stagnation')) + pcento = float(read_from_control(control_file, 'per_change')) + + # ----------------------------------------------------------------------- + + # #### 1. Read objective function values from OstModel0.txt + of_values, last_trial = read_from_ostoutput(ostoutput_file, kstop) + + # #### 2. Stopping criteria + if (len(of_values) == kstop) and (last_trial == maxn or abs(of_values[0]-of_values[-1]) <= of_values[0] * pcento/100): + ### stop Ostrich exe + ostquit_file = os.path.join(calib_path, 'OstQuit.txt') + open(ostquit_file, "a").close() + From 3f72838700808abfe136214afb1f964943ee49c4 Mon Sep 17 00:00:00 2001 From: CyrilThebault Date: Wed, 14 Aug 2024 11:18:27 -0600 Subject: [PATCH 2/6] Remove .DS_Store files and add a .gitignore file --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index c1c75e437c36ba2f3faaa76b3cc83f73641f870d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM%TB^T6urYkKw`o|6Wld%i?O^G#7%?v1J>w54N^ks)Oevfw^ zC=^+d7=!mFbI&j{r|mgOr@aLLSbOYN0m=Z7$0o2;#PmamdC^uPrAKxV8S(+D&LkW< zK6h5u(f~O?4v+)n069Po{0#^2nJpr}=DDwCDU$=_z`t}r><ymTdnfH6nmDitiOZ#U$h2Nx&wajM4 zI5uY$W7?`?w`w+)nu ztk@EU;03a9N5%> zv^qdp)c@z}zyEJ~8sd`!nih;^|-Nx>w`aYR{; fBYyp1h3XY{QR)`}Q^dUgnK#3gqRR=x+Al*OH From 7aa973f7564ba6c96d9d9430430a500367eb18d1 Mon Sep 17 00:00:00 2001 From: CyrilThebault Date: Wed, 14 Aug 2024 11:22:48 -0600 Subject: [PATCH 3/6] Add a .gitignore file --- .gitignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d39ff67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +slurm-*.out +output*.out + +# notebook stuff +.ipynb_checkpoints + +# Ignore macOS system files +.DS_Store + +# Ignore environment configuration files +.env \ No newline at end of file From 8fa36c41d5c1eba5b3c7b2299a27b4c892977087 Mon Sep 17 00:00:00 2001 From: CyrilThebault Date: Wed, 14 Aug 2024 13:03:16 -0600 Subject: [PATCH 4/6] Remove all .DS_Store files --- demo1/.DS_Store | Bin 6148 -> 0 bytes demo1/model/.DS_Store | Bin 6148 -> 0 bytes demo1/model/settings/.DS_Store | Bin 6148 -> 0 bytes demo1/model/settings/SUMMA/.DS_Store | Bin 6148 -> 0 bytes demo2/model/settings/SUMMA/.DS_Store | Bin 6148 -> 0 bytes demo3/model/settings/SUMMA/.DS_Store | Bin 6148 -> 0 bytes demo4/model/settings/SUMMA/.DS_Store | Bin 6148 -> 0 bytes 7 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 demo1/.DS_Store delete mode 100644 demo1/model/.DS_Store delete mode 100644 demo1/model/settings/.DS_Store delete mode 100644 demo1/model/settings/SUMMA/.DS_Store delete mode 100644 demo2/model/settings/SUMMA/.DS_Store delete mode 100644 demo3/model/settings/SUMMA/.DS_Store delete mode 100644 demo4/model/settings/SUMMA/.DS_Store diff --git a/demo1/.DS_Store b/demo1/.DS_Store deleted file mode 100644 index 99ab241969f2bc1af6c8c4e81594dad9b84bca1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z>*NZ7D(y3VK`cS}|36C|*LWFJMFuDm5WNgK4%jsXdfJ?)pN$h|lB9 z?gm;69!2a7?0&QJvzz%K`@W--Rv&=5H)6@unUSIqBvZ!~vWAl=r3_beA)?&tH&^=EfDx|T8tO5G1` z;%G6p_AX?a`*9l0R6-m^5ORMTr=eW9a-N2n%JsCP12VP_m&??Vlk=S5Z-O8O({YS3VI88t(Yo36fYsx7cim+m70)HgE3p0)Er77cYPsW#OHBl zcO#Z4coMNQW%iq$pDg>O>|_~Z+?|Jg#!SYT0gBk@!0?4&9JMA5?Lp-788J)Qgk?dI zO>5cY_=^nSyE9nEB9_DN)B6h&5kTxUm?m+S+x8o8G+P^+ZIEvJ*1H#lm;3oVbN$&h z&Mt&Vg39)T%Qz~==Ju&bb3aa_nJkFI2vTmY;xrV6E9PmK$y!eZIv`_nZ?QNU+Jl~T zU@v>tVt5Q@-yRH>%Z{x+vg9VD{Xe<@VqXP!~e8hMQ5e00#OCVYr9gU?z zh=6ca3aCoCzG84y4t`7LIT}las+@7TGCW7G%=Hb0%hkbe$#ljYg)|Za#K0;8O*J*K z|DSz-|6eVl88JW%{3`}{Yvhew*plw8wasC#wLtGcQ82Gm_)!9eY{ig^t#}ty3ivHF W03D5`Lhyjlhk&Gk24dh>8F&YCWleDa diff --git a/demo1/model/settings/.DS_Store b/demo1/model/settings/.DS_Store deleted file mode 100644 index e71ed0b66eadd9b7bca96858313653f0ede101b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5T0$TZ74zx3VI88t(Yo3h?h|73pAn!mD<<8l_GHimumPZkN?5Y6Ss@fBU6PXV5DN8;E=ZU_24OH= z%4Wx3WPsMrf+0lkj4StL{nAko%K)Qq!6=T>%yr*Isa)CEtfJJbxBi2i`dL4lr0xFr zntB&f#zA5CgUcwK_U!F5nPmMa3CF4+8ibf~a}^~6Ic>{HGDuaeuLBlJ&)%EOj!xWG z!#Qy04QF<8jAqkqwdQlHwzGeD+U-5Y!$iJlJ_Y`IO12CZ@QTKYsXh7QB$mlNMvKa# zf{__u2AF|0VZdyEwfdUOm#4`LFatklfc6ImmC!SoYgAhYHgtWYc!iJzZF)-(ItD$1 zxkikj2wjS(ONDu22wjeT$K-hibB($jgc=#YV@4L{g(B4G=yy~)2u~xo%m6d6$Us?l zZ94zYzkmNP7IBXmUpq727Z-+4{uXVv;Y7A diff --git a/demo1/model/settings/SUMMA/.DS_Store b/demo1/model/settings/SUMMA/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Thu, 15 Aug 2024 09:36:26 -0600 Subject: [PATCH 5/6] Add an argument in the control_active file to decide whether or not to use the stopping criterion --- demo1/control_active.txt | 42 ++++++++++++++++++++------------------ demo1/save_best.sh | 7 ++++++- demo2/control_active.txt | 44 +++++++++++++++++++++------------------- demo3/control_active.txt | 44 +++++++++++++++++++++------------------- demo3/save_best.sh | 7 ++++++- demo4/control_active.txt | 44 +++++++++++++++++++++------------------- 6 files changed, 103 insertions(+), 85 deletions(-) diff --git a/demo1/control_active.txt b/demo1/control_active.txt index c781265..a9f133c 100644 --- a/demo1/control_active.txt +++ b/demo1/control_active.txt @@ -8,30 +8,32 @@ calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. -objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. -max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +WarmStart | no # (04) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +objective_function | KGE # (05) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (06) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS or SCE needs this configuration (MAXN). +stopping_criteria | FALSE # (07) If TRUE, add a stopping criteria to stop calibration if there is no further improvement. Optional input, depending on the optimization method. Eg, can be used with DDS but already included in SCE. +loop_stagnation | 5 # (08) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration (KSTOP), and it's optional for DDS (only if stopping criteria = TRUE). +per_change | 0.01 # (09) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration (PCENTO), and it's optional for DDS (only if stopping criteria = TRUE). + ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (10) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. -summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (11) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (12) Name of the SUMMA master configuration file. +summa_exe_path | # (13) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. -route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (14) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (15) Name of the mizuRoute configuration file. +route_exe_path | # (16) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (17) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (18) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. -obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (19) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (20) Path of observed streamflow data. +obs_unit | cfs # (21) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (22) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (23) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (24) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/demo1/save_best.sh b/demo1/save_best.sh index c5251eb..0fcf554 100755 --- a/demo1/save_best.sh +++ b/demo1/save_best.sh @@ -104,7 +104,12 @@ cp $stat_output $outDir/ cp $calib_path/Ost*.txt $outDir/ cp $calib_path/timetrack.log $outDir/ -python ../scripts/stopping_criteria.py $control_file +# Run stopping_criteria.py script if specified in the control file +stopping_criteria="$(read_from_control $control_file "stopping_criteria")" + +if [ "$stopping_criteria" = "true" ]; then + python ../scripts/stopping_criteria.py $control_file +fi exit 0 diff --git a/demo2/control_active.txt b/demo2/control_active.txt index b880566..a9f133c 100644 --- a/demo2/control_active.txt +++ b/demo2/control_active.txt @@ -5,33 +5,35 @@ # Note on path specification. If deviating from default paths, a full path must be specified. E.g. '/home/user/non-default/path' ## ---- PART 1. Paramerter estimation settings ---- -calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. -objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. -max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +WarmStart | no # (04) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +objective_function | KGE # (05) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (06) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS or SCE needs this configuration (MAXN). +stopping_criteria | FALSE # (07) If TRUE, add a stopping criteria to stop calibration if there is no further improvement. Optional input, depending on the optimization method. Eg, can be used with DDS but already included in SCE. +loop_stagnation | 5 # (08) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration (KSTOP), and it's optional for DDS (only if stopping criteria = TRUE). +per_change | 0.01 # (09) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration (PCENTO), and it's optional for DDS (only if stopping criteria = TRUE). + ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (10) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. -summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (11) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (12) Name of the SUMMA master configuration file. +summa_exe_path | # (13) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. -route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (14) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (15) Name of the mizuRoute configuration file. +route_exe_path | # (16) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (17) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (18) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. -obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (19) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (20) Path of observed streamflow data. +obs_unit | cfs # (21) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (22) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (23) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (24) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/demo3/control_active.txt b/demo3/control_active.txt index b880566..a9f133c 100644 --- a/demo3/control_active.txt +++ b/demo3/control_active.txt @@ -5,33 +5,35 @@ # Note on path specification. If deviating from default paths, a full path must be specified. E.g. '/home/user/non-default/path' ## ---- PART 1. Paramerter estimation settings ---- -calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. -objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. -max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +WarmStart | no # (04) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +objective_function | KGE # (05) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (06) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS or SCE needs this configuration (MAXN). +stopping_criteria | FALSE # (07) If TRUE, add a stopping criteria to stop calibration if there is no further improvement. Optional input, depending on the optimization method. Eg, can be used with DDS but already included in SCE. +loop_stagnation | 5 # (08) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration (KSTOP), and it's optional for DDS (only if stopping criteria = TRUE). +per_change | 0.01 # (09) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration (PCENTO), and it's optional for DDS (only if stopping criteria = TRUE). + ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (10) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. -summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (11) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (12) Name of the SUMMA master configuration file. +summa_exe_path | # (13) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. -route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (14) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (15) Name of the mizuRoute configuration file. +route_exe_path | # (16) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (17) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (18) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. -obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (19) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (20) Path of observed streamflow data. +obs_unit | cfs # (21) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (22) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (23) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (24) End date for statistics calculation, in format yyyy-mm-dd. diff --git a/demo3/save_best.sh b/demo3/save_best.sh index bc72248..37e5840 100755 --- a/demo3/save_best.sh +++ b/demo3/save_best.sh @@ -104,7 +104,12 @@ cp $stat_output $outDir/ cp $calib_path/Ost*.txt $outDir/ cp $calib_path/timetrack.log $outDir/ -python ../scripts/stopping_criteria.py $control_file +# Run stopping_criteria.py script if specified in the control file +stopping_criteria="$(read_from_control $control_file "stopping_criteria")" + +if [ "$stopping_criteria" = "true" ]; then + python ../scripts/stopping_criteria.py $control_file +fi exit 0 diff --git a/demo4/control_active.txt b/demo4/control_active.txt index b880566..a9f133c 100644 --- a/demo4/control_active.txt +++ b/demo4/control_active.txt @@ -5,33 +5,35 @@ # Note on path specification. If deviating from default paths, a full path must be specified. E.g. '/home/user/non-default/path' ## ---- PART 1. Paramerter estimation settings ---- -calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 +calib_path | # (01) Path where parameter estimation is stored. e.g., /____/demo1 object_parameters | k_macropore, k_soil, theta_sat, aquiferBaseflowExp, aquiferBaseflowRate, qSurfScale, summerLAI, frozenPrecipMultip, heightCanopyBottom, heightCanopyTop, routingGammaScale, routingGammaShape, Fcapil # (02) Parameter names to be optimized or evaluated. The parameter names should be the same as they are in the summa source code. ostIn_tpl | tpl/ostIn.DDS.tpl # (03) Name of ostIn template file. Input file in '[calib_path]/[ostIn_tpl]'. -objective_function | KGE # (04) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. -max_iterations | 10 # (05) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS needs this configuration. -loop_stagnation | 5 # (06) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -per_change | 0.01 # (07) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration and it's optional for DDS. -WarmStart | no # (08) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +WarmStart | no # (04) If set to "yes" OSTRICH will read the contents of any previously created "OstModel" output files and use the entries therein to restart an optimization or calibration exercise. +objective_function | KGE # (05) Name of the objective function. Must be: 'KGE', 'KGEp', 'NSE', 'MAE', 'RMSE'. +max_iterations | 10 # (06) Maximum Number of iterations for optimization. Optional input, depending on the optimization method. Eg, DDS or SCE needs this configuration (MAXN). +stopping_criteria | FALSE # (07) If TRUE, add a stopping criteria to stop calibration if there is no further improvement. Optional input, depending on the optimization method. Eg, can be used with DDS but already included in SCE. +loop_stagnation | 5 # (08) Number of previous value of the objective function to check. Optional input, depending on the optimization method. Eg, SCE needs this configuration (KSTOP), and it's optional for DDS (only if stopping criteria = TRUE). +per_change | 0.01 # (09) Percentage by which the optimization criterion value must change. Optional input, depending on the optimization method. Eg, SCE needs this configuration (PCENTO), and it's optional for DDS (only if stopping criteria = TRUE). + ## ---- PART 2. Hydrologic model settings ---- -model_path | default # (09) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. +model_path | default # (10) Path of destination hydrologic model. If 'default', use '[calib_path]/model'. -summa_settings_relpath | settings/SUMMA # (10) Relative path of summa model settings folder, relative to [model_path]. -summa_filemanager | fileManager.txt # (11) Name of the SUMMA master configuration file. -summa_exe_path | # (12) summa executable path. e.g., /____/summa.exe +summa_settings_relpath | settings/SUMMA # (11) Relative path of summa model settings folder, relative to [model_path]. +summa_filemanager | fileManager.txt # (12) Name of the SUMMA master configuration file. +summa_exe_path | # (13) summa executable path. e.g., /____/summa.exe -route_settings_relpath | settings/mizuRoute # (13) Relative path of summa model settings folder, relative to [model_path]. -route_control | mizuroute.control # (14) Name of the mizuRoute configuration file. -route_exe_path | # (15) muziroute executable path, e.g., /____/mizuroute.exe +route_settings_relpath | settings/mizuRoute # (14) Relative path of summa model settings folder, relative to [model_path]. +route_control | mizuroute.control # (15) Name of the mizuRoute configuration file. +route_exe_path | # (16) muziroute executable path, e.g., /____/mizuroute.exe -simStartTime | 2008-07-15 00:00 # (16) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. -simEndTime | 2008-07-31 23:00 # (17) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simStartTime | 2008-07-15 00:00 # (17) Start time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. +simEndTime | 2008-07-31 23:00 # (18) End time for hydrologic simualtion, in format yyyy-mm-dd hh:mm. ## ---- PART 3. Calculate statistics settings ---- -q_seg_index | 49 # (18) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. -obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (19) Path of observed streamflow data. -obs_unit | cfs # (20) Observation streamflow data unit (cfs or cms). -stat_output | trial_stats.txt # (21) Name of file with statistical metric results. Output file in [calib_path]. -statStartDate | 2008-07-15 # (22) Start date for statistics calculation, in format yyyy-mm-dd. -statEndDate | 2008-07-31 # (23) End date for statistics calculation, in format yyyy-mm-dd. +q_seg_index | 49 # (19) segment index in routing output file that matches obs location (start from 1). For the demo domain, its outlet is located on reachID 71028585 which corresponds to the 49th segment. +obs_file_path | ./obs_flow.BowRiveratBanff.cfs.csv # (20) Path of observed streamflow data. +obs_unit | cfs # (21) Observation streamflow data unit (cfs or cms). +stat_output | trial_stats.txt # (22) Name of file with statistical metric results. Output file in [calib_path]. +statStartDate | 2008-07-15 # (23) Start date for statistics calculation, in format yyyy-mm-dd. +statEndDate | 2008-07-31 # (24) End date for statistics calculation, in format yyyy-mm-dd. From ac5f14fa354d5a9c15d19a5cec11465809db6920 Mon Sep 17 00:00:00 2001 From: CyrilThebault Date: Thu, 15 Aug 2024 09:54:51 -0600 Subject: [PATCH 6/6] Make the condition space and case unsensitive --- demo1/save_best.sh | 6 +++++- demo3/save_best.sh | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/demo1/save_best.sh b/demo1/save_best.sh index 0fcf554..e199196 100755 --- a/demo1/save_best.sh +++ b/demo1/save_best.sh @@ -104,9 +104,13 @@ cp $stat_output $outDir/ cp $calib_path/Ost*.txt $outDir/ cp $calib_path/timetrack.log $outDir/ -# Run stopping_criteria.py script if specified in the control file +# Read stopping_criteria condition from control_file. stopping_criteria="$(read_from_control $control_file "stopping_criteria")" +# Convert to lowercase and remove spaces +stopping_criteria=$(echo "$stopping_criteria" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]') + +# Run stopping_criteria.py script if specified in the control file if [ "$stopping_criteria" = "true" ]; then python ../scripts/stopping_criteria.py $control_file fi diff --git a/demo3/save_best.sh b/demo3/save_best.sh index 37e5840..a7fa10f 100755 --- a/demo3/save_best.sh +++ b/demo3/save_best.sh @@ -104,9 +104,13 @@ cp $stat_output $outDir/ cp $calib_path/Ost*.txt $outDir/ cp $calib_path/timetrack.log $outDir/ -# Run stopping_criteria.py script if specified in the control file +# Read stopping_criteria condition from control_file. stopping_criteria="$(read_from_control $control_file "stopping_criteria")" +# Convert to lowercase and remove spaces +stopping_criteria=$(echo "$stopping_criteria" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]') + +# Run stopping_criteria.py script if specified in the control file if [ "$stopping_criteria" = "true" ]; then python ../scripts/stopping_criteria.py $control_file fi