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
|
@@ -7,6 +7,7 @@ from PyQt6.QtCore import pyqtSignal as Signal
|
|
|
7
7
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
8
8
|
from PyQt6.QtGui import QCloseEvent
|
|
9
9
|
from PyQt6.QtWidgets import QDialog, QPlainTextEdit, QVBoxLayout
|
|
10
|
+
from typing_extensions import override
|
|
10
11
|
|
|
11
12
|
from ert.gui.tools.search_bar import SearchBar
|
|
12
13
|
|
|
@@ -32,10 +33,7 @@ class _GUILogHandler(logging.Handler):
|
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
class GUILogHandler(_Signaler):
|
|
35
|
-
"""
|
|
36
|
-
Log handler which will emit a qt signal every time a
|
|
37
|
-
log is emitted
|
|
38
|
-
"""
|
|
36
|
+
"""Log handler which will emit a qt signal every time a log is emitted."""
|
|
39
37
|
|
|
40
38
|
def __init__(self) -> None:
|
|
41
39
|
super().__init__()
|
|
@@ -78,6 +76,7 @@ class EventViewerPanel(QDialog):
|
|
|
78
76
|
def val_changed(self, value: str) -> None:
|
|
79
77
|
self.text_box.appendPlainText(value)
|
|
80
78
|
|
|
79
|
+
@override
|
|
81
80
|
def closeEvent(self, event: QCloseEvent | None) -> None:
|
|
82
81
|
logger.info("Gui utility: EventViewer tool was used")
|
|
83
82
|
super().closeEvent(event)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from PyQt6.QtCore import QObject
|
|
2
2
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
3
3
|
from PyQt6.QtGui import QIcon
|
|
4
|
+
from typing_extensions import override
|
|
4
5
|
|
|
5
6
|
from ert.gui.tools import Tool
|
|
6
7
|
|
|
@@ -21,6 +22,7 @@ class EventViewerTool(Tool, QObject):
|
|
|
21
22
|
self.logging_window.setWindowTitle(f"Event viewer: {config_filename}")
|
|
22
23
|
self.setEnabled(True)
|
|
23
24
|
|
|
25
|
+
@override
|
|
24
26
|
def trigger(self) -> None:
|
|
25
27
|
self.logging_window.show()
|
|
26
28
|
|
|
@@ -13,10 +13,10 @@ from ert.gui.ertwidgets import (
|
|
|
13
13
|
EnsembleSelector,
|
|
14
14
|
QApplication,
|
|
15
15
|
StringBox,
|
|
16
|
+
Suggestor,
|
|
16
17
|
TextBox,
|
|
17
18
|
TextModel,
|
|
18
19
|
)
|
|
19
|
-
from ert.gui.suggestor import Suggestor
|
|
20
20
|
from ert.run_models.run_model import captured_logs
|
|
21
21
|
from ert.storage.local_ensemble import load_parameters_and_responses_from_runpath
|
|
22
22
|
from ert.validation import RangeStringArgument, StringDefinition
|
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
4
|
from PyQt6.QtGui import QIcon
|
|
5
|
+
from typing_extensions import override
|
|
5
6
|
|
|
6
7
|
from ert.config import ErtConfig
|
|
7
8
|
from ert.gui.ertnotifier import ErtNotifier
|
|
@@ -23,6 +24,7 @@ class LoadResultsTool(Tool):
|
|
|
23
24
|
self._notifier = notifier
|
|
24
25
|
self._config = config
|
|
25
26
|
|
|
27
|
+
@override
|
|
26
28
|
def trigger(self) -> None:
|
|
27
29
|
if self._import_widget is None:
|
|
28
30
|
self._import_widget = LoadResultsPanel(self._config, self._notifier)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
5
|
+
import polars as pl
|
|
6
|
+
from PyQt6.QtCore import (
|
|
7
|
+
Qt,
|
|
8
|
+
)
|
|
9
|
+
from PyQt6.QtCore import (
|
|
10
|
+
pyqtSlot as Slot,
|
|
11
|
+
)
|
|
12
|
+
from PyQt6.QtGui import QColor, QPalette
|
|
13
|
+
from PyQt6.QtWidgets import (
|
|
14
|
+
QDialog,
|
|
15
|
+
QDialogButtonBox,
|
|
16
|
+
QFileDialog,
|
|
17
|
+
QHBoxLayout,
|
|
18
|
+
QLineEdit,
|
|
19
|
+
QPushButton,
|
|
20
|
+
QTextEdit,
|
|
21
|
+
QVBoxLayout,
|
|
22
|
+
QWidget,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ExportDialog(QDialog):
|
|
27
|
+
"""Base dialog for exporting ensemble-related data to files."""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
export_data: pl.DataFrame,
|
|
32
|
+
window_title: str = "Export data",
|
|
33
|
+
parent: QWidget | None = None,
|
|
34
|
+
) -> None:
|
|
35
|
+
QDialog.__init__(self, parent)
|
|
36
|
+
self._export_data = export_data
|
|
37
|
+
self.setWindowTitle(window_title)
|
|
38
|
+
|
|
39
|
+
self.setWindowFlags(Qt.WindowType.Dialog)
|
|
40
|
+
self.setModal(True)
|
|
41
|
+
self.setMinimumWidth(450)
|
|
42
|
+
self.setMinimumHeight(200)
|
|
43
|
+
|
|
44
|
+
main_layout = QVBoxLayout()
|
|
45
|
+
|
|
46
|
+
file_layout = QHBoxLayout()
|
|
47
|
+
self._file_path_edit = QLineEdit(self)
|
|
48
|
+
self._file_path_edit.setPlaceholderText("Select output file...")
|
|
49
|
+
self._file_path_edit.textChanged.connect(self.validate_file)
|
|
50
|
+
browse_button = QPushButton("Browse...", self)
|
|
51
|
+
browse_button.clicked.connect(self.browse_file)
|
|
52
|
+
file_layout.addWidget(self._file_path_edit)
|
|
53
|
+
file_layout.addWidget(browse_button)
|
|
54
|
+
main_layout.addLayout(file_layout)
|
|
55
|
+
|
|
56
|
+
self._export_text_area = QTextEdit(self)
|
|
57
|
+
self._export_text_area.setReadOnly(True)
|
|
58
|
+
self._export_text_area.setFixedHeight(100)
|
|
59
|
+
main_layout.addWidget(self._export_text_area)
|
|
60
|
+
|
|
61
|
+
button_box = QDialogButtonBox(self)
|
|
62
|
+
button_box.setStandardButtons(QDialogButtonBox.StandardButton.Cancel)
|
|
63
|
+
button_box.rejected.connect(self.cancel)
|
|
64
|
+
|
|
65
|
+
self._export_button = cast(
|
|
66
|
+
QPushButton,
|
|
67
|
+
button_box.addButton("Export", QDialogButtonBox.ButtonRole.AcceptRole),
|
|
68
|
+
)
|
|
69
|
+
self._export_button.clicked.connect(self.export)
|
|
70
|
+
self._export_button.setEnabled(False) # Initially disabled
|
|
71
|
+
main_layout.addWidget(button_box)
|
|
72
|
+
|
|
73
|
+
self.setLayout(main_layout)
|
|
74
|
+
|
|
75
|
+
@Slot()
|
|
76
|
+
def export(self) -> None:
|
|
77
|
+
self._export_text_area.insertPlainText("Exporting...\n")
|
|
78
|
+
try:
|
|
79
|
+
output_file: str = self._file_path_edit.text().strip()
|
|
80
|
+
self._export_button.setEnabled(False)
|
|
81
|
+
self._export_data.write_csv(output_file, float_precision=6)
|
|
82
|
+
self._export_text_area.insertPlainText(f"Data exported to: {output_file}\n")
|
|
83
|
+
except Exception as e:
|
|
84
|
+
self._export_text_area.insertHtml(
|
|
85
|
+
f"<span style='color: red;'>Could not export data: {e!s}</span><br>"
|
|
86
|
+
)
|
|
87
|
+
finally:
|
|
88
|
+
self._export_button.setEnabled(True)
|
|
89
|
+
|
|
90
|
+
@Slot()
|
|
91
|
+
def cancel(self) -> None:
|
|
92
|
+
self.reject()
|
|
93
|
+
|
|
94
|
+
@Slot()
|
|
95
|
+
def validate_file(self) -> None:
|
|
96
|
+
"""Validation to check if the file path is not empty or invalid."""
|
|
97
|
+
|
|
98
|
+
def _set_invalid(tooltip_text: str = "Invalid file path") -> None:
|
|
99
|
+
palette = self._file_path_edit.palette()
|
|
100
|
+
palette.setColor(QPalette.ColorRole.Text, QColor("red"))
|
|
101
|
+
self._file_path_edit.setPalette(palette)
|
|
102
|
+
self._file_path_edit.setToolTip(tooltip_text)
|
|
103
|
+
self._export_button.setToolTip(tooltip_text)
|
|
104
|
+
self._export_button.setEnabled(False)
|
|
105
|
+
|
|
106
|
+
def _set_valid() -> None:
|
|
107
|
+
palette = self._file_path_edit.palette()
|
|
108
|
+
palette.setColor(QPalette.ColorRole.Text, QColor("black"))
|
|
109
|
+
self._file_path_edit.setPalette(palette)
|
|
110
|
+
self._file_path_edit.setToolTip("")
|
|
111
|
+
self._export_button.setToolTip("")
|
|
112
|
+
self._export_button.setEnabled(True)
|
|
113
|
+
|
|
114
|
+
path = Path(self._file_path_edit.text().strip())
|
|
115
|
+
if str(path) in {"", "."}:
|
|
116
|
+
_set_invalid(tooltip_text="No filename provided")
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
if path.is_dir():
|
|
120
|
+
_set_invalid(tooltip_text=f"'{path!s}' is an existing directory.")
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
with contextlib.suppress(Exception):
|
|
124
|
+
if path.parent.is_dir():
|
|
125
|
+
_set_valid()
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
_set_invalid()
|
|
129
|
+
|
|
130
|
+
@Slot()
|
|
131
|
+
def browse_file(self) -> None:
|
|
132
|
+
file_path, _ = QFileDialog.getSaveFileName(
|
|
133
|
+
self, "Select Output File", "", "All Files (*)"
|
|
134
|
+
)
|
|
135
|
+
if file_path:
|
|
136
|
+
self._file_path_edit.setText(file_path)
|
|
@@ -12,6 +12,7 @@ from PyQt6.QtWidgets import (
|
|
|
12
12
|
QVBoxLayout,
|
|
13
13
|
QWidget,
|
|
14
14
|
)
|
|
15
|
+
from typing_extensions import override
|
|
15
16
|
|
|
16
17
|
from ert.gui.ertwidgets import (
|
|
17
18
|
CheckList,
|
|
@@ -153,6 +154,7 @@ class ManageExperimentsPanel(QTabWidget):
|
|
|
153
154
|
|
|
154
155
|
self.addTab(panel, "Initialize from scratch")
|
|
155
156
|
|
|
157
|
+
@override
|
|
156
158
|
def eventFilter(self, a0: QObject | None, a1: QEvent | None) -> bool:
|
|
157
159
|
if a1 is not None and a1.type() == QEvent.Type.Close:
|
|
158
160
|
self.notifier.emitErtChange()
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import json
|
|
2
3
|
from enum import IntEnum
|
|
3
4
|
|
|
@@ -6,13 +7,18 @@ import seaborn as sns
|
|
|
6
7
|
import yaml
|
|
7
8
|
from matplotlib.backends.backend_qt5agg import FigureCanvas # type: ignore
|
|
8
9
|
from matplotlib.figure import Figure
|
|
10
|
+
from polars import DataFrame
|
|
9
11
|
from PyQt6.QtCore import Qt
|
|
10
12
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
11
13
|
from PyQt6.QtWidgets import (
|
|
14
|
+
QAbstractItemView,
|
|
12
15
|
QFrame,
|
|
13
16
|
QHBoxLayout,
|
|
14
17
|
QLabel,
|
|
18
|
+
QPushButton,
|
|
15
19
|
QStackedLayout,
|
|
20
|
+
QTableWidget,
|
|
21
|
+
QTableWidgetItem,
|
|
16
22
|
QTabWidget,
|
|
17
23
|
QTextEdit,
|
|
18
24
|
QTreeWidget,
|
|
@@ -21,8 +27,11 @@ from PyQt6.QtWidgets import (
|
|
|
21
27
|
QWidget,
|
|
22
28
|
)
|
|
23
29
|
|
|
30
|
+
from ert import LibresFacade
|
|
24
31
|
from ert.storage import Ensemble, Experiment, RealizationStorageState
|
|
25
32
|
|
|
33
|
+
from .export_dialog import ExportDialog
|
|
34
|
+
|
|
26
35
|
|
|
27
36
|
class _WidgetType(IntEnum):
|
|
28
37
|
EMPTY_WIDGET = 0
|
|
@@ -42,6 +51,8 @@ class _EnsembleWidgetTabs(IntEnum):
|
|
|
42
51
|
ENSEMBLE_TAB = 0
|
|
43
52
|
STATE_TAB = 1
|
|
44
53
|
OBSERVATIONS_TAB = 2
|
|
54
|
+
PARAMETERS_TAB = 3
|
|
55
|
+
MISFIT_TAB = 4
|
|
45
56
|
|
|
46
57
|
|
|
47
58
|
class _ExperimentWidget(QWidget):
|
|
@@ -126,12 +137,15 @@ class _EnsembleWidget(QWidget):
|
|
|
126
137
|
|
|
127
138
|
info_frame.setLayout(info_layout)
|
|
128
139
|
|
|
140
|
+
state_frame = QFrame()
|
|
141
|
+
state_layout = QHBoxLayout()
|
|
129
142
|
self._state_text_edit = QTextEdit()
|
|
130
143
|
self._state_text_edit.setReadOnly(True)
|
|
131
144
|
self._state_text_edit.setObjectName("ensemble_state_text")
|
|
145
|
+
state_layout.addWidget(self._state_text_edit)
|
|
146
|
+
state_frame.setLayout(state_layout)
|
|
132
147
|
|
|
133
148
|
observations_frame = QFrame()
|
|
134
|
-
|
|
135
149
|
self._observations_tree_widget = QTreeWidget(self)
|
|
136
150
|
self._observations_tree_widget.currentItemChanged.connect(
|
|
137
151
|
self._currentItemChanged
|
|
@@ -151,15 +165,38 @@ class _EnsembleWidget(QWidget):
|
|
|
151
165
|
observations_layout.addWidget(self._canvas)
|
|
152
166
|
observations_frame.setLayout(observations_layout)
|
|
153
167
|
|
|
168
|
+
self._parameters_table = QTableWidget()
|
|
169
|
+
self._parameters_table.setEditTriggers(
|
|
170
|
+
QAbstractItemView.EditTrigger.NoEditTriggers
|
|
171
|
+
)
|
|
172
|
+
self._export_params_button = QPushButton("Export...")
|
|
173
|
+
self._export_params_button.clicked.connect(self.onClickExportParameters)
|
|
174
|
+
|
|
175
|
+
parameters_frame = self.create_export_frame(
|
|
176
|
+
self._parameters_table, self._export_params_button
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
self._misfit_table = QTableWidget()
|
|
180
|
+
self._export_misfit_button = QPushButton("Export...")
|
|
181
|
+
self._export_misfit_button.clicked.connect(self.onClickExportMisfit)
|
|
182
|
+
|
|
183
|
+
misfit_frame = self.create_export_frame(
|
|
184
|
+
self._misfit_table, self._export_misfit_button
|
|
185
|
+
)
|
|
186
|
+
|
|
154
187
|
self._tab_widget = QTabWidget()
|
|
155
188
|
self._tab_widget.insertTab(
|
|
156
189
|
_EnsembleWidgetTabs.ENSEMBLE_TAB, info_frame, "Ensemble"
|
|
157
190
|
)
|
|
191
|
+
self._tab_widget.insertTab(_EnsembleWidgetTabs.STATE_TAB, state_frame, "State")
|
|
158
192
|
self._tab_widget.insertTab(
|
|
159
|
-
_EnsembleWidgetTabs.
|
|
193
|
+
_EnsembleWidgetTabs.OBSERVATIONS_TAB, observations_frame, "Observations"
|
|
160
194
|
)
|
|
161
195
|
self._tab_widget.insertTab(
|
|
162
|
-
_EnsembleWidgetTabs.
|
|
196
|
+
_EnsembleWidgetTabs.PARAMETERS_TAB, parameters_frame, "Parameters"
|
|
197
|
+
)
|
|
198
|
+
self._tab_widget.insertTab(
|
|
199
|
+
_EnsembleWidgetTabs.MISFIT_TAB, misfit_frame, "Misfit"
|
|
163
200
|
)
|
|
164
201
|
self._tab_widget.currentChanged.connect(self._currentTabChanged)
|
|
165
202
|
|
|
@@ -168,6 +205,17 @@ class _EnsembleWidget(QWidget):
|
|
|
168
205
|
|
|
169
206
|
self.setLayout(layout)
|
|
170
207
|
|
|
208
|
+
def create_export_frame(self, table: QTableWidget, button: QPushButton) -> QFrame:
|
|
209
|
+
export_frame = QFrame()
|
|
210
|
+
export_layout = QVBoxLayout()
|
|
211
|
+
vertical_header = table.verticalHeader()
|
|
212
|
+
assert vertical_header is not None
|
|
213
|
+
vertical_header.setVisible(False)
|
|
214
|
+
export_layout.addWidget(table)
|
|
215
|
+
export_layout.addWidget(button)
|
|
216
|
+
export_frame.setLayout(export_layout)
|
|
217
|
+
return export_frame
|
|
218
|
+
|
|
171
219
|
def _currentItemChanged(
|
|
172
220
|
self, selected: QTreeWidgetItem, _: QTreeWidgetItem
|
|
173
221
|
) -> None:
|
|
@@ -189,9 +237,9 @@ class _EnsembleWidget(QWidget):
|
|
|
189
237
|
|
|
190
238
|
response_type, obs_for_type = next(
|
|
191
239
|
(
|
|
192
|
-
(response_type,
|
|
193
|
-
for response_type,
|
|
194
|
-
if observation_key in
|
|
240
|
+
(response_type, df)
|
|
241
|
+
for response_type, df in observations_dict.items()
|
|
242
|
+
if observation_key in df["observation_key"]
|
|
195
243
|
),
|
|
196
244
|
(None, None),
|
|
197
245
|
)
|
|
@@ -356,12 +404,53 @@ class _EnsembleWidget(QWidget):
|
|
|
356
404
|
0, Qt.SortOrder.AscendingOrder
|
|
357
405
|
)
|
|
358
406
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
407
|
+
for i in range(self._observations_tree_widget.topLevelItemCount()):
|
|
408
|
+
item = self._observations_tree_widget.topLevelItem(i)
|
|
409
|
+
assert item is not None
|
|
410
|
+
if item.childCount() > 0:
|
|
411
|
+
self._observations_tree_widget.setCurrentItem(item.child(0))
|
|
412
|
+
break
|
|
413
|
+
|
|
414
|
+
elif index in {
|
|
415
|
+
_EnsembleWidgetTabs.PARAMETERS_TAB,
|
|
416
|
+
_EnsembleWidgetTabs.MISFIT_TAB,
|
|
417
|
+
}:
|
|
418
|
+
assert self._ensemble is not None
|
|
419
|
+
|
|
420
|
+
df: pl.DataFrame = pl.DataFrame()
|
|
421
|
+
with contextlib.suppress(Exception):
|
|
422
|
+
if index == _EnsembleWidgetTabs.PARAMETERS_TAB:
|
|
423
|
+
df = self._ensemble.load_scalar_keys(transformed=True)
|
|
424
|
+
else:
|
|
425
|
+
df = self.get_misfit_df()
|
|
426
|
+
|
|
427
|
+
table = (
|
|
428
|
+
self._parameters_table
|
|
429
|
+
if index == _EnsembleWidgetTabs.PARAMETERS_TAB
|
|
430
|
+
else self._misfit_table
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
table.setUpdatesEnabled(False)
|
|
434
|
+
table.setSortingEnabled(False)
|
|
435
|
+
table.setRowCount(df.height)
|
|
436
|
+
table.setColumnCount(df.width)
|
|
437
|
+
table.setHorizontalHeaderLabels(df.columns)
|
|
438
|
+
|
|
439
|
+
rows = df.rows()
|
|
440
|
+
for r, row in enumerate(rows):
|
|
441
|
+
for c, v in enumerate(row):
|
|
442
|
+
table.setItem(r, c, QTableWidgetItem("" if v is None else str(v)))
|
|
443
|
+
|
|
444
|
+
table.resizeColumnsToContents()
|
|
445
|
+
table.setUpdatesEnabled(True)
|
|
446
|
+
|
|
447
|
+
def get_misfit_df(self) -> DataFrame:
|
|
448
|
+
assert self._ensemble is not None
|
|
449
|
+
df = LibresFacade.load_all_misfit_data(self._ensemble)
|
|
450
|
+
realization_column = pl.Series(df.index)
|
|
451
|
+
df = pl.from_pandas(df)
|
|
452
|
+
df.insert_column(0, realization_column)
|
|
453
|
+
return df
|
|
365
454
|
|
|
366
455
|
@Slot(Ensemble)
|
|
367
456
|
def setEnsemble(self, ensemble: Ensemble) -> None:
|
|
@@ -372,6 +461,22 @@ class _EnsembleWidget(QWidget):
|
|
|
372
461
|
|
|
373
462
|
self._tab_widget.setCurrentIndex(0)
|
|
374
463
|
|
|
464
|
+
@Slot()
|
|
465
|
+
def onClickExportMisfit(self) -> None:
|
|
466
|
+
assert self._ensemble is not None
|
|
467
|
+
misfit_df = self.get_misfit_df()
|
|
468
|
+
export_dialog = ExportDialog(misfit_df, "Export misfit", parent=self)
|
|
469
|
+
export_dialog.show()
|
|
470
|
+
|
|
471
|
+
@Slot()
|
|
472
|
+
def onClickExportParameters(self) -> None:
|
|
473
|
+
assert self._ensemble is not None
|
|
474
|
+
parameters_df = self._ensemble.load_scalar_keys(transformed=True)
|
|
475
|
+
export_dialog = ExportDialog(
|
|
476
|
+
parameters_df, window_title="Export parameters", parent=self
|
|
477
|
+
)
|
|
478
|
+
export_dialog.show()
|
|
479
|
+
|
|
375
480
|
|
|
376
481
|
class _RealizationWidget(QWidget):
|
|
377
482
|
def __init__(self) -> None:
|
|
@@ -418,14 +523,14 @@ class _RealizationWidget(QWidget):
|
|
|
418
523
|
)
|
|
419
524
|
|
|
420
525
|
html = "<table>"
|
|
421
|
-
for name,
|
|
422
|
-
html += f"<tr><td>{name} - {
|
|
526
|
+
for name, response_state in ensemble.get_response_state(realization).items():
|
|
527
|
+
html += f"<tr><td>{name} - {response_state.name}</td></tr>"
|
|
423
528
|
html += "</table>"
|
|
424
529
|
self._response_text_edit.setHtml(html)
|
|
425
530
|
|
|
426
531
|
html = "<table>"
|
|
427
|
-
for name,
|
|
428
|
-
html += f"<tr><td>{name} - {
|
|
532
|
+
for name, param_state in ensemble.get_parameter_state(realization).items():
|
|
533
|
+
html += f"<tr><td>{name} - {param_state.name}</td></tr>"
|
|
429
534
|
html += "</table>"
|
|
430
535
|
self._parameter_text_edit.setHtml(html)
|
|
431
536
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections.abc import Callable
|
|
3
|
+
from typing import cast
|
|
3
4
|
|
|
4
5
|
from PyQt6.QtCore import (
|
|
5
6
|
QAbstractItemModel,
|
|
@@ -23,8 +24,7 @@ from PyQt6.QtWidgets import (
|
|
|
23
24
|
|
|
24
25
|
from ert.config import ErrorInfo, ErtConfig
|
|
25
26
|
from ert.gui.ertnotifier import ErtNotifier
|
|
26
|
-
from ert.gui.ertwidgets
|
|
27
|
-
from ert.gui.suggestor import Suggestor
|
|
27
|
+
from ert.gui.ertwidgets import CreateExperimentDialog, Suggestor
|
|
28
28
|
from ert.storage import Ensemble, Experiment
|
|
29
29
|
|
|
30
30
|
from .storage_model import (
|
|
@@ -149,7 +149,8 @@ class StorageWidget(QWidget):
|
|
|
149
149
|
self.setLayout(layout)
|
|
150
150
|
|
|
151
151
|
def _currentChanged(self, selected: QModelIndex, previous: QModelIndex) -> None:
|
|
152
|
-
|
|
152
|
+
model = cast(_SortingProxyModel, self._tree_view.model())
|
|
153
|
+
idx = model.mapToSource(selected)
|
|
153
154
|
cls = idx.internalPointer()
|
|
154
155
|
|
|
155
156
|
if isinstance(cls, EnsembleModel):
|
|
@@ -3,14 +3,15 @@ from PyQt6.QtCore import pyqtSignal as Signal
|
|
|
3
3
|
from PyQt6.QtCore import pyqtSlot as Slot
|
|
4
4
|
from PyQt6.QtGui import QColor, QMouseEvent, QPainter, QPaintEvent
|
|
5
5
|
from PyQt6.QtWidgets import QColorDialog, QFrame
|
|
6
|
+
from typing_extensions import override
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class ColorBox(QFrame):
|
|
10
|
+
"""A widget that shows a colored box"""
|
|
11
|
+
|
|
9
12
|
colorChanged = Signal(QColor)
|
|
10
13
|
mouseRelease = Signal()
|
|
11
14
|
|
|
12
|
-
"""A widget that shows a colored box"""
|
|
13
|
-
|
|
14
15
|
def __init__(self, size: int = 15) -> None:
|
|
15
16
|
QFrame.__init__(self)
|
|
16
17
|
self.setFrameStyle(QFrame.Shape.Panel | QFrame.Shadow.Sunken)
|
|
@@ -49,6 +50,7 @@ class ColorBox(QFrame):
|
|
|
49
50
|
self._color = new_color
|
|
50
51
|
self.update()
|
|
51
52
|
|
|
53
|
+
@override
|
|
52
54
|
def paintEvent(self, a0: QPaintEvent | None) -> None:
|
|
53
55
|
"""Paints the box"""
|
|
54
56
|
painter = QPainter(self)
|
|
@@ -69,6 +71,7 @@ class ColorBox(QFrame):
|
|
|
69
71
|
|
|
70
72
|
QFrame.paintEvent(self, a0)
|
|
71
73
|
|
|
74
|
+
@override
|
|
72
75
|
def mouseReleaseEvent(self, a0: QMouseEvent | None) -> None:
|
|
73
76
|
if a0:
|
|
74
77
|
self.mouseRelease.emit()
|
|
@@ -20,6 +20,7 @@ from PyQt6.QtWidgets import (
|
|
|
20
20
|
QWidget,
|
|
21
21
|
QWidgetAction,
|
|
22
22
|
)
|
|
23
|
+
from typing_extensions import override
|
|
23
24
|
|
|
24
25
|
from ert.gui.tools.plot.plot_api import PlotApiKeyDefinition
|
|
25
26
|
from ert.gui.tools.plot.plottery import PlotConfig, PlotConfigFactory, PlotConfigHistory
|
|
@@ -296,6 +297,7 @@ class CustomizePlotDialog(QDialog):
|
|
|
296
297
|
def currentPlotKeyChanged(self, new_key: str | None) -> None:
|
|
297
298
|
self.current_key = new_key
|
|
298
299
|
|
|
300
|
+
@override
|
|
299
301
|
def keyPressEvent(self, a0: QKeyEvent | None) -> None:
|
|
300
302
|
# Hide when pressing Escape instead of QDialog.keyPressEvent(KeyEscape)
|
|
301
303
|
# which closes the dialog
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
|
+
from typing_extensions import override
|
|
4
|
+
|
|
3
5
|
from .customization_view import CustomizationView, WidgetProperty
|
|
4
6
|
|
|
5
7
|
if TYPE_CHECKING:
|
|
@@ -57,6 +59,7 @@ class DefaultCustomizationView(CustomizationView):
|
|
|
57
59
|
"observations", "Observations", "Toggle observations visibility."
|
|
58
60
|
)
|
|
59
61
|
|
|
62
|
+
@override
|
|
60
63
|
def applyCustomization(self, plot_config: "PlotConfig") -> None:
|
|
61
64
|
plot_config.setTitle(self.title)
|
|
62
65
|
|
|
@@ -68,6 +71,7 @@ class DefaultCustomizationView(CustomizationView):
|
|
|
68
71
|
plot_config.setHistoryEnabled(self.history)
|
|
69
72
|
plot_config.setObservationsEnabled(self.observations)
|
|
70
73
|
|
|
74
|
+
@override
|
|
71
75
|
def revertCustomization(self, plot_config: "PlotConfig") -> None:
|
|
72
76
|
if not plot_config.isUnnamed():
|
|
73
77
|
self.title = plot_config.title()
|
|
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, ClassVar, cast
|
|
|
6
6
|
|
|
7
7
|
from PyQt6.QtGui import QDoubleValidator, QIntValidator
|
|
8
8
|
from PyQt6.QtWidgets import QLabel, QLineEdit, QStackedWidget
|
|
9
|
+
from typing_extensions import override
|
|
9
10
|
|
|
10
11
|
from ert.gui.tools.plot.plottery import PlotContext, PlotLimits
|
|
11
12
|
from ert.gui.tools.plot.widgets import ClearableLineEdit, CustomDateEdit
|
|
@@ -249,8 +250,10 @@ class LimitsCustomizationView(CustomizationView):
|
|
|
249
250
|
self._limits_widget.switchInputOnX(x_axis_type)
|
|
250
251
|
self._limits_widget.switchInputOnY(y_axis_type)
|
|
251
252
|
|
|
253
|
+
@override
|
|
252
254
|
def revertCustomization(self, plot_config: PlotConfig) -> None:
|
|
253
255
|
self._limits_widget.limits = plot_config.limits
|
|
254
256
|
|
|
257
|
+
@override
|
|
255
258
|
def applyCustomization(self, plot_config: PlotConfig) -> None:
|
|
256
259
|
plot_config.limits = self._limits_widget.limits
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import TYPE_CHECKING, cast
|
|
4
4
|
|
|
5
5
|
from PyQt6.QtWidgets import QComboBox, QHBoxLayout
|
|
6
|
+
from typing_extensions import override
|
|
6
7
|
|
|
7
8
|
from .customization_view import CustomizationView, WidgetProperty
|
|
8
9
|
from .style_chooser import STYLESET_AREA, StyleChooser
|
|
@@ -132,6 +133,7 @@ class StatisticsCustomizationView(CustomizationView):
|
|
|
132
133
|
style.marker = marker_style
|
|
133
134
|
setattr(self, attribute_name, style)
|
|
134
135
|
|
|
136
|
+
@override
|
|
135
137
|
def applyCustomization(self, plot_config: PlotConfig) -> None:
|
|
136
138
|
plot_config.setStatisticsStyle("mean", self.mean_style)
|
|
137
139
|
plot_config.setStatisticsStyle("p50", self.p50_style)
|
|
@@ -143,6 +145,7 @@ class StatisticsCustomizationView(CustomizationView):
|
|
|
143
145
|
plot_config.setStandardDeviationFactor(self.std_dev_factor)
|
|
144
146
|
plot_config.setDistributionLineEnabled(self.distribution_lines)
|
|
145
147
|
|
|
148
|
+
@override
|
|
146
149
|
def revertCustomization(self, plot_config: PlotConfig) -> None:
|
|
147
150
|
self.mean_style = plot_config.getStatisticsStyle("mean")
|
|
148
151
|
self.p50_style = plot_config.getStatisticsStyle("p50")
|
|
@@ -8,6 +8,7 @@ from PyQt6.QtWidgets import (
|
|
|
8
8
|
QLayout,
|
|
9
9
|
QWidget,
|
|
10
10
|
)
|
|
11
|
+
from typing_extensions import override
|
|
11
12
|
|
|
12
13
|
from ert.gui.tools.plot.plottery import PlotStyle
|
|
13
14
|
|
|
@@ -182,6 +183,7 @@ class StyleChooser(QWidget):
|
|
|
182
183
|
self._style.width = thickness
|
|
183
184
|
self._style.size = size
|
|
184
185
|
|
|
186
|
+
@override
|
|
185
187
|
def setStyle(self, style: PlotStyle) -> None: # type: ignore
|
|
186
188
|
self._style.copyStyleFrom(style)
|
|
187
189
|
self._updateLineStyleAndMarker(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, cast
|
|
2
2
|
|
|
3
3
|
from PyQt6.QtWidgets import QHBoxLayout
|
|
4
|
+
from typing_extensions import override
|
|
4
5
|
|
|
5
6
|
from .color_chooser import ColorBox
|
|
6
7
|
from .customization_view import CustomizationView, WidgetProperty
|
|
@@ -91,6 +92,7 @@ class StyleCustomizationView(CustomizationView):
|
|
|
91
92
|
color_box = self._color_boxes[index]
|
|
92
93
|
color_box.color = color_tuple
|
|
93
94
|
|
|
95
|
+
@override
|
|
94
96
|
def applyCustomization(self, plot_config: "PlotConfig") -> None:
|
|
95
97
|
plot_config.setDefaultStyle(self.default_style)
|
|
96
98
|
plot_config.setHistoryStyle(self.history_style)
|
|
@@ -98,6 +100,7 @@ class StyleCustomizationView(CustomizationView):
|
|
|
98
100
|
plot_config.setObservationsColor(self.observs_color)
|
|
99
101
|
plot_config.setLineColorCycle(self.color_cycle)
|
|
100
102
|
|
|
103
|
+
@override
|
|
101
104
|
def revertCustomization(self, plot_config: "PlotConfig") -> None:
|
|
102
105
|
self.default_style = plot_config.defaultStyle()
|
|
103
106
|
self.history_style = plot_config.historyStyle()
|
|
@@ -9,6 +9,7 @@ from PyQt6.QtWidgets import (
|
|
|
9
9
|
QVBoxLayout,
|
|
10
10
|
QWidget,
|
|
11
11
|
)
|
|
12
|
+
from typing_extensions import override
|
|
12
13
|
|
|
13
14
|
from ert.gui.ertwidgets import SearchBox
|
|
14
15
|
|
|
@@ -29,6 +30,7 @@ class _LegendMarker(QWidget):
|
|
|
29
30
|
|
|
30
31
|
self.color = color
|
|
31
32
|
|
|
33
|
+
@override
|
|
32
34
|
def paintEvent(self, a0: QPaintEvent | None) -> None:
|
|
33
35
|
painter = QPainter(self)
|
|
34
36
|
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from PyQt6.QtCore import QModelIndex, QObject, QSortFilterProxyModel, Qt
|
|
6
|
+
from typing_extensions import override
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
8
9
|
from .data_type_keys_list_model import DataTypeKeysListModel
|
|
@@ -21,6 +22,7 @@ class DataTypeProxyModel(QSortFilterProxyModel):
|
|
|
21
22
|
self.setFilterCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
|
|
22
23
|
self.setSourceModel(model)
|
|
23
24
|
|
|
25
|
+
@override
|
|
24
26
|
def filterAcceptsRow(self, source_row: int, source_parent: QModelIndex) -> bool:
|
|
25
27
|
show = QSortFilterProxyModel.filterAcceptsRow(self, source_row, source_parent)
|
|
26
28
|
|
|
@@ -45,6 +47,7 @@ class DataTypeProxyModel(QSortFilterProxyModel):
|
|
|
45
47
|
|
|
46
48
|
return show
|
|
47
49
|
|
|
50
|
+
@override
|
|
48
51
|
def sourceModel(self) -> DataTypeKeysListModel:
|
|
49
52
|
return QSortFilterProxyModel.sourceModel(self) # type: ignore
|
|
50
53
|
|