ert 16.0.9__py3-none-any.whl → 19.0.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- _ert/events.py +19 -2
- _ert/forward_model_runner/client.py +6 -2
- _ert/forward_model_runner/fm_dispatch.py +9 -6
- _ert/forward_model_runner/reporting/event.py +1 -0
- _ert/forward_model_runner/runner.py +1 -2
- _ert/utils.py +12 -0
- ert/__main__.py +58 -38
- ert/analysis/_enif_update.py +8 -4
- ert/analysis/_es_update.py +19 -6
- ert/analysis/_update_commons.py +16 -6
- ert/base_model_context.py +1 -1
- ert/cli/main.py +17 -12
- ert/cli/monitor.py +7 -0
- ert/config/__init__.py +17 -6
- ert/config/_create_observation_dataframes.py +118 -21
- ert/config/_get_num_cpu.py +1 -1
- ert/config/_observations.py +91 -2
- ert/config/_read_summary.py +74 -328
- ert/config/design_matrix.py +62 -23
- ert/config/distribution.py +1 -1
- ert/config/ensemble_config.py +9 -17
- ert/config/ert_config.py +155 -58
- ert/config/everest_control.py +234 -0
- ert/config/{everest_constraints_config.py → everest_response.py} +27 -15
- ert/config/field.py +99 -90
- ert/config/forward_model_step.py +122 -17
- ert/config/gen_data_config.py +5 -10
- ert/config/gen_kw_config.py +11 -41
- ert/config/known_response_types.py +14 -0
- ert/config/parameter_config.py +1 -33
- ert/config/parsing/_option_dict.py +10 -2
- ert/config/parsing/config_errors.py +1 -1
- ert/config/parsing/config_keywords.py +2 -1
- ert/config/parsing/config_schema.py +23 -11
- ert/config/parsing/config_schema_deprecations.py +3 -3
- ert/config/parsing/config_schema_item.py +26 -11
- ert/config/parsing/context_values.py +3 -3
- ert/config/parsing/file_context_token.py +1 -1
- ert/config/parsing/observations_parser.py +6 -2
- ert/config/parsing/queue_system.py +9 -0
- ert/config/parsing/schema_item_type.py +1 -0
- ert/config/queue_config.py +42 -50
- ert/config/response_config.py +0 -8
- ert/config/rft_config.py +275 -0
- ert/config/summary_config.py +3 -8
- ert/config/surface_config.py +73 -26
- ert/config/workflow_fixtures.py +2 -1
- ert/config/workflow_job.py +135 -54
- ert/dark_storage/client/__init__.py +2 -2
- ert/dark_storage/client/_session.py +4 -4
- ert/dark_storage/client/client.py +2 -2
- ert/dark_storage/common.py +12 -3
- ert/dark_storage/compute/misfits.py +11 -7
- ert/dark_storage/endpoints/compute/misfits.py +6 -4
- ert/dark_storage/endpoints/ensembles.py +4 -0
- ert/dark_storage/endpoints/experiment_server.py +30 -24
- ert/dark_storage/endpoints/experiments.py +2 -2
- ert/dark_storage/endpoints/observations.py +8 -6
- ert/dark_storage/endpoints/parameters.py +4 -12
- ert/dark_storage/endpoints/responses.py +24 -5
- ert/dark_storage/json_schema/ensemble.py +3 -0
- ert/dark_storage/json_schema/experiment.py +1 -1
- ert/data/_measured_data.py +6 -5
- ert/ensemble_evaluator/__init__.py +8 -1
- ert/ensemble_evaluator/config.py +2 -1
- ert/ensemble_evaluator/evaluator.py +81 -29
- ert/ensemble_evaluator/event.py +6 -0
- ert/ensemble_evaluator/snapshot.py +3 -1
- ert/ensemble_evaluator/state.py +1 -0
- ert/field_utils/__init__.py +8 -0
- ert/field_utils/field_utils.py +228 -15
- ert/field_utils/grdecl_io.py +1 -1
- ert/field_utils/roff_io.py +1 -1
- ert/gui/__init__.py +5 -2
- ert/gui/ertnotifier.py +1 -1
- ert/gui/ertwidgets/__init__.py +23 -16
- ert/gui/ertwidgets/analysismoduleedit.py +2 -2
- ert/gui/ertwidgets/checklist.py +1 -1
- ert/gui/ertwidgets/closabledialog.py +2 -0
- ert/gui/ertwidgets/copyablelabel.py +2 -0
- ert/gui/ertwidgets/create_experiment_dialog.py +3 -1
- ert/gui/ertwidgets/ensembleselector.py +2 -2
- ert/gui/ertwidgets/listeditbox.py +2 -0
- ert/gui/ertwidgets/models/__init__.py +2 -0
- ert/gui/ertwidgets/models/activerealizationsmodel.py +5 -1
- ert/gui/ertwidgets/models/path_model.py +1 -1
- ert/gui/ertwidgets/models/targetensemblemodel.py +5 -1
- ert/gui/ertwidgets/models/text_model.py +4 -1
- ert/gui/ertwidgets/pathchooser.py +0 -3
- ert/gui/ertwidgets/searchbox.py +17 -4
- ert/gui/ertwidgets/stringbox.py +2 -0
- ert/gui/{suggestor → ertwidgets/suggestor}/_suggestor_message.py +13 -4
- ert/gui/{suggestor → ertwidgets/suggestor}/suggestor.py +63 -30
- ert/gui/main.py +41 -13
- ert/gui/main_window.py +3 -7
- ert/gui/model/fm_step_list.py +3 -0
- ert/gui/model/real_list.py +1 -0
- ert/gui/model/snapshot.py +1 -0
- ert/gui/simulation/combobox_with_description.py +3 -0
- ert/gui/simulation/ensemble_experiment_panel.py +8 -2
- ert/gui/simulation/ensemble_information_filter_panel.py +7 -2
- ert/gui/simulation/ensemble_smoother_panel.py +8 -2
- ert/gui/simulation/evaluate_ensemble_panel.py +17 -7
- ert/gui/simulation/experiment_panel.py +18 -6
- ert/gui/simulation/manual_update_panel.py +35 -10
- ert/gui/simulation/multiple_data_assimilation_panel.py +13 -9
- ert/gui/simulation/run_dialog.py +47 -20
- ert/gui/simulation/single_test_run_panel.py +6 -3
- ert/gui/simulation/view/progress_widget.py +2 -0
- ert/gui/simulation/view/realization.py +5 -1
- ert/gui/simulation/view/update.py +2 -0
- ert/gui/summarypanel.py +20 -1
- ert/gui/tools/event_viewer/panel.py +3 -4
- ert/gui/tools/event_viewer/tool.py +2 -0
- ert/gui/tools/load_results/load_results_panel.py +1 -1
- ert/gui/tools/load_results/load_results_tool.py +2 -0
- ert/gui/tools/manage_experiments/export_dialog.py +136 -0
- ert/gui/tools/manage_experiments/manage_experiments_panel.py +2 -0
- ert/gui/tools/manage_experiments/storage_info_widget.py +121 -16
- ert/gui/tools/manage_experiments/storage_widget.py +4 -3
- ert/gui/tools/plot/customize/color_chooser.py +5 -2
- ert/gui/tools/plot/customize/customize_plot_dialog.py +2 -0
- ert/gui/tools/plot/customize/default_customization_view.py +4 -0
- ert/gui/tools/plot/customize/limits_customization_view.py +3 -0
- ert/gui/tools/plot/customize/statistics_customization_view.py +3 -0
- ert/gui/tools/plot/customize/style_chooser.py +2 -0
- ert/gui/tools/plot/customize/style_customization_view.py +3 -0
- ert/gui/tools/plot/data_type_keys_widget.py +2 -0
- ert/gui/tools/plot/data_type_proxy_model.py +3 -0
- ert/gui/tools/plot/plot_api.py +50 -28
- ert/gui/tools/plot/plot_ensemble_selection_widget.py +17 -10
- ert/gui/tools/plot/plot_widget.py +15 -2
- ert/gui/tools/plot/plot_window.py +41 -19
- ert/gui/tools/plot/plottery/plot_config.py +2 -0
- ert/gui/tools/plot/plottery/plot_context.py +14 -0
- ert/gui/tools/plot/plottery/plots/__init__.py +2 -0
- ert/gui/tools/plot/plottery/plots/cesp.py +3 -1
- ert/gui/tools/plot/plottery/plots/distribution.py +6 -1
- ert/gui/tools/plot/plottery/plots/ensemble.py +13 -5
- ert/gui/tools/plot/plottery/plots/gaussian_kde.py +12 -2
- ert/gui/tools/plot/plottery/plots/histogram.py +3 -1
- ert/gui/tools/plot/plottery/plots/misfits.py +436 -0
- ert/gui/tools/plot/plottery/plots/observations.py +18 -4
- ert/gui/tools/plot/plottery/plots/statistics.py +62 -20
- ert/gui/tools/plot/plottery/plots/std_dev.py +3 -1
- ert/gui/tools/plot/widgets/clearable_line_edit.py +9 -0
- ert/gui/tools/plot/widgets/filter_popup.py +2 -0
- ert/gui/tools/plot/widgets/filterable_kw_list_model.py +3 -0
- ert/gui/tools/plugins/plugin.py +1 -1
- ert/gui/tools/plugins/plugins_tool.py +2 -0
- ert/gui/tools/plugins/process_job_dialog.py +3 -0
- ert/gui/tools/workflows/workflow_dialog.py +2 -0
- ert/gui/tools/workflows/workflows_tool.py +2 -0
- ert/libres_facade.py +5 -7
- ert/logging/__init__.py +4 -1
- ert/mode_definitions.py +2 -0
- ert/plugins/__init__.py +4 -6
- ert/plugins/hook_implementations/workflows/csv_export.py +2 -3
- ert/plugins/hook_implementations/workflows/gen_data_rft_export.py +10 -2
- ert/plugins/hook_specifications/__init__.py +0 -10
- ert/plugins/hook_specifications/jobs.py +0 -9
- ert/plugins/plugin_manager.py +53 -124
- ert/resources/forward_models/run_reservoirsimulator.py +8 -4
- ert/resources/forward_models/template_render.py +10 -10
- ert/resources/shell_scripts/delete_directory.py +2 -2
- ert/run_models/__init__.py +24 -6
- ert/run_models/_create_run_path.py +133 -38
- ert/run_models/ensemble_experiment.py +10 -4
- ert/run_models/ensemble_information_filter.py +8 -1
- ert/run_models/ensemble_smoother.py +9 -3
- ert/run_models/evaluate_ensemble.py +8 -6
- ert/run_models/event.py +7 -3
- ert/run_models/everest_run_model.py +337 -113
- ert/run_models/initial_ensemble_run_model.py +25 -24
- ert/run_models/manual_update.py +6 -3
- ert/run_models/manual_update_enif.py +37 -0
- ert/run_models/model_factory.py +78 -18
- ert/run_models/multiple_data_assimilation.py +22 -11
- ert/run_models/run_model.py +72 -73
- ert/run_models/single_test_run.py +7 -4
- ert/run_models/update_run_model.py +4 -2
- ert/runpaths.py +5 -6
- ert/sample_prior.py +9 -4
- ert/scheduler/__init__.py +10 -5
- ert/scheduler/driver.py +40 -0
- ert/scheduler/event.py +3 -1
- ert/scheduler/job.py +23 -13
- ert/scheduler/lsf_driver.py +15 -5
- ert/scheduler/openpbs_driver.py +10 -4
- ert/scheduler/scheduler.py +5 -0
- ert/scheduler/slurm_driver.py +20 -5
- ert/services/__init__.py +2 -2
- ert/services/_base_service.py +37 -20
- ert/services/_storage_main.py +20 -18
- ert/services/ert_server.py +317 -0
- ert/shared/_doc_utils/__init__.py +4 -2
- ert/shared/_doc_utils/ert_jobs.py +1 -4
- ert/shared/net_utils.py +43 -18
- ert/shared/storage/connection.py +3 -3
- ert/shared/version.py +3 -3
- ert/storage/__init__.py +14 -1
- ert/storage/local_ensemble.py +44 -13
- ert/storage/local_experiment.py +54 -34
- ert/storage/local_storage.py +90 -58
- ert/storage/migration/to10.py +3 -2
- ert/storage/migration/to11.py +9 -10
- ert/storage/migration/to12.py +19 -20
- ert/storage/migration/to13.py +28 -27
- ert/storage/migration/to14.py +3 -3
- ert/storage/migration/to15.py +25 -0
- ert/storage/migration/to16.py +38 -0
- ert/storage/migration/to17.py +42 -0
- ert/storage/migration/to18.py +11 -0
- ert/storage/migration/to19.py +34 -0
- ert/storage/migration/to20.py +23 -0
- ert/storage/migration/to21.py +25 -0
- ert/storage/migration/to6.py +3 -2
- ert/storage/migration/to7.py +12 -13
- ert/storage/migration/to8.py +9 -11
- ert/storage/migration/to9.py +5 -4
- ert/storage/realization_storage_state.py +7 -7
- ert/substitutions.py +12 -28
- ert/validation/active_range.py +7 -7
- ert/validation/ensemble_realizations_argument.py +4 -2
- ert/validation/rangestring.py +16 -16
- ert/workflow_runner.py +6 -3
- {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/METADATA +21 -15
- ert-19.0.0rc2.dist-info/RECORD +524 -0
- {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/WHEEL +1 -1
- everest/api/everest_data_api.py +14 -1
- everest/assets/everest_logo.svg +406 -0
- everest/bin/config_branch_script.py +30 -14
- everest/bin/everconfigdump_script.py +2 -10
- everest/bin/everest_script.py +53 -33
- everest/bin/everlint_script.py +3 -5
- everest/bin/kill_script.py +7 -5
- everest/bin/main.py +11 -24
- everest/bin/monitor_script.py +64 -35
- everest/bin/utils.py +58 -43
- everest/bin/visualization_script.py +23 -13
- everest/config/__init__.py +4 -1
- everest/config/control_config.py +81 -6
- everest/config/control_variable_config.py +4 -3
- everest/config/everest_config.py +102 -79
- everest/config/forward_model_config.py +5 -3
- everest/config/install_data_config.py +7 -5
- everest/config/install_job_config.py +45 -3
- everest/config/install_template_config.py +3 -3
- everest/config/optimization_config.py +19 -6
- everest/config/output_constraint_config.py +8 -2
- everest/config/server_config.py +6 -55
- everest/config/simulator_config.py +62 -17
- everest/config/utils.py +25 -105
- everest/config/validation_utils.py +34 -15
- everest/config_file_loader.py +30 -21
- everest/detached/__init__.py +0 -6
- everest/detached/client.py +7 -52
- everest/detached/everserver.py +19 -45
- everest/everest_storage.py +24 -40
- everest/gui/everest_client.py +2 -3
- everest/gui/main_window.py +2 -2
- everest/optimizer/everest2ropt.py +68 -42
- everest/optimizer/opt_model_transforms.py +15 -20
- everest/optimizer/utils.py +0 -29
- everest/plugins/hook_specs.py +0 -24
- everest/strings.py +1 -6
- everest/util/__init__.py +3 -1
- ert/config/everest_objective_config.py +0 -95
- ert/config/ext_param_config.py +0 -107
- ert/gui/tools/export/__init__.py +0 -3
- ert/gui/tools/export/export_panel.py +0 -83
- ert/gui/tools/export/export_tool.py +0 -67
- ert/gui/tools/export/exporter.py +0 -36
- ert/plugins/hook_specifications/ecl_config.py +0 -29
- ert/services/storage_service.py +0 -127
- ert/summary_key_type.py +0 -234
- ert-16.0.9.dist-info/RECORD +0 -521
- everest/bin/everexport_script.py +0 -53
- everest/config/sampler_config.py +0 -103
- everest/simulator/__init__.py +0 -88
- everest/simulator/everest_to_ert.py +0 -252
- /ert/gui/{suggestor → ertwidgets/suggestor}/__init__.py +0 -0
- /ert/gui/{suggestor → ertwidgets/suggestor}/_colors.py +0 -0
- {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/entry_points.txt +0 -0
- {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/licenses/COPYING +0 -0
- {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/top_level.txt +0 -0
|
@@ -5,6 +5,7 @@ import numpy as np
|
|
|
5
5
|
from PyQt6.QtCore import Qt
|
|
6
6
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
7
7
|
from PyQt6.QtWidgets import QFormLayout, QLabel, QWidget
|
|
8
|
+
from typing_extensions import override
|
|
8
9
|
|
|
9
10
|
from ert.config import ErrorInfo
|
|
10
11
|
from ert.gui.ertnotifier import ErtNotifier
|
|
@@ -13,9 +14,9 @@ from ert.gui.ertwidgets import (
|
|
|
13
14
|
CopyableLabel,
|
|
14
15
|
EnsembleSelector,
|
|
15
16
|
StringBox,
|
|
17
|
+
Suggestor,
|
|
16
18
|
)
|
|
17
19
|
from ert.gui.simulation.experiment_config_panel import ExperimentConfigPanel
|
|
18
|
-
from ert.gui.suggestor import Suggestor
|
|
19
20
|
from ert.mode_definitions import EVALUATE_ENSEMBLE_MODE
|
|
20
21
|
from ert.run_models.evaluate_ensemble import EvaluateEnsemble
|
|
21
22
|
from ert.storage import RealizationStorageState
|
|
@@ -32,9 +33,7 @@ class Arguments:
|
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
class EvaluateEnsemblePanel(ExperimentConfigPanel):
|
|
35
|
-
def __init__(
|
|
36
|
-
self, ensemble_size: int, run_path: str, notifier: ErtNotifier
|
|
37
|
-
) -> None:
|
|
36
|
+
def __init__(self, run_path: str, notifier: ErtNotifier) -> None:
|
|
38
37
|
self.notifier = notifier
|
|
39
38
|
super().__init__(EvaluateEnsemble)
|
|
40
39
|
self.setObjectName("Evaluate_parameters_panel")
|
|
@@ -49,8 +48,14 @@ class EvaluateEnsemblePanel(ExperimentConfigPanel):
|
|
|
49
48
|
runpath_label = CopyableLabel(text=run_path)
|
|
50
49
|
layout.addRow("Runpath:", runpath_label)
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
ensemble_size = 0
|
|
52
|
+
if self._ensemble_selector.selected_ensemble:
|
|
53
|
+
ensemble_size = self._ensemble_selector.selected_ensemble.ensemble_size
|
|
54
|
+
|
|
55
|
+
self._number_of_realizations_label = QLabel(f"<b>{ensemble_size}</b>")
|
|
56
|
+
layout.addRow(
|
|
57
|
+
QLabel("Number of realizations:"), self._number_of_realizations_label
|
|
58
|
+
)
|
|
54
59
|
|
|
55
60
|
self._active_realizations_field = StringBox(
|
|
56
61
|
ActiveRealizationsModel(ensemble_size, show_default=False), # type: ignore
|
|
@@ -58,7 +63,6 @@ class EvaluateEnsemblePanel(ExperimentConfigPanel):
|
|
|
58
63
|
)
|
|
59
64
|
self._realizations_validator = EnsembleRealizationsArgument(
|
|
60
65
|
lambda: self._ensemble_selector.selected_ensemble,
|
|
61
|
-
max_value=ensemble_size,
|
|
62
66
|
required_realization_storage_states=[
|
|
63
67
|
RealizationStorageState.PARAMETERS_LOADED
|
|
64
68
|
],
|
|
@@ -78,12 +82,14 @@ class EvaluateEnsemblePanel(ExperimentConfigPanel):
|
|
|
78
82
|
)
|
|
79
83
|
self._ensemble_selector.currentIndexChanged.connect(self._realizations_from_fs)
|
|
80
84
|
|
|
85
|
+
@override
|
|
81
86
|
def isConfigurationValid(self) -> bool:
|
|
82
87
|
return (
|
|
83
88
|
self._active_realizations_field.isValid()
|
|
84
89
|
and self._ensemble_selector.currentIndex() != -1
|
|
85
90
|
)
|
|
86
91
|
|
|
92
|
+
@override
|
|
87
93
|
def get_experiment_arguments(self) -> Arguments:
|
|
88
94
|
assert self._ensemble_selector.selected_ensemble is not None
|
|
89
95
|
return Arguments(
|
|
@@ -106,6 +112,9 @@ class EvaluateEnsemblePanel(ExperimentConfigPanel):
|
|
|
106
112
|
if not any(mask):
|
|
107
113
|
mask = parameters
|
|
108
114
|
self._active_realizations_field.model.setValueFromMask(mask) # type: ignore
|
|
115
|
+
self._number_of_realizations_label.setText(
|
|
116
|
+
f"<b>{ensemble.ensemble_size}</b>"
|
|
117
|
+
)
|
|
109
118
|
except OSError as err:
|
|
110
119
|
logger.error(str(err))
|
|
111
120
|
Suggestor(
|
|
@@ -114,6 +123,7 @@ class EvaluateEnsemblePanel(ExperimentConfigPanel):
|
|
|
114
123
|
parent=self,
|
|
115
124
|
).show()
|
|
116
125
|
|
|
126
|
+
@override
|
|
117
127
|
@Slot(QWidget)
|
|
118
128
|
def experimentTypeChanged(self, w: QWidget) -> None:
|
|
119
129
|
if isinstance(w, EvaluateEnsemblePanel):
|
|
@@ -55,9 +55,15 @@ def create_md_table(kv: dict[str, str], output: str) -> str:
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
def get_simulation_thread(
|
|
58
|
-
model: Any,
|
|
58
|
+
model: Any,
|
|
59
|
+
rerun_failed_realizations: bool = False,
|
|
60
|
+
use_ipc_protocol: bool = False,
|
|
61
|
+
prioritize_private_ip_address: bool = False,
|
|
59
62
|
) -> ErtThread:
|
|
60
|
-
evaluator_server_config = EvaluatorServerConfig(
|
|
63
|
+
evaluator_server_config = EvaluatorServerConfig(
|
|
64
|
+
use_ipc_protocol=use_ipc_protocol,
|
|
65
|
+
prioritize_private_ip_address=prioritize_private_ip_address,
|
|
66
|
+
)
|
|
61
67
|
|
|
62
68
|
def run() -> None:
|
|
63
69
|
model.api.start_simulations_thread(
|
|
@@ -158,7 +164,6 @@ class ExperimentPanel(QWidget):
|
|
|
158
164
|
True,
|
|
159
165
|
)
|
|
160
166
|
|
|
161
|
-
ensemble_size = config.ensemble_size
|
|
162
167
|
active_realizations = config.active_realizations
|
|
163
168
|
config_num_realization = config.runpath_config.num_realizations
|
|
164
169
|
self.addExperimentConfigPanel(
|
|
@@ -173,7 +178,7 @@ class ExperimentPanel(QWidget):
|
|
|
173
178
|
True,
|
|
174
179
|
)
|
|
175
180
|
self.addExperimentConfigPanel(
|
|
176
|
-
EvaluateEnsemblePanel(
|
|
181
|
+
EvaluateEnsemblePanel(run_path, notifier),
|
|
177
182
|
True,
|
|
178
183
|
)
|
|
179
184
|
|
|
@@ -215,7 +220,7 @@ class ExperimentPanel(QWidget):
|
|
|
215
220
|
experiment_type_valid,
|
|
216
221
|
)
|
|
217
222
|
self.addExperimentConfigPanel(
|
|
218
|
-
ManualUpdatePanel(
|
|
223
|
+
ManualUpdatePanel(run_path, notifier, analysis_config),
|
|
219
224
|
experiment_type_valid,
|
|
220
225
|
)
|
|
221
226
|
|
|
@@ -355,6 +360,10 @@ class ExperimentPanel(QWidget):
|
|
|
355
360
|
return
|
|
356
361
|
QApplication.restoreOverrideCursor()
|
|
357
362
|
|
|
363
|
+
self.configuration_summary.log_summary(
|
|
364
|
+
args.mode, model.get_number_of_active_realizations()
|
|
365
|
+
)
|
|
366
|
+
|
|
358
367
|
self._dialog = RunDialog(
|
|
359
368
|
f"Experiment - {self._config_file} {find_ert_info()}",
|
|
360
369
|
model.api,
|
|
@@ -365,7 +374,9 @@ class ExperimentPanel(QWidget):
|
|
|
365
374
|
run_path=Path(self.config.runpath_config.runpath_format_string),
|
|
366
375
|
storage_path=self._notifier.storage.path,
|
|
367
376
|
)
|
|
368
|
-
self._dialog.
|
|
377
|
+
self._dialog.queue_system.setText(
|
|
378
|
+
f"Queue system:\n{model.queue_config.queue_system.formatted_name}"
|
|
379
|
+
)
|
|
369
380
|
self.experiment_started.emit(self._dialog)
|
|
370
381
|
self._simulation_done = False
|
|
371
382
|
self.run_button.setEnabled(self._simulation_done)
|
|
@@ -376,6 +387,7 @@ class ExperimentPanel(QWidget):
|
|
|
376
387
|
rerun_failed_realizations,
|
|
377
388
|
use_ipc_protocol=self.config.queue_config.queue_system
|
|
378
389
|
== QueueSystem.LOCAL,
|
|
390
|
+
prioritize_private_ip_address=self.config.prioritize_private_ip_address,
|
|
379
391
|
)
|
|
380
392
|
self._dialog.setup_event_monitoring(rerun_failed_realizations)
|
|
381
393
|
simulation_thread.start()
|
|
@@ -3,9 +3,10 @@ from dataclasses import dataclass
|
|
|
3
3
|
from typing import cast
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
|
-
from PyQt6.QtCore import
|
|
6
|
+
from PyQt6.QtCore import pyqtSignal
|
|
7
7
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
8
|
-
from PyQt6.QtWidgets import QFormLayout, QLabel, QWidget
|
|
8
|
+
from PyQt6.QtWidgets import QComboBox, QFormLayout, QLabel, QWidget
|
|
9
|
+
from typing_extensions import override
|
|
9
10
|
|
|
10
11
|
from ert.config import AnalysisConfig, ErrorInfo
|
|
11
12
|
from ert.gui.ertnotifier import ErtNotifier
|
|
@@ -15,11 +16,11 @@ from ert.gui.ertwidgets import (
|
|
|
15
16
|
CopyableLabel,
|
|
16
17
|
EnsembleSelector,
|
|
17
18
|
StringBox,
|
|
19
|
+
Suggestor,
|
|
18
20
|
TargetEnsembleModel,
|
|
19
21
|
)
|
|
20
22
|
from ert.gui.simulation.experiment_config_panel import ExperimentConfigPanel
|
|
21
|
-
from ert.
|
|
22
|
-
from ert.mode_definitions import MANUAL_UPDATE_MODE
|
|
23
|
+
from ert.mode_definitions import MANUAL_ENIF_UPDATE_MODE, MANUAL_UPDATE_MODE
|
|
23
24
|
from ert.run_models.manual_update import ManualUpdate
|
|
24
25
|
from ert.storage import Ensemble, RealizationStorageState
|
|
25
26
|
from ert.validation import EnsembleRealizationsArgument, ProperNameFormatArgument
|
|
@@ -37,9 +38,10 @@ class Arguments:
|
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
class ManualUpdatePanel(ExperimentConfigPanel):
|
|
41
|
+
updateMethodChanged = pyqtSignal(str)
|
|
42
|
+
|
|
40
43
|
def __init__(
|
|
41
44
|
self,
|
|
42
|
-
ensemble_size: int,
|
|
43
45
|
run_path: str,
|
|
44
46
|
notifier: ErtNotifier,
|
|
45
47
|
analysis_config: AnalysisConfig,
|
|
@@ -49,9 +51,17 @@ class ManualUpdatePanel(ExperimentConfigPanel):
|
|
|
49
51
|
self.setObjectName("Manual_update_panel")
|
|
50
52
|
|
|
51
53
|
layout = QFormLayout()
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
self._update_method_dropdown = QComboBox()
|
|
55
|
+
self._update_method_dropdown.addItems(
|
|
56
|
+
["ES Update", "EnIF Update (Experimental)"]
|
|
57
|
+
)
|
|
58
|
+
self._update_method_dropdown.currentTextChanged.connect(
|
|
59
|
+
self._on_update_method_changed
|
|
60
|
+
)
|
|
61
|
+
self._update_method_dropdown.setObjectName("manual_update_method_dropdown")
|
|
62
|
+
|
|
63
|
+
layout.addRow("Update method:", self._update_method_dropdown)
|
|
64
|
+
|
|
55
65
|
self._ensemble_selector = EnsembleSelector(
|
|
56
66
|
notifier, show_only_with_response_data=True
|
|
57
67
|
)
|
|
@@ -97,15 +107,30 @@ class ManualUpdatePanel(ExperimentConfigPanel):
|
|
|
97
107
|
self._ensemble_selector.currentIndexChanged.connect(self._realizations_from_fs)
|
|
98
108
|
self.setLayout(layout)
|
|
99
109
|
|
|
110
|
+
@property
|
|
111
|
+
def selected_update_method(self) -> str:
|
|
112
|
+
return self._update_method_dropdown.currentText()
|
|
113
|
+
|
|
114
|
+
@Slot(str)
|
|
115
|
+
def _on_update_method_changed(self, new_method: str) -> None:
|
|
116
|
+
if new_method == "ES Update":
|
|
117
|
+
self._analysis_module_edit.show()
|
|
118
|
+
else:
|
|
119
|
+
self._analysis_module_edit.hide()
|
|
120
|
+
|
|
121
|
+
@override
|
|
100
122
|
def isConfigurationValid(self) -> bool:
|
|
101
123
|
return (
|
|
102
124
|
self._active_realizations_field.isValid()
|
|
103
125
|
and self._ensemble_selector.currentIndex() != -1
|
|
104
126
|
)
|
|
105
127
|
|
|
128
|
+
@override
|
|
106
129
|
def get_experiment_arguments(self) -> Arguments:
|
|
107
130
|
return Arguments(
|
|
108
|
-
mode=MANUAL_UPDATE_MODE
|
|
131
|
+
mode=MANUAL_UPDATE_MODE
|
|
132
|
+
if self.selected_update_method == "ES Update"
|
|
133
|
+
else MANUAL_ENIF_UPDATE_MODE,
|
|
109
134
|
ensemble_id=str(
|
|
110
135
|
cast(Ensemble, self._ensemble_selector.selected_ensemble).id
|
|
111
136
|
),
|
|
@@ -126,7 +151,6 @@ class ManualUpdatePanel(ExperimentConfigPanel):
|
|
|
126
151
|
self._active_realizations_field.setValidator(
|
|
127
152
|
EnsembleRealizationsArgument(
|
|
128
153
|
lambda: ensemble,
|
|
129
|
-
max_value=ensemble.ensemble_size,
|
|
130
154
|
required_realization_storage_states=[
|
|
131
155
|
RealizationStorageState.PARAMETERS_LOADED,
|
|
132
156
|
RealizationStorageState.RESPONSES_LOADED,
|
|
@@ -148,6 +172,7 @@ class ManualUpdatePanel(ExperimentConfigPanel):
|
|
|
148
172
|
parent=self,
|
|
149
173
|
).show()
|
|
150
174
|
|
|
175
|
+
@override
|
|
151
176
|
@Slot(QWidget)
|
|
152
177
|
def experimentTypeChanged(self, w: QWidget) -> None:
|
|
153
178
|
if isinstance(w, ManualUpdatePanel):
|
|
@@ -8,6 +8,7 @@ from PyQt6.QtCore import Qt
|
|
|
8
8
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
9
9
|
from PyQt6.QtGui import QFont
|
|
10
10
|
from PyQt6.QtWidgets import QCheckBox, QFormLayout, QHBoxLayout, QLabel, QWidget
|
|
11
|
+
from typing_extensions import override
|
|
11
12
|
|
|
12
13
|
from ert.config import ErrorInfo, ParameterConfig
|
|
13
14
|
from ert.gui.ertnotifier import ErtNotifier
|
|
@@ -17,14 +18,14 @@ from ert.gui.ertwidgets import (
|
|
|
17
18
|
CopyableLabel,
|
|
18
19
|
EnsembleSelector,
|
|
19
20
|
StringBox,
|
|
21
|
+
Suggestor,
|
|
20
22
|
TargetEnsembleModel,
|
|
21
23
|
TextModel,
|
|
22
24
|
ValueModel,
|
|
25
|
+
get_parameters_button,
|
|
23
26
|
)
|
|
24
|
-
from ert.gui.ertwidgets.parameterviewer import get_parameters_button
|
|
25
|
-
from ert.gui.suggestor import Suggestor
|
|
26
27
|
from ert.mode_definitions import ES_MDA_MODE
|
|
27
|
-
from ert.run_models import MultipleDataAssimilation
|
|
28
|
+
from ert.run_models import MultipleDataAssimilation, MultipleDataAssimilationConfig
|
|
28
29
|
from ert.storage.realization_storage_state import RealizationStorageState
|
|
29
30
|
from ert.validation import (
|
|
30
31
|
ExperimentValidation,
|
|
@@ -113,7 +114,7 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
113
114
|
self._target_ensemble_format_field.setValidator(ProperNameFormatArgument())
|
|
114
115
|
layout.addRow("Target ensemble format:", self._target_ensemble_format_field)
|
|
115
116
|
|
|
116
|
-
self.weights =
|
|
117
|
+
self.weights = MultipleDataAssimilationConfig.default_weights
|
|
117
118
|
self.weights_valid = True
|
|
118
119
|
self._createInputForWeights(layout)
|
|
119
120
|
|
|
@@ -139,7 +140,6 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
139
140
|
self._ensemble_selector = EnsembleSelector(notifier)
|
|
140
141
|
self._previous_ensemble_realizations_validator = EnsembleRealizationsArgument(
|
|
141
142
|
lambda: self._ensemble_selector.selected_ensemble,
|
|
142
|
-
max_value=len(active_realizations),
|
|
143
143
|
required_realization_storage_states=[
|
|
144
144
|
RealizationStorageState.RESPONSES_LOADED
|
|
145
145
|
],
|
|
@@ -189,12 +189,14 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
189
189
|
merged_parameters
|
|
190
190
|
)
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
if merged_parameters:
|
|
193
|
+
layout.addRow("Parameters", get_parameters_button(merged_parameters, self))
|
|
193
194
|
|
|
194
195
|
self.setLayout(layout)
|
|
195
196
|
|
|
196
197
|
self.notifier.ertChanged.connect(self._update_experiment_name_placeholder)
|
|
197
198
|
|
|
199
|
+
@override
|
|
198
200
|
@Slot(QWidget)
|
|
199
201
|
def experimentTypeChanged(self, w: QWidget) -> None:
|
|
200
202
|
if isinstance(w, MultipleDataAssimilationPanel):
|
|
@@ -215,7 +217,7 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
215
217
|
|
|
216
218
|
self._relative_iteration_weights_box.setText(
|
|
217
219
|
self._ensemble_selector.selected_ensemble.relative_weights
|
|
218
|
-
or
|
|
220
|
+
or MultipleDataAssimilationConfig.default_weights
|
|
219
221
|
)
|
|
220
222
|
self._evaluate_weights_box_enabled()
|
|
221
223
|
|
|
@@ -250,9 +252,9 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
250
252
|
self._ensemble_selector.selected_ensemble is not None
|
|
251
253
|
and self._ensemble_selector.selected_ensemble.relative_weights
|
|
252
254
|
)
|
|
253
|
-
or
|
|
255
|
+
or MultipleDataAssimilationConfig.default_weights
|
|
254
256
|
if self._restart_box.isChecked()
|
|
255
|
-
else
|
|
257
|
+
else MultipleDataAssimilationConfig.default_weights
|
|
256
258
|
)
|
|
257
259
|
if self._restart_box.isChecked():
|
|
258
260
|
self._active_realizations_field.setValidator(
|
|
@@ -307,6 +309,7 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
307
309
|
|
|
308
310
|
updateVisualizationOfNormalizedWeights() # To normalize the default weights
|
|
309
311
|
|
|
312
|
+
@override
|
|
310
313
|
def isConfigurationValid(self) -> bool:
|
|
311
314
|
return (
|
|
312
315
|
self._experiment_name_field.isValid()
|
|
@@ -316,6 +319,7 @@ class MultipleDataAssimilationPanel(ExperimentConfigPanel):
|
|
|
316
319
|
and self.weights_valid
|
|
317
320
|
)
|
|
318
321
|
|
|
322
|
+
@override
|
|
319
323
|
def get_experiment_arguments(self) -> Arguments:
|
|
320
324
|
return Arguments(
|
|
321
325
|
mode=ES_MDA_MODE,
|
ert/gui/simulation/run_dialog.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from datetime import datetime
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from queue import SimpleQueue
|
|
6
|
-
from typing import
|
|
7
|
+
from typing import cast
|
|
7
8
|
|
|
8
9
|
import humanize
|
|
9
10
|
from PyQt6.QtCore import QModelIndex, QSize, Qt, QThread, QTimer
|
|
@@ -28,16 +29,20 @@ from PyQt6.QtWidgets import (
|
|
|
28
29
|
QVBoxLayout,
|
|
29
30
|
QWidget,
|
|
30
31
|
)
|
|
32
|
+
from typing_extensions import override
|
|
31
33
|
|
|
32
|
-
from
|
|
34
|
+
from _ert.events import EnsembleEvaluationWarning
|
|
35
|
+
from ert.config import ErrorInfo, WarningInfo
|
|
33
36
|
from ert.ensemble_evaluator import (
|
|
34
37
|
EndEvent,
|
|
35
38
|
FullSnapshotEvent,
|
|
36
39
|
SnapshotUpdateEvent,
|
|
40
|
+
StartEvent,
|
|
37
41
|
WarningEvent,
|
|
38
42
|
)
|
|
39
43
|
from ert.ensemble_evaluator import identifiers as ids
|
|
40
44
|
from ert.gui.ertnotifier import ErtNotifier
|
|
45
|
+
from ert.gui.ertwidgets import Suggestor
|
|
41
46
|
from ert.gui.model.fm_step_list import FMStepListProxyModel
|
|
42
47
|
from ert.gui.model.node import IterNode
|
|
43
48
|
from ert.gui.model.real_list import RealListModel
|
|
@@ -48,7 +53,6 @@ from ert.gui.model.snapshot import (
|
|
|
48
53
|
RealIens,
|
|
49
54
|
SnapshotModel,
|
|
50
55
|
)
|
|
51
|
-
from ert.gui.suggestor import Suggestor
|
|
52
56
|
from ert.gui.tools.file import FileDialog
|
|
53
57
|
from ert.run_models import (
|
|
54
58
|
RunModelAPI,
|
|
@@ -175,6 +179,7 @@ class FMStepOverview(QTableView):
|
|
|
175
179
|
error_textedit.moveCursor(QTextCursor.MoveOperation.Start)
|
|
176
180
|
error_dialog.exec()
|
|
177
181
|
|
|
182
|
+
@override
|
|
178
183
|
def mouseMoveEvent(self, e: QMouseEvent | None) -> None:
|
|
179
184
|
if e:
|
|
180
185
|
index = self.indexAt(e.pos())
|
|
@@ -256,6 +261,7 @@ class RunDialog(QFrame):
|
|
|
256
261
|
self._fm_step_label.setObjectName("fm_step_label")
|
|
257
262
|
self._fm_step_overview = FMStepOverview(self._snapshot_model, self)
|
|
258
263
|
|
|
264
|
+
self._start_time: datetime | None = None
|
|
259
265
|
self.running_time = QLabel("Running time:\n -")
|
|
260
266
|
self.running_time.setMinimumWidth(150)
|
|
261
267
|
self.queue_system = QLabel("")
|
|
@@ -266,6 +272,9 @@ class RunDialog(QFrame):
|
|
|
266
272
|
self.kill_button = QPushButton("Terminate experiment")
|
|
267
273
|
self.rerun_button = QPushButton("Rerun failed simulations")
|
|
268
274
|
self.rerun_button.setEnabled(False)
|
|
275
|
+
self.show_warnings_button = QPushButton()
|
|
276
|
+
self.set_show_warning_button_to_initial_state()
|
|
277
|
+
self.show_warnings_button.clicked.connect(self.toggle_fail_message_box)
|
|
269
278
|
|
|
270
279
|
size = 20
|
|
271
280
|
spin_movie = QMovie("img:loading.gif")
|
|
@@ -309,6 +318,7 @@ class RunDialog(QFrame):
|
|
|
309
318
|
button_layout = QVBoxLayout()
|
|
310
319
|
button_layout.addWidget(self.kill_button)
|
|
311
320
|
button_layout.addWidget(self.rerun_button)
|
|
321
|
+
button_layout.addWidget(self.show_warnings_button)
|
|
312
322
|
footer_layout.addLayout(button_layout)
|
|
313
323
|
|
|
314
324
|
footer_widget_container = QWidget()
|
|
@@ -478,6 +488,7 @@ class RunDialog(QFrame):
|
|
|
478
488
|
if failed:
|
|
479
489
|
self.update_total_progress(1.0, "Failed")
|
|
480
490
|
self._progress_widget.set_all_failed()
|
|
491
|
+
self.show_warnings_button.setText("Show errors")
|
|
481
492
|
else:
|
|
482
493
|
self.update_total_progress(1.0, "Experiment completed.")
|
|
483
494
|
|
|
@@ -495,6 +506,8 @@ class RunDialog(QFrame):
|
|
|
495
506
|
),
|
|
496
507
|
parent=self,
|
|
497
508
|
)
|
|
509
|
+
self.show_warnings_button.setEnabled(True)
|
|
510
|
+
self.show_warnings_button.setToolTip("")
|
|
498
511
|
self.fail_msg_box.show()
|
|
499
512
|
|
|
500
513
|
if self.post_simulation_warnings:
|
|
@@ -503,11 +516,23 @@ class RunDialog(QFrame):
|
|
|
503
516
|
f"{len(self.post_simulation_warnings)} PostSimulationWarnings"
|
|
504
517
|
)
|
|
505
518
|
|
|
519
|
+
def set_show_warning_button_to_initial_state(self) -> None:
|
|
520
|
+
self.show_warnings_button.setEnabled(False)
|
|
521
|
+
self.show_warnings_button.setText("Show warnings")
|
|
522
|
+
self.show_warnings_button.setToolTip("No warnings to show")
|
|
523
|
+
|
|
524
|
+
def toggle_fail_message_box(self) -> None:
|
|
525
|
+
if self.fail_msg_box is None:
|
|
526
|
+
return
|
|
527
|
+
self.fail_msg_box.setVisible(not self.fail_msg_box.isVisible())
|
|
528
|
+
|
|
506
529
|
@Slot()
|
|
507
530
|
def _on_ticker(self) -> None:
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
531
|
+
if self._start_time:
|
|
532
|
+
humanized_runtime = humanize.precisedelta(
|
|
533
|
+
datetime.now() - self._start_time, minimum_unit="seconds", format="%d"
|
|
534
|
+
)
|
|
535
|
+
self.running_time.setText(f"Running time:\n{humanized_runtime}")
|
|
511
536
|
|
|
512
537
|
maximum_memory_usage = self._snapshot_model.root.max_memory_usage
|
|
513
538
|
|
|
@@ -524,11 +549,16 @@ class RunDialog(QFrame):
|
|
|
524
549
|
def _on_event(self, event: object) -> None:
|
|
525
550
|
model = self._snapshot_model
|
|
526
551
|
match event:
|
|
552
|
+
case StartEvent():
|
|
553
|
+
self._start_time = event.timestamp
|
|
527
554
|
case EndEvent(failed=failed, msg=msg):
|
|
528
555
|
self.simulation_done.emit(failed, msg)
|
|
529
556
|
self._ticker.stop()
|
|
530
557
|
case WarningEvent(msg=msg):
|
|
531
558
|
self.post_simulation_warnings.append(msg)
|
|
559
|
+
case EnsembleEvaluationWarning(warning_message=msg):
|
|
560
|
+
self._show_warning(msg)
|
|
561
|
+
|
|
532
562
|
case FullSnapshotEvent(
|
|
533
563
|
status_count=status_count, realization_count=realization_count
|
|
534
564
|
):
|
|
@@ -634,25 +664,22 @@ class RunDialog(QFrame):
|
|
|
634
664
|
self.post_simulation_warnings.clear()
|
|
635
665
|
self._is_rerunning_failed_realizations = True
|
|
636
666
|
self.rerun_failed_realizations_experiment.emit()
|
|
667
|
+
self.set_show_warning_button_to_initial_state()
|
|
637
668
|
|
|
638
|
-
|
|
639
|
-
match queue_system:
|
|
640
|
-
case QueueSystem.LSF:
|
|
641
|
-
formatted_queue_system = "LSF"
|
|
642
|
-
case QueueSystem.LOCAL:
|
|
643
|
-
formatted_queue_system = "Local"
|
|
644
|
-
case QueueSystem.TORQUE:
|
|
645
|
-
formatted_queue_system = "Torque/OpenPBS"
|
|
646
|
-
case QueueSystem.SLURM:
|
|
647
|
-
formatted_queue_system = "Slurm"
|
|
648
|
-
case default:
|
|
649
|
-
assert_never(default)
|
|
650
|
-
self.queue_system.setText(f"Queue system:\n{formatted_queue_system}")
|
|
651
|
-
|
|
669
|
+
@override
|
|
652
670
|
def hideEvent(self, event: QHideEvent | None) -> None:
|
|
653
671
|
for file_dialog in self.findChildren(FileDialog):
|
|
654
672
|
file_dialog.close()
|
|
655
673
|
|
|
674
|
+
def _show_warning(self, msg: str) -> None:
|
|
675
|
+
msg_box = QMessageBox(self)
|
|
676
|
+
msg_box.setObjectName("EnsembleEvaluationWarningBox")
|
|
677
|
+
msg_box.setIcon(QMessageBox.Icon.Warning)
|
|
678
|
+
msg_box.setWindowTitle("Ensemble Evaluation Warning")
|
|
679
|
+
msg_box.setText(msg)
|
|
680
|
+
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
|
681
|
+
msg_box.show()
|
|
682
|
+
|
|
656
683
|
|
|
657
684
|
# Cannot use a non-static method here as
|
|
658
685
|
# it is called when the object is destroyed
|
|
@@ -2,14 +2,15 @@ from dataclasses import dataclass
|
|
|
2
2
|
|
|
3
3
|
from PyQt6.QtCore import Qt
|
|
4
4
|
from PyQt6.QtWidgets import QFormLayout, QLabel
|
|
5
|
+
from typing_extensions import override
|
|
5
6
|
|
|
7
|
+
from ert.config import AnalysisConfig, ParameterConfig
|
|
6
8
|
from ert.gui.ertnotifier import ErtNotifier
|
|
7
9
|
from ert.gui.ertwidgets import CopyableLabel
|
|
8
10
|
from ert.mode_definitions import TEST_RUN_MODE
|
|
9
11
|
from ert.run_models import SingleTestRun
|
|
10
12
|
|
|
11
|
-
from
|
|
12
|
-
from ..ertwidgets.parameterviewer import get_parameters_button
|
|
13
|
+
from ..ertwidgets import get_parameters_button
|
|
13
14
|
from ._design_matrix_panel import DesignMatrixPanel
|
|
14
15
|
from .experiment_config_panel import ExperimentConfigPanel
|
|
15
16
|
|
|
@@ -54,9 +55,11 @@ class SingleTestRunPanel(ExperimentConfigPanel):
|
|
|
54
55
|
merged_parameters
|
|
55
56
|
)
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
if merged_parameters:
|
|
59
|
+
layout.addRow("Parameters", get_parameters_button(merged_parameters, self))
|
|
58
60
|
|
|
59
61
|
self.setLayout(layout)
|
|
60
62
|
|
|
63
|
+
@override
|
|
61
64
|
def get_experiment_arguments(self) -> Arguments:
|
|
62
65
|
return Arguments(TEST_RUN_MODE, "ensemble", "single_test_run")
|
|
@@ -8,6 +8,7 @@ from PyQt6.QtWidgets import (
|
|
|
8
8
|
QProgressBar,
|
|
9
9
|
QVBoxLayout,
|
|
10
10
|
)
|
|
11
|
+
from typing_extensions import override
|
|
11
12
|
|
|
12
13
|
from ert.ensemble_evaluator.state import ENSEMBLE_STATE_FAILED, REAL_STATE_TO_COLOR
|
|
13
14
|
|
|
@@ -107,5 +108,6 @@ class ProgressWidget(QFrame):
|
|
|
107
108
|
self.stop_waiting_progress_bar()
|
|
108
109
|
self.repaint_components()
|
|
109
110
|
|
|
111
|
+
@override
|
|
110
112
|
def resizeEvent(self, a0: QResizeEvent | None) -> None:
|
|
111
113
|
self.repaint_components()
|
|
@@ -22,6 +22,7 @@ from PyQt6.QtWidgets import (
|
|
|
22
22
|
QVBoxLayout,
|
|
23
23
|
QWidget,
|
|
24
24
|
)
|
|
25
|
+
from typing_extensions import override
|
|
25
26
|
|
|
26
27
|
from ert.gui.model.real_list import RealListModel
|
|
27
28
|
from ert.gui.model.snapshot import (
|
|
@@ -105,6 +106,7 @@ class RealizationDelegate(QStyledItemDelegate):
|
|
|
105
106
|
self._color_lightgray = QColor("LightGray").lighter(120)
|
|
106
107
|
self._pen_black = QPen(self._color_black, 2, Qt.PenStyle.SolidLine)
|
|
107
108
|
|
|
109
|
+
@override
|
|
108
110
|
def paint(
|
|
109
111
|
self, painter: QPainter | None, option: QStyleOptionViewItem, index: QModelIndex
|
|
110
112
|
) -> None:
|
|
@@ -158,10 +160,12 @@ class RealizationDelegate(QStyledItemDelegate):
|
|
|
158
160
|
|
|
159
161
|
painter.restore()
|
|
160
162
|
|
|
163
|
+
@override
|
|
161
164
|
def sizeHint(self, option: QStyleOptionViewItem, index: QModelIndex) -> QSize:
|
|
162
165
|
return self._size
|
|
163
166
|
|
|
164
|
-
|
|
167
|
+
@override
|
|
168
|
+
def eventFilter(self, object: QObject | None, event: QEvent | None) -> bool:
|
|
165
169
|
if isinstance(event, QHelpEvent) and event.type() == QEvent.Type.ToolTip:
|
|
166
170
|
mouse_pos = event.pos() + self.adjustment_point_for_job_rect_margin
|
|
167
171
|
parent: RealizationWidget = cast(RealizationWidget, self.parent())
|
|
@@ -25,6 +25,7 @@ from PyQt6.QtWidgets import (
|
|
|
25
25
|
QVBoxLayout,
|
|
26
26
|
QWidget,
|
|
27
27
|
)
|
|
28
|
+
from typing_extensions import override
|
|
28
29
|
|
|
29
30
|
from ert.analysis.event import DataSection
|
|
30
31
|
from ert.ensemble_evaluator import state
|
|
@@ -56,6 +57,7 @@ class UpdateLogTable(QTableWidget):
|
|
|
56
57
|
for j, val in enumerate(row):
|
|
57
58
|
self.setItem(i, j, QTableWidgetItem(str(val)))
|
|
58
59
|
|
|
60
|
+
@override
|
|
59
61
|
def keyPressEvent(self, e: QKeyEvent | None) -> None:
|
|
60
62
|
if e is not None and e.matches(QKeySequence.StandardKey.Copy):
|
|
61
63
|
stream = ""
|
ert/gui/summarypanel.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import logging
|
|
3
4
|
from typing import TYPE_CHECKING, Any
|
|
4
5
|
|
|
5
6
|
from PyQt6.QtCore import Qt
|
|
@@ -13,11 +14,13 @@ from PyQt6.QtWidgets import (
|
|
|
13
14
|
QWidget,
|
|
14
15
|
)
|
|
15
16
|
|
|
16
|
-
from ert.gui.ertwidgets
|
|
17
|
+
from ert.gui.ertwidgets import ErtSummary
|
|
17
18
|
|
|
18
19
|
if TYPE_CHECKING:
|
|
19
20
|
from ert.config import ErtConfig
|
|
20
21
|
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
21
24
|
|
|
22
25
|
class SummaryTemplate:
|
|
23
26
|
def __init__(self, title: str) -> None:
|
|
@@ -123,6 +126,22 @@ class SummaryPanel(QFrame):
|
|
|
123
126
|
|
|
124
127
|
self._layout.addLayout(layout)
|
|
125
128
|
|
|
129
|
+
def log_summary(self, run_model: str, num_realizations: int) -> None:
|
|
130
|
+
summary = ErtSummary(self.config)
|
|
131
|
+
|
|
132
|
+
observations = summary.getObservations()
|
|
133
|
+
observations_count = sum(e["count"] for e in observations)
|
|
134
|
+
|
|
135
|
+
_, parameter_count = summary.get_parameters()
|
|
136
|
+
|
|
137
|
+
logger.info(
|
|
138
|
+
f"Experiment summary:\n"
|
|
139
|
+
f"Runmodel: {run_model}\n"
|
|
140
|
+
f"Realizations: {num_realizations}\n"
|
|
141
|
+
f"Parameters: {parameter_count}\n"
|
|
142
|
+
f"Observations: {observations_count}"
|
|
143
|
+
)
|
|
144
|
+
|
|
126
145
|
@staticmethod
|
|
127
146
|
def _runlength_encode_list(strings: list[str]) -> list[tuple[str, int]]:
|
|
128
147
|
"""Runlength encode a list of strings.
|