From d92bc301aad09039a7d65ff501a4197dc84fb3ca Mon Sep 17 00:00:00 2001 From: Andreas Eknes Lie Date: Mon, 12 Dec 2022 11:43:12 +0100 Subject: [PATCH 1/2] Provide feedback for RUNPATH format Remove iteration_count property Remove obsoleted test Add LibresFacade testing valid runpaths Added logger feedback on deprecated syntax for runpath Update documentation for RUNPATH Replace jobname specifiers with and --- .../configuration/poly_new/guide.rst | 2 +- .../poly_new/with_observations/poly.ert | 2 +- .../poly_new/with_observations/poly_final.ert | 2 +- .../poly_new/with_parameters/poly.ert | 2 +- .../poly_new/with_results/poly.ert | 2 +- .../poly_new/with_simple_script/poly.ert | 2 +- docs/reference/configuration/keywords.rst | 22 +++++++++---------- docs/reference/queue/local_queue.ert | 2 +- docs/reference/queue/lsf_queue.ert | 2 +- src/ert/_c_wrappers/enkf/model_config.py | 22 ++++++++++++++----- .../tools/load_results/load_results_panel.py | 21 +----------------- .../tools/load_results/load_results_tool.py | 14 +----------- src/ert/libres_facade.py | 8 +++++++ test-data/batch_sim/batch_sim.ert | 2 +- .../batch_sim/batch_sim_sleep_and_fail.ert | 2 +- test-data/batch_sim/sleepy_time.ert | 2 +- test-data/configuration_tests/ecl_config.ert | 2 +- .../configuration_tests/ensemble_config.ert | 2 +- .../configuration_tests/model_config.ert | 2 +- .../sched_file_as_history_source.ert | 2 +- test-data/poly_example/poly-ies.ert | 2 +- test-data/poly_example/poly.ert | 2 +- test-data/poly_template/poly.ert.j2 | 2 +- test-data/simple_config/analysis_config | 2 +- test-data/simple_config/minimum_config | 2 +- test-data/simple_config/slurm_config | 2 +- test-data/snake_oil/snake_oil.ert | 2 +- test-data/snake_oil_field/snake_oil.ert | 2 +- test-data/snake_oil_field/snake_oil_field.ert | 2 +- .../snake_oil_field/snake_oil_surface.ert | 2 +- .../ert/model/user_config.ert | 2 +- .../test_config_parsing/test_model_config.py | 19 +++++++++++----- tests/test_config_parsing/test_res_config.py | 4 ++-- .../c_wrappers/res/enkf/test_model_config.py | 8 +++---- .../res/enkf/test_programmatic_res_config.py | 8 +++---- .../c_wrappers/res/enkf/test_res_config.py | 15 +++++++------ tests/unit_tests/gui/tools/test_case_tool.py | 18 +++++++++++++++ .../unit_tests/gui/tools/test_results_tool.py | 21 ------------------ tests/unit_tests/lsf_queue/test_lsf_driver.py | 2 +- tests/unit_tests/shared/share/test_shell.py | 2 +- 40 files changed, 115 insertions(+), 121 deletions(-) delete mode 100644 tests/unit_tests/gui/tools/test_results_tool.py diff --git a/docs/getting_started/configuration/poly_new/guide.rst b/docs/getting_started/configuration/poly_new/guide.rst index 2d18d8903cd..7b5ef922c95 100644 --- a/docs/getting_started/configuration/poly_new/guide.rst +++ b/docs/getting_started/configuration/poly_new/guide.rst @@ -116,7 +116,7 @@ We need to have each iteration run in a different folder, so that they won't step on each others toes. Add to the config (``poly.ert``) file the following line:: - RUNPATH poly_out/realization-%d/iter-%d + RUNPATH poly_out/realization-/iter- The second ``%d`` in the runpath is replaced by the iteration number of the algorithm. This is needed since the algorithm may run several iterations during diff --git a/docs/getting_started/configuration/poly_new/with_observations/poly.ert b/docs/getting_started/configuration/poly_new/with_observations/poly.ert index ad0f959a738..aae9fb69309 100644 --- a/docs/getting_started/configuration/poly_new/with_observations/poly.ert +++ b/docs/getting_started/configuration/poly_new/with_observations/poly.ert @@ -4,7 +4,7 @@ NUM_REALIZATIONS 100 QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter_%d +RUNPATH poly_out/realization-/iter- GEN_KW COEFFS coeff.tmpl coeffs.json coeff_priors diff --git a/docs/getting_started/configuration/poly_new/with_observations/poly_final.ert b/docs/getting_started/configuration/poly_new/with_observations/poly_final.ert index 73255b4766f..d6405d00062 100644 --- a/docs/getting_started/configuration/poly_new/with_observations/poly_final.ert +++ b/docs/getting_started/configuration/poly_new/with_observations/poly_final.ert @@ -4,7 +4,7 @@ NUM_REALIZATIONS 100 QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- GEN_KW COEFFS coeff.tmpl coeffs.json coeff_priors diff --git a/docs/getting_started/configuration/poly_new/with_parameters/poly.ert b/docs/getting_started/configuration/poly_new/with_parameters/poly.ert index 23d65c88e77..ec8ad6c73db 100644 --- a/docs/getting_started/configuration/poly_new/with_parameters/poly.ert +++ b/docs/getting_started/configuration/poly_new/with_parameters/poly.ert @@ -4,7 +4,7 @@ NUM_REALIZATIONS 100 QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- GEN_KW COEFFS coeff.tmpl coeffs.json coeff_priors diff --git a/docs/getting_started/configuration/poly_new/with_results/poly.ert b/docs/getting_started/configuration/poly_new/with_results/poly.ert index 73255b4766f..d6405d00062 100644 --- a/docs/getting_started/configuration/poly_new/with_results/poly.ert +++ b/docs/getting_started/configuration/poly_new/with_results/poly.ert @@ -4,7 +4,7 @@ NUM_REALIZATIONS 100 QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- GEN_KW COEFFS coeff.tmpl coeffs.json coeff_priors diff --git a/docs/getting_started/configuration/poly_new/with_simple_script/poly.ert b/docs/getting_started/configuration/poly_new/with_simple_script/poly.ert index 4e7b0d9ecaa..699ec281ba5 100644 --- a/docs/getting_started/configuration/poly_new/with_simple_script/poly.ert +++ b/docs/getting_started/configuration/poly_new/with_simple_script/poly.ert @@ -3,7 +3,7 @@ NUM_REALIZATIONS 5 QUEUE_SYSTEM LOCAL -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- INSTALL_JOB poly_eval POLY_EVAL SIMULATION_JOB poly_eval diff --git a/docs/reference/configuration/keywords.rst b/docs/reference/configuration/keywords.rst index 5e57c1c39f5..00a307043c6 100644 --- a/docs/reference/configuration/keywords.rst +++ b/docs/reference/configuration/keywords.rst @@ -66,7 +66,7 @@ Keyword name Required :ref:`QUEUE_SYSTEM ` NO LOCAL_DRIVER System used for running simulation jobs :ref:`REFCASE ` NO Reference case used for observations and plotting (See HISTORY_SOURCE and SUMMARY) :ref:`RESULT_PATH ` NO results/step_%d Define where ERT should store results -:ref:`RUNPATH ` NO simulations/realization%d Directory to run simulations +:ref:`RUNPATH ` NO realization-/iter- Directory to run simulations; simulations/realization-/iter- :ref:`RUNPATH_FILE ` NO .ert_runpath_list Name of file with path for all forward models that ERT has run. To be used by user defined scripts to find the realizations :ref:`RUN_TEMPLATE ` NO Install arbitrary files in the runpath directory :ref:`SCHEDULE_PREDICTION_FILE ` NO Deprecated: Schedule prediction file @@ -461,25 +461,25 @@ possible to do with ERT. .. topic:: RUNPATH The RUNPATH keyword should give the name of the folders where the ECLIPSE - simulations are executed. It should contain at least one %d specifier, which - will be replaced by the realization number when ERT creates the folders. - Optionally, it can contain one more %d specifier, which will be replaced by - the iteration number. + simulations are executed. It should contain and , which + will be replaced by the realization number and iteration number when ERT creates the folders. + By default, RUNPATH is set to "simulations/realization-/iter-". - By default, RUNPATH is set to "simulations/realization-%d". + Deprecated syntax still allow use of two %d specifers. Use of less than two %d is prohibited. + The behaviour is identical to the default substitution. - *Example A:* + *Example:* :: - -- Giving a RUNPATH with just one %d specifer. - RUNPATH /mnt/my_scratch_disk/realization-%d + -- Using & specifiers for RUNPATH. + RUNPATH /mnt/my_scratch_disk/realization-/iter- - *Example B:* + *Example deprecated syntax:* :: - -- Giving a RUNPATH with two %d specifers. + -- Using RUNPATH with two %d specifers. RUNPATH /mnt/my_scratch_disk/realization-%d/iteration-%d The RUNPATH keyword is optional. diff --git a/docs/reference/queue/local_queue.ert b/docs/reference/queue/local_queue.ert index 8b168b26000..4ed8708536b 100644 --- a/docs/reference/queue/local_queue.ert +++ b/docs/reference/queue/local_queue.ert @@ -3,7 +3,7 @@ JOBNAME queue_test_%d QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH local_testing/realization-%d/iter-%d +RUNPATH local_testing/realization-/iter- NUM_REALIZATIONS 100 MIN_REALIZATIONS 1 diff --git a/docs/reference/queue/lsf_queue.ert b/docs/reference/queue/lsf_queue.ert index b2db5072928..2d73142515d 100644 --- a/docs/reference/queue/lsf_queue.ert +++ b/docs/reference/queue/lsf_queue.ert @@ -8,7 +8,7 @@ QUEUE_OPTION LSF LSF_SERVER be-grid01 -- Change this to a server you have access QUEUE_OPTION LSF LSF_QUEUE mr QUEUE_OPTION LSF PROJECT_CODE user:$USER -RUNPATH lsf_testing/realization-%d/iter-%d +RUNPATH lsf_testing/realization-/iter- NUM_REALIZATIONS 1 MIN_REALIZATIONS 1 diff --git a/src/ert/_c_wrappers/enkf/model_config.py b/src/ert/_c_wrappers/enkf/model_config.py index 352f3ea0658..2e4545f037a 100644 --- a/src/ert/_c_wrappers/enkf/model_config.py +++ b/src/ert/_c_wrappers/enkf/model_config.py @@ -12,7 +12,7 @@ class ModelConfig: DEFAULT_HISTORY_SOURCE = HistorySourceEnum.REFCASE_HISTORY - DEFAULT_RUNPATH = "simulations/realization-%d/iter-%d" + DEFAULT_RUNPATH = "simulations/realization-/iter-" DEFAULT_GEN_KW_EXPORT_NAME = "parameters" DEFAULT_ENSPATH = "storage" @@ -40,11 +40,21 @@ def __init__( else self.DEFAULT_HISTORY_SOURCE ) - self.runpath_format_string = ( - runpath_format_string - if runpath_format_string is not None - else self.DEFAULT_RUNPATH - ) + if runpath_format_string is None: + self.runpath_format_string = self.DEFAULT_RUNPATH + elif "%d" in runpath_format_string: + self.runpath_format_string = runpath_format_string + logger.warning( + "RUNPATH keyword should use syntax " + f"`{self.DEFAULT_RUNPATH}` " + "instead of deprecated syntax " + f"`{runpath_format_string}`" + ) + elif not any(x in runpath_format_string for x in [", "]): + self.runpath_format_string = runpath_format_string + logger.error( + "RUNPATH keyword should use syntax " f"`{self.DEFAULT_RUNPATH}`." + ) self.jobname_format_string = jobname_format_string self.gen_kw_export_name = ( diff --git a/src/ert/gui/tools/load_results/load_results_panel.py b/src/ert/gui/tools/load_results/load_results_panel.py index a9eadb2657b..00dfe9e1cde 100644 --- a/src/ert/gui/tools/load_results/load_results_panel.py +++ b/src/ert/gui/tools/load_results/load_results_panel.py @@ -1,5 +1,3 @@ -import os - from PyQt5.QtWidgets import QMessageBox from qtpy.QtWidgets import QComboBox, QFormLayout, QTextEdit, QWidget @@ -50,7 +48,7 @@ def __init__(self, facade: LibresFacade): self._active_realizations_field.setValidator(RangeStringArgument()) layout.addRow("Realizations to load:", self._active_realizations_field) - self._iterations_model = ValueModel(self.iteration_count) + self._iterations_model = ValueModel(self.facade.get_number_of_iterations()) self._iterations_field = StringBox( self._iterations_model, "load_results_manually/iterations" ) @@ -59,23 +57,6 @@ def __init__(self, facade: LibresFacade): self.setLayout(layout) - @property - def iteration_count(self) -> int: - try: - self.facade.run_path % (0, 0) - except TypeError: - return 0 - - iteration = 0 - valid_directory = True - while valid_directory: - formatted = self.facade.run_path % (0, iteration + 1) - valid_directory = os.path.exists(formatted) - if valid_directory: - iteration += 1 - - return iteration - def readCurrentRunPath(self): current_case = self.facade.get_current_case_name() run_path = self.facade.run_path diff --git a/src/ert/gui/tools/load_results/load_results_tool.py b/src/ert/gui/tools/load_results/load_results_tool.py index 9d1454e2b32..c9712ec943f 100644 --- a/src/ert/gui/tools/load_results/load_results_tool.py +++ b/src/ert/gui/tools/load_results/load_results_tool.py @@ -34,16 +34,4 @@ def load(self, _): self.__dialog.accept() def is_valid_run_path(self) -> bool: - """A run path is considered valid if we can - insert realisation and iteration numbers""" - try: - # pylint: disable=pointless-statement - self.facade.run_path % (0, 0) - return True - except TypeError: - try: - # pylint: disable=pointless-statement - self.facade.run_path % 0 - return True - except TypeError: - return False + return self.facade.is_valid_runpath() diff --git a/src/ert/libres_facade.py b/src/ert/libres_facade.py index d7531f55a29..ed85dc805f8 100644 --- a/src/ert/libres_facade.py +++ b/src/ert/libres_facade.py @@ -159,6 +159,14 @@ def get_number_of_iterations(self) -> int: def have_observations(self) -> bool: return self._enkf_main.have_observations() + def is_valid_runpath(self) -> bool: + iter_0_paths = set(self.get_run_paths([True] * self.get_ensemble_size(), 0)) + iter_1_paths = set(self.get_run_paths([True] * self.get_ensemble_size(), 1)) + return ( + len(iter_0_paths) == self.get_ensemble_size() + and iter_0_paths != iter_1_paths + ) + @property def run_path(self) -> str: return self._enkf_main.getModelConfig().runpath_format_string diff --git a/test-data/batch_sim/batch_sim.ert b/test-data/batch_sim/batch_sim.ert index 70a3f98ee6f..4d386dd6b6a 100644 --- a/test-data/batch_sim/batch_sim.ert +++ b/test-data/batch_sim/batch_sim.ert @@ -5,7 +5,7 @@ NUM_REALIZATIONS 25 DEFINE storage/ -RUNPATH /runpath//realization-%d/iter-%d +RUNPATH /runpath//realization-/iter- ENSPATH /ensemble JOBNAME SNAKE_OIL_FIELD diff --git a/test-data/batch_sim/batch_sim_sleep_and_fail.ert b/test-data/batch_sim/batch_sim_sleep_and_fail.ert index 11c1f71b8ef..097d2c0d476 100644 --- a/test-data/batch_sim/batch_sim_sleep_and_fail.ert +++ b/test-data/batch_sim/batch_sim_sleep_and_fail.ert @@ -3,7 +3,7 @@ QUEUE_OPTION LOCAL MAX_RUNNING 10 NUM_REALIZATIONS 10 -RUNPATH runpath/realization-%d/iter-%d +RUNPATH runpath/realization-/iter- JOBNAME SNAKE_OIL_FIELD INSTALL_JOB SQUARE_PARAMS jobs/SQUARE_PARAMS diff --git a/test-data/batch_sim/sleepy_time.ert b/test-data/batch_sim/sleepy_time.ert index fbdf3a387d4..1cfa6dec312 100644 --- a/test-data/batch_sim/sleepy_time.ert +++ b/test-data/batch_sim/sleepy_time.ert @@ -3,7 +3,7 @@ QUEUE_OPTION LOCAL MAX_RUNNING 10 NUM_REALIZATIONS 10 -RUNPATH runpath/realization-%d-/iter-%d +RUNPATH runpath/realization--/iter- JOBNAME OLE_LUKKOYE INSTALL_JOB SLEEP jobs/SLEEP diff --git a/test-data/configuration_tests/ecl_config.ert b/test-data/configuration_tests/ecl_config.ert index 6030203972f..8b1909e5ec9 100644 --- a/test-data/configuration_tests/ecl_config.ert +++ b/test-data/configuration_tests/ecl_config.ert @@ -4,7 +4,7 @@ REFCASE input/refcase/SNAKE_OIL_FIELD GRID input/CASE.EGRID SCHEDULE_PREDICTION_FILE input/schedule.sch -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 MIN_REALIZATIONS 10 diff --git a/test-data/configuration_tests/ensemble_config.ert b/test-data/configuration_tests/ensemble_config.ert index 3e48d510539..fe842365331 100644 --- a/test-data/configuration_tests/ensemble_config.ert +++ b/test-data/configuration_tests/ensemble_config.ert @@ -1,5 +1,5 @@ JOBNAME Job%d -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 MIN_REALIZATIONS 10 diff --git a/test-data/configuration_tests/model_config.ert b/test-data/configuration_tests/model_config.ert index 42b146f11df..fb95d5992db 100644 --- a/test-data/configuration_tests/model_config.ert +++ b/test-data/configuration_tests/model_config.ert @@ -10,7 +10,7 @@ INSTALL_JOB SNAKE_OIL_DIFF input/jobs/SNAKE_OIL_DIFF -- ModelConfig specific input JOBNAME model_config_test -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 ENSPATH Ensemble diff --git a/test-data/configuration_tests/sched_file_as_history_source.ert b/test-data/configuration_tests/sched_file_as_history_source.ert index 27a3bd3b086..0ac035fd1c1 100644 --- a/test-data/configuration_tests/sched_file_as_history_source.ert +++ b/test-data/configuration_tests/sched_file_as_history_source.ert @@ -12,7 +12,7 @@ INSTALL_JOB SNAKE_OIL_DIFF input/jobs/SNAKE_OIL_DIFF -- ModelConfig specific input JOBNAME model_config_test -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 ENSPATH Ensemble diff --git a/test-data/poly_example/poly-ies.ert b/test-data/poly_example/poly-ies.ert index 6551792857c..e57a8ead014 100644 --- a/test-data/poly_example/poly-ies.ert +++ b/test-data/poly_example/poly-ies.ert @@ -3,7 +3,7 @@ JOBNAME poly_%d QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- OBS_CONFIG observations TIME_MAP time_map diff --git a/test-data/poly_example/poly.ert b/test-data/poly_example/poly.ert index 6551792857c..e57a8ead014 100644 --- a/test-data/poly_example/poly.ert +++ b/test-data/poly_example/poly.ert @@ -3,7 +3,7 @@ JOBNAME poly_%d QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- OBS_CONFIG observations TIME_MAP time_map diff --git a/test-data/poly_template/poly.ert.j2 b/test-data/poly_template/poly.ert.j2 index 51f06f31a4a..2570485809a 100644 --- a/test-data/poly_template/poly.ert.j2 +++ b/test-data/poly_template/poly.ert.j2 @@ -2,7 +2,7 @@ QUEUE_SYSTEM LOCAL QUEUE_OPTION LOCAL MAX_RUNNING 50 -RUNPATH poly_out/realization-%d/iter-%d +RUNPATH poly_out/realization-/iter- OBS_CONFIG observations diff --git a/test-data/simple_config/analysis_config b/test-data/simple_config/analysis_config index 6ed10a19f2c..e9f2d6d56f1 100644 --- a/test-data/simple_config/analysis_config +++ b/test-data/simple_config/analysis_config @@ -1,5 +1,5 @@ JOBNAME Job%d -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 MIN_REALIZATIONS 10 JOB_SCRIPT script.sh diff --git a/test-data/simple_config/minimum_config b/test-data/simple_config/minimum_config index 900560c3c6b..86eb0b03c5a 100644 --- a/test-data/simple_config/minimum_config +++ b/test-data/simple_config/minimum_config @@ -1,5 +1,5 @@ JOBNAME Job%d -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 MIN_REALIZATIONS 10 JOB_SCRIPT script.sh diff --git a/test-data/simple_config/slurm_config b/test-data/simple_config/slurm_config index d58309e66f0..397418a985d 100644 --- a/test-data/simple_config/slurm_config +++ b/test-data/simple_config/slurm_config @@ -1,5 +1,5 @@ JOBNAME Job%d -RUNPATH /tmp/simulations/run%d +RUNPATH /tmp/simulations/realization-/iter- NUM_REALIZATIONS 10 MIN_REALIZATIONS 10 JOB_SCRIPT script.sh diff --git a/test-data/snake_oil/snake_oil.ert b/test-data/snake_oil/snake_oil.ert index f72e60ec4cf..3a36f1bc7d8 100644 --- a/test-data/snake_oil/snake_oil.ert +++ b/test-data/snake_oil/snake_oil.ert @@ -8,7 +8,7 @@ ANALYSIS_SET_VAR STD_ENKF IES_INVERSION 1 DEFINE storage/ RANDOM_SEED 3593114179000630026631423308983283277868 -RUNPATH /runpath/realization-%d/iter-%d +RUNPATH /runpath/realization-/iter- ENSPATH /ensemble ECLBASE SNAKE_OIL_FIELD SUMMARY * diff --git a/test-data/snake_oil_field/snake_oil.ert b/test-data/snake_oil_field/snake_oil.ert index 470447ad738..305d614d375 100644 --- a/test-data/snake_oil_field/snake_oil.ert +++ b/test-data/snake_oil_field/snake_oil.ert @@ -7,7 +7,7 @@ GRID grid/CASE.EGRID DEFINE storage/ RANDOM_SEED 3593114179000630026631423308983283277868 -RUNPATH /runpath/realization-%d/iter-%d +RUNPATH /runpath/realization-/iter- ENSPATH /ensemble ECLBASE SNAKE_OIL_FIELD SUMMARY * diff --git a/test-data/snake_oil_field/snake_oil_field.ert b/test-data/snake_oil_field/snake_oil_field.ert index 6eec01a3725..a0f49d8df7b 100644 --- a/test-data/snake_oil_field/snake_oil_field.ert +++ b/test-data/snake_oil_field/snake_oil_field.ert @@ -6,7 +6,7 @@ GRID grid/CASE.EGRID DEFINE storage/ RANDOM_SEED 3593114179000630026631423308983283277868 -RUNPATH /runpath/realization-%d/iter-%d +RUNPATH /runpath/realization-/iter- ENSPATH /ensemble ECLBASE SNAKE_OIL_FIELD SUMMARY * diff --git a/test-data/snake_oil_field/snake_oil_surface.ert b/test-data/snake_oil_field/snake_oil_surface.ert index a5917e73ad3..dd28b5d38f6 100644 --- a/test-data/snake_oil_field/snake_oil_surface.ert +++ b/test-data/snake_oil_field/snake_oil_surface.ert @@ -7,7 +7,7 @@ DEFINE storage/ RANDOM_SEED 3593114179000630026631423308983283277868 -RUNPATH /runpath/realization-%d/iter-%d +RUNPATH /runpath/realization-/iter- ENSPATH /ensemble ECLBASE SNAKE_OIL_FIELD SUMMARY * diff --git a/test-data/snake_oil_structure/ert/model/user_config.ert b/test-data/snake_oil_structure/ert/model/user_config.ert index 6bcf335950b..6ed433aaeb4 100755 --- a/test-data/snake_oil_structure/ert/model/user_config.ert +++ b/test-data/snake_oil_structure/ert/model/user_config.ert @@ -19,7 +19,7 @@ DEFINE XYZ --------------------------------------------------- DATA_FILE ../../eclipse/model/SNAKE_OIL.DATA -- Location of the Eclipse .DATA-file GRID ../../eclipse/include/grid/CASE.EGRID -- Name of the Eclipse .GRID-file -RUNPATH ///realization-%d/iter-%d -- Runpath for simulations (first %d will be replaced with realization number, second %d with iteration number +RUNPATH ///realization-/iter- -- Runpath for simulations ( will be replaced with realization number, with iteration number) ECLBASE eclipse/model/-%d -- Name used for the ECLIPSE simulations (%d will be replaced with the realization number) ENSPATH ../output/storage/ -- Storage of internal ert data RUNPATH_FILE ../output/run_path_file/.ert-runpath-list_ -- Ert runpath file for workflows diff --git a/tests/test_config_parsing/test_model_config.py b/tests/test_config_parsing/test_model_config.py index 5689fc0a627..b56310e43f1 100644 --- a/tests/test_config_parsing/test_model_config.py +++ b/tests/test_config_parsing/test_model_config.py @@ -45,12 +45,21 @@ def test_default_model_config_ens_path(tmpdir): def test_default_model_config_run_path(tmpdir): - assert ( - ModelConfig( - num_realizations=1, - ).runpath_format_string - == "simulations/realization-%d/iter-%d" + mc = ModelConfig(num_realizations=1) + assert mc.runpath_format_string == "simulations/realization-/iter-" + + +def test_invalid_model_config_run_path(tmpdir): + mc = ModelConfig( + num_realizations=1, runpath_format_string="realization-no-specifier" ) + assert mc.runpath_format_string == "realization-no-specifier" + + +def test_deprecated_model_config_run_path(tmpdir): + runpath = "simulations/realization-%d/iter-%d" + mc = ModelConfig(num_realizations=1, runpath_format_string=runpath) + assert mc.runpath_format_string == runpath @given(config_generators()) diff --git a/tests/test_config_parsing/test_res_config.py b/tests/test_config_parsing/test_res_config.py index 47a20b714d5..770039f415d 100644 --- a/tests/test_config_parsing/test_res_config.py +++ b/tests/test_config_parsing/test_res_config.py @@ -80,7 +80,7 @@ def test_res_config_parses_date(): """ NUM_REALIZATIONS 1 DEFINE storage/- - RUNPATH /runpath/realization-%d/iter-%d + RUNPATH /runpath/realization-/iter- ENSPATH /ensemble """ ) @@ -90,7 +90,7 @@ def test_res_config_parses_date(): date_string = date.today().isoformat() expected_storage = os.path.abspath(f"storage/{test_config_file_base}-{date_string}") - expected_run_path = f"{expected_storage}/runpath/realization-%d/iter-%d" + expected_run_path = f"{expected_storage}/runpath/realization-/iter-" expected_ens_path = f"{expected_storage}/ensemble" assert res_config.model_config.ens_path == expected_ens_path assert res_config.model_config.runpath_format_string == expected_run_path diff --git a/tests/unit_tests/c_wrappers/res/enkf/test_model_config.py b/tests/unit_tests/c_wrappers/res/enkf/test_model_config.py index e274107a7b8..7e20749d735 100644 --- a/tests/unit_tests/c_wrappers/res/enkf/test_model_config.py +++ b/tests/unit_tests/c_wrappers/res/enkf/test_model_config.py @@ -16,7 +16,7 @@ def test_eclbase_and_jobname(): "QUEUE_SYSTEM": { "JOBNAME": "JOBNAME%d", }, - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": 1, "JOB_SCRIPT": "script.sh", "ENSPATH": "Ensemble", @@ -35,7 +35,7 @@ def test_eclbase(): "CONFIG_DIRECTORY": ".", }, "SIMULATION": { - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": 1, "JOB_SCRIPT": "script.sh", "ENSPATH": "Ensemble", @@ -58,7 +58,7 @@ def test_jobname(): "QUEUE_SYSTEM": { "JOBNAME": "JOBNAME%d", }, - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": 1, "JOB_SCRIPT": "script.sh", "ENSPATH": "Ensemble", @@ -72,7 +72,7 @@ def test_model_config_dict_constructor(setup_case): res_config_from_file = setup_case("configuration_tests", "model_config.ert") config_dict = { ConfigKeys.JOBNAME: "model_config_test", - ConfigKeys.RUNPATH: "/tmp/simulations/run%d", + ConfigKeys.RUNPATH: "/tmp/simulations/realization-/iter-", ConfigKeys.NUM_REALIZATIONS: 10, ConfigKeys.ENSPATH: os.path.join(os.getcwd(), "Ensemble"), ConfigKeys.TIME_MAP: os.path.join(os.getcwd(), "input/refcase/time_map.txt"), diff --git a/tests/unit_tests/c_wrappers/res/enkf/test_programmatic_res_config.py b/tests/unit_tests/c_wrappers/res/enkf/test_programmatic_res_config.py index baba9838e95..8a8dce4e61b 100644 --- a/tests/unit_tests/c_wrappers/res/enkf/test_programmatic_res_config.py +++ b/tests/unit_tests/c_wrappers/res/enkf/test_programmatic_res_config.py @@ -18,7 +18,7 @@ def fixture_minimum_config_dict(): "QUEUE_SYSTEM": { "JOBNAME": "Job%d", }, - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": 10, "MIN_REALIZATIONS": 10, "JOB_SCRIPT": "script.sh", @@ -66,7 +66,7 @@ def test_errors(): "QUEUE_SYSTEM": { "JOBNAME": "Job%d", }, - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": "/should/be/an/integer", "JOB_SCRIPT": "script.sh", "ENSPATH": "Ensemble", @@ -87,7 +87,7 @@ def test_failed_keys(): "QUEUE_SYSTEM": { "JOBNAME": "Job%d", }, - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": 10, "JOB_SCRIPT": "script.sh", "ENSPATH": "Ensemble", @@ -185,7 +185,7 @@ def test_large_config(setup_case): ], }, "DATA_FILE": "eclipse/model/SNAKE_OIL.DATA", - "RUNPATH": "///realization-%d/iter-%d", + "RUNPATH": "///realization-/iter-", "RUNPATH_FILE": "../output/run_path_file/.ert-runpath-list_", "ECLBASE": "eclipse/model/-%d", "NUM_REALIZATIONS": "10", diff --git a/tests/unit_tests/c_wrappers/res/enkf/test_res_config.py b/tests/unit_tests/c_wrappers/res/enkf/test_res_config.py index 0de1df78e35..6bc5a3f6614 100644 --- a/tests/unit_tests/c_wrappers/res/enkf/test_res_config.py +++ b/tests/unit_tests/c_wrappers/res/enkf/test_res_config.py @@ -28,7 +28,7 @@ } snake_oil_structure_config = { - "RUNPATH": "///realization-%d/iter-%d", + "RUNPATH": "///realization-/iter-", "NUM_REALIZATIONS": 10, "MAX_RUNTIME": 23400, "MIN_REALIZATIONS": "50%", @@ -147,7 +147,7 @@ def test_missing_directory(): "QUEUE_SYSTEM": { "JOBNAME": "Job%d", }, - "RUNPATH": "/tmp/simulations/run%d", + "RUNPATH": "/tmp/simulations/realization-/iter-", "NUM_REALIZATIONS": 1, "JOB_SCRIPT": "script.sh", "ENSPATH": "Ensemble", @@ -308,7 +308,7 @@ def test_res_config_dict_constructor(setup_case): ConfigKeys.MIN_REALIZATIONS: 5, # "MIN_REALIZATIONS" : "50%", percentages need to be fixed or removed ConfigKeys.RUNPATH: os.path.join( - os.getcwd(), "///realization-%d/iter-%d" + os.getcwd(), "///realization-/iter-" ), ConfigKeys.NUM_REALIZATIONS: 10, # model ConfigKeys.MAX_RUNTIME: 23400, @@ -535,7 +535,8 @@ def test_that_job_script_can_be_set_in_site_config(monkeypatch, tmp_path): test_user_config = tmp_path / "user_config.ert" test_user_config.write_text( - "JOBNAME Job%d\nRUNPATH /tmp/simulations/run%d\nNUM_REALIZATIONS 10\n" + "JOBNAME Job%d\nRUNPATH /tmp/simulations/realization-/iter-\n" + "NUM_REALIZATIONS 10\n" ) res_config = ResConfig(str(test_user_config)) @@ -559,7 +560,7 @@ def test_that_unknown_queue_option_gives_error_message( test_user_config = tmp_path / "user_config.ert" test_user_config.write_text( - "JOBNAME Job%d\nRUNPATH /tmp/simulations/run%d\n" + "JOBNAME Job%d\nRUNPATH /tmp/simulations/realization-/iter-\n" "NUM_REALIZATIONS 10\nQUEUE_OPTION UNKNOWN_QUEUE unsetoption\n" ) @@ -586,7 +587,7 @@ def test_that_workflow_run_modes_can_be_selected(tmp_path, run_mode): os.chmod(my_script, st.st_mode | stat.S_IEXEC) test_user_config = tmp_path / "user_config.ert" test_user_config.write_text( - "JOBNAME Job%d\nRUNPATH /tmp/simulations/run%d\n" + "JOBNAME Job%d\nRUNPATH /tmp/simulations/realization-/iter-\n" "NUM_REALIZATIONS 10\n" f"LOAD_WORKFLOW {my_script} SCRIPT\n" f"HOOK_WORKFLOW SCRIPT {run_mode}\n" @@ -650,7 +651,7 @@ def test_logging_snake_oil_config(caplog, source_root): DEFINE XYZ DATA_FILE ../../eclipse/model/SNAKE_OIL.DATA GRID ../../eclipse/include/grid/CASE.EGRID -RUNPATH ///realization-%d/iter-%d +RUNPATH ///realization-/iter- ECLBASE eclipse/model/-%d ENSPATH ../output/storage/ RUNPATH_FILE ../output/run_path_file/.ert-runpath-list_ diff --git a/tests/unit_tests/gui/tools/test_case_tool.py b/tests/unit_tests/gui/tools/test_case_tool.py index 6c766c0a1bb..52f35f95d7a 100644 --- a/tests/unit_tests/gui/tools/test_case_tool.py +++ b/tests/unit_tests/gui/tools/test_case_tool.py @@ -5,9 +5,11 @@ from qtpy.QtCore import Qt from qtpy.QtWidgets import QPushButton +from ert import LibresFacade from ert._c_wrappers.enkf import EnKFMain, ResConfig from ert._clib.state_map import RealizationStateEnum from ert._clib.update import Parameter +from ert.gui.tools.load_results import LoadResultsTool from ert.gui.tools.manage_cases.case_init_configuration import ( CaseInitializationConfigurationPanel, ) @@ -70,3 +72,19 @@ def test_that_case_tool_can_copy_case_state(qtbot): assert new_case.load_parameter(config_node, [0], parameter,).flatten()[ 0 ] == pytest.approx(-0.8814227775506998) + + +@pytest.mark.parametrize( + "run_path, expected", + [ + ("valid_%d", False), + ("valid_%d/iter_%d", True), + ("real-/iter-", True), + ("invalid", False), + ], +) +def test_results_tool_valid_runpath(run_path, expected, tmp_path): + config_file = tmp_path / "config.ert" + config_file.write_text(f"NUM_REALIZATIONS 1\nRUNPATH {run_path}\n") + tool = LoadResultsTool(LibresFacade.from_config_file(str(config_file))) + assert tool.is_valid_run_path() is expected diff --git a/tests/unit_tests/gui/tools/test_results_tool.py b/tests/unit_tests/gui/tools/test_results_tool.py deleted file mode 100644 index 7c9361911e2..00000000000 --- a/tests/unit_tests/gui/tools/test_results_tool.py +++ /dev/null @@ -1,21 +0,0 @@ -from unittest.mock import MagicMock - -import pytest - -from ert.gui.tools.load_results import LoadResultsTool - - -@pytest.mark.parametrize( - "run_path, expected", - [ - ("valid_%d", True), - ("valid_%d/iter_%d", True), - ("invalid_%d_%d_%d", False), - ("invalid", False), - ], -) -def test_results_tool_valid_runpath(run_path, expected): - facade_mock = MagicMock() - facade_mock.run_path = run_path - tool = LoadResultsTool(facade_mock) - assert tool.is_valid_run_path() is expected diff --git a/tests/unit_tests/lsf_queue/test_lsf_driver.py b/tests/unit_tests/lsf_queue/test_lsf_driver.py index 8bd5bdb3a4b..f87c232e5b4 100644 --- a/tests/unit_tests/lsf_queue/test_lsf_driver.py +++ b/tests/unit_tests/lsf_queue/test_lsf_driver.py @@ -158,7 +158,7 @@ def copy_lsf_poly_case(copy_poly_case): "QUEUE_OPTION LSF MAX_RUNNING 10\n", "QUEUE_OPTION LSF BJOBS_CMD ../mock_bjobs\n", "QUEUE_OPTION LSF BSUB_CMD ../mock_bsub\n", - "RUNPATH poly_out/realization-%d/iter-%d\n", + "RUNPATH poly_out/realization-/iter-\n", "OBS_CONFIG observations\n", "TIME_MAP time_map\n", "NUM_REALIZATIONS 10\n", diff --git a/tests/unit_tests/shared/share/test_shell.py b/tests/unit_tests/shared/share/test_shell.py index da664578ce3..9270fdb109c 100644 --- a/tests/unit_tests/shared/share/test_shell.py +++ b/tests/unit_tests/shared/share/test_shell.py @@ -363,7 +363,7 @@ def test_shell_scripts_integration(tmpdir): with open(ert_config_fname, "w", encoding="utf-8") as file_h: file_h.write( """ -RUNPATH realization-%d/iter-%d +RUNPATH realization-/iter- JOBNAME TEST QUEUE_SYSTEM LOCAL NUM_REALIZATIONS 1 From e2dd788a19268dc944f7ced9a8be60042312d2e8 Mon Sep 17 00:00:00 2001 From: Andreas Eknes Lie Date: Tue, 3 Jan 2023 08:23:57 +0100 Subject: [PATCH 2/2] Allow load results manually in ert gui Before load results manually would check whether runpath was valid, however that just checked for the precense of %d. Since results can be loaded regardless of %d, this button is now always enabled. --- src/ert/gui/tools/load_results/load_results_tool.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ert/gui/tools/load_results/load_results_tool.py b/src/ert/gui/tools/load_results/load_results_tool.py index c9712ec943f..b1e876db30c 100644 --- a/src/ert/gui/tools/load_results/load_results_tool.py +++ b/src/ert/gui/tools/load_results/load_results_tool.py @@ -14,7 +14,6 @@ def __init__(self, facade): ) self.__import_widget = None self.__dialog = None - self.setEnabled(self.is_valid_run_path()) def trigger(self): if self.__import_widget is None: