Skip to content

Commit 321a50d

Browse files
authored
Unify convert and gather obs endpoints
Converter functionality is moved to an own module: observation_converters The module contains a dispatcher which calls the appropriate converter based on arguments given to the cli command. This will also simplify the functionality of BulkConfigConverter such that it no longer spins up an ert API but simply reads the observations from the ert config directly. This will match the behavior of existing history observation converter. We currently do not wish to expose the specific observation types to the public interface of ert.config, therefore there is a bunch of custom handling for the Observation types in the bulk config converter - as we are sure we are working with SummaryObservations and BreakthroughObservations. This could be revisited later, if we wish to expose these classes to the interface. This commit also contains minor changes to the formatting of the bulk config converter.
1 parent 697e484 commit 321a50d

17 files changed

Lines changed: 815 additions & 931 deletions

src/ert/__main__.py

Lines changed: 23 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
import os
99
import re
1010
import resource
11-
import shutil
1211
import sys
1312
import warnings
1413
from argparse import ArgumentParser, ArgumentTypeError
1514
from collections.abc import Sequence
16-
from datetime import datetime
1715
from pathlib import Path
1816
from typing import Any
1917
from uuid import UUID
@@ -26,10 +24,6 @@
2624
from ert.base_model_context import use_runtime_plugins
2725
from ert.cli.main import ErtCliError, run_cli
2826
from ert.config import ConfigValidationError, ErtConfig, lint_file
29-
from ert.config.observation_config_migrations import (
30-
remove_refcase_and_time_map_dependence_from_obs_config,
31-
)
32-
from ert.export_observations import export_observations
3327
from ert.logging import LOGGING_CONFIG
3428
from ert.mode_definitions import (
3529
ENIF_MODE,
@@ -40,6 +34,7 @@
4034
WORKFLOW_MODE,
4135
)
4236
from ert.namespace import Namespace
37+
from ert.observation_converters import SupportedFormat, convert_observations
4338
from ert.plugins import ErtRuntimePlugins, get_site_plugins, setup_site_logging
4439
from ert.services import ErtServerController
4540
from ert.services._storage_main import add_parser_options as ert_api_add_parser_options
@@ -58,66 +53,6 @@
5853
logger = logging.getLogger(__name__)
5954

6055

61-
def run_convert_observations(
62-
args: Namespace, _: ErtRuntimePlugins | None = None
63-
) -> None:
64-
changes = remove_refcase_and_time_map_dependence_from_obs_config(args.config)
65-
66-
if changes is None or changes.is_empty():
67-
logger.info("convert_observations did not make any changes")
68-
print(
69-
"No observations dependent on TIME_MAP / REFCASE found, you can "
70-
"safely remove TIME_MAP / REFCASE and the "
71-
"corresponding files from ERT config."
72-
)
73-
return
74-
75-
obs_config_to_edit_path = changes.obs_config_path + ".updated"
76-
print(
77-
f"Making copy of obs config "
78-
f"@ {changes.obs_config_path} -> {obs_config_to_edit_path}"
79-
)
80-
81-
shutil.copy(changes.obs_config_path, obs_config_to_edit_path)
82-
print(f"Applying change to obs config @ {obs_config_to_edit_path}...")
83-
changes.apply_to_file(Path(obs_config_to_edit_path))
84-
convert_observations_trace = ""
85-
for history_change in changes.history_changes:
86-
convert_observations_trace += (
87-
f"History obs {history_change.source_observation.name} "
88-
f"-> {len(history_change.summary_obs_declarations)} summary observations\n"
89-
)
90-
91-
for gen_obs_change in changes.general_obs_changes:
92-
convert_observations_trace += (
93-
f"General obs {gen_obs_change.source_observation.name}, changing "
94-
f"DATE {gen_obs_change.source_observation.date} "
95-
f"to RESTART={gen_obs_change.restart}\n"
96-
)
97-
for summary_change in changes.summary_obs_changes:
98-
convert_observations_trace += (
99-
f"Summary obs {summary_change.source_observation.name}, changing "
100-
f"RESTART {summary_change.source_observation.restart} "
101-
f"to DATE={summary_change.date}\n"
102-
)
103-
104-
logger.info(f"convert_observations trace: \n {convert_observations_trace}")
105-
print(convert_observations_trace)
106-
107-
os.rename(
108-
changes.obs_config_path,
109-
f"{changes.obs_config_path}-{datetime.now().astimezone().strftime('%Y-%m-%d-%H-%M-%S')}.old",
110-
)
111-
os.rename(obs_config_to_edit_path, changes.obs_config_path)
112-
msg = (
113-
f"Observation changes applied to {changes.obs_config_path}. The old "
114-
f"observations file is now at {changes.obs_config_path}.old and can be "
115-
f"safely deleted if the new one works."
116-
)
117-
print(msg)
118-
logger.info(msg)
119-
120-
12156
def run_ert_storage(args: Namespace, _: ErtRuntimePlugins | None = None) -> None:
12257
with ErtServerController.start_server(
12358
verbose=True,
@@ -554,71 +489,39 @@ def get_ert_parser(parser: ArgumentParser | None = None) -> ArgumentParser:
554489
)
555490

556491
# convert_observations_parser
492+
help_text = (
493+
"Convert observations to an observation format. "
494+
"Must be provided with an ERT configuration file. "
495+
"The default behaviour is to convert from history "
496+
"observation format to summary, but this can be "
497+
"configured using the --format flag to specify "
498+
"which format to convert to."
499+
"Valid formats are: bulk, summary"
500+
)
557501
convert_obs_parser = subparsers.add_parser(
558502
"convert_observations",
559-
help=(
560-
"Convert HISTORY_OBSERVATION to SUMMARY_OBSERVATION and "
561-
"remove REFCASE and TIME_MAP from ERT config."
562-
),
563-
description=(
564-
"Convert HISTORY_OBSERVATION to SUMMARY_OBSERVATION, "
565-
"and embed REFCASE and TIME_MAP into observations"
566-
),
567-
)
568-
convert_obs_parser.set_defaults(func=run_convert_observations)
503+
help=help_text,
504+
description=help_text,
505+
)
506+
convert_obs_parser.set_defaults(func=convert_observations)
569507
convert_obs_parser.add_argument(
570508
"config",
571509
type=valid_file,
572510
help="Path to ERT config file",
573511
)
512+
513+
convert_obs_parser.add_argument(
514+
"--format",
515+
dest="format",
516+
required=False,
517+
default=SupportedFormat.SUMMARY,
518+
choices=SupportedFormat,
519+
help="Observation format to convert to.",
520+
)
574521
convert_obs_parser.add_argument(
575522
"--verbose", action="store_true", help="Show verbose output.", default=False
576523
)
577524

578-
# Experimental feature
579-
if os.environ.get("ERT_FEATURE_GATHER_OBS"):
580-
extract_obs_summary_keys_parser = subparsers.add_parser(
581-
"export_observations",
582-
description=(
583-
"Identify all summary and breakthrough observations and output them "
584-
"in a bulk config format. A CSV file containing the observation values "
585-
"is written to disk while the bulk config is printed to terminal to be "
586-
"copied into the observation configuration.\n"
587-
"Given no experiment argument, will prompt for which experiment to "
588-
"extract observations from if there are multiple to choose from in "
589-
"storage.\n"
590-
"This workflow will not overwrite any existing configuration files, so "
591-
"the output will have to be manually integrated.\n"
592-
"This command requires the path to an ert config file as first "
593-
"argument and optionally an experiment ID as second argument. The name "
594-
"of the produced CSV filename is defaulted to "
595-
"'summary_observations.csv', but can be manually set using the keyword "
596-
"argument:\n"
597-
"--output-csv-file <filename>"
598-
),
599-
help="This command requires the path to an ert config file as first "
600-
"argument and optionally an experiment ID as second argument. The name "
601-
"of the produced CSV filename is defaulted to 'summary_observations.csv', "
602-
"but can be manually set using the keyword argument:\n"
603-
"--output-csv-file <filename>",
604-
)
605-
extract_obs_summary_keys_parser.set_defaults(func=export_observations)
606-
extract_obs_summary_keys_parser.add_argument(
607-
"config", type=valid_file, help="Path to ERT config file"
608-
)
609-
extract_obs_summary_keys_parser.add_argument(
610-
"experiment_id", nargs="?", type=str, default=None, help="Experiment ID"
611-
)
612-
extract_obs_summary_keys_parser.add_argument(
613-
"--output-csv-file",
614-
default="summary_observations.csv",
615-
type=str,
616-
help="Output CSV file name",
617-
)
618-
extract_obs_summary_keys_parser.add_argument(
619-
"--verbose", action="store_true", help="Show verbose output.", default=False
620-
)
621-
622525
# Common arguments/defaults for all non-gui modes
623526
for cli_parser in [
624527
test_run_parser,

src/ert/export_observations/__init__.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/ert/export_observations/bulk_config_exporter.py

Lines changed: 0 additions & 178 deletions
This file was deleted.

0 commit comments

Comments
 (0)