diff --git a/tests/jobs/localisation/example_case/example_case.yml b/tests/jobs/localisation/example_case/example_case.yml new file mode 100644 index 000000000..ee9ea8332 --- /dev/null +++ b/tests/jobs/localisation/example_case/example_case.yml @@ -0,0 +1,45 @@ +settings: + grid_size: + xsize: 7500.0 + ysize: 12500.0 + zsize: 50.0 + use_eclipse_grid_index_origo: "eclipse" + + field: + name: "FIELDPARAM" + initial_file_name: "init_files/FieldParam.roff" + updated_file_name: "FieldParam.roff" + seed_file: "randomseeds.txt" + variogram: "gaussian" + correlation_range: [5000.0, 3000.0, 2.0] + correlation_azimuth: 45.0 + correlation_dip: 0.0 + trend_use: False + trend_params: [ 1.0, -1.0 ] + trend_relstd: 0.15 + grid_dimension: [150, 250, 1] + grid_file_name: "GRID.EGRID" + + response: + grid_dimension: [15, 25, 1] + upscaled_file_name: "Upscaled.roff" + grid_file_name: "UpscaleGrid.EGRID" + response_function: "average" + gen_data_file_name: "UpscaledField_0.txt" + calculate_all_cells: True + + observation: + directory: "observations" + file_name: "observations.obs" + data_dir: "obs_data" + 3D_param_file_name: "init_files/UpscaledObsField.roff" + rel_error: 0.10 + min_abs_error: 0.01 + selected_grid_cells: + - [5, 10, 1] + - [10, 20, 1] + + optional: + write_upscaled_to_file: True + write_obs_pred_diff_field_file: True + diff --git a/tests/jobs/localisation/example_case/modify_variogram.yml b/tests/jobs/localisation/example_case/modify_variogram.yml new file mode 100644 index 000000000..2b74d14f9 --- /dev/null +++ b/tests/jobs/localisation/example_case/modify_variogram.yml @@ -0,0 +1,15 @@ +settings: + + field: + variogram: "spherical" + correlation_range: [4000.0, 4000.0, 2.0] + + observation: + directory: "observations2" + data_dir: "obs_data2" + 3D_param_file_name: "init_files/UpscaledObsField2.roff" + + + + + diff --git a/tests/jobs/localisation/example_case/scripts/common_functions.py b/tests/jobs/localisation/example_case/scripts/common_functions.py index 27366aefd..f0fa19893 100644 --- a/tests/jobs/localisation/example_case/scripts/common_functions.py +++ b/tests/jobs/localisation/example_case/scripts/common_functions.py @@ -5,6 +5,8 @@ import xtgeo import gaussianfft as sim import numpy as np +import yaml +import copy # NOTE: xtgeo MUST be imported BEFORE gaussianfft @@ -47,110 +49,164 @@ # pylint: disable= redefined-outer-name, too-many-nested-blocks -def specify_settings(): +def specify_settings(spec_dict=None, yml_file_name=None): """ grid_size - length, width, thickness of a box containing the field - Same size is used for both fine scale grid with the simulated field - and the coarse scale grid containing upscaled values - of the simulated field. - - field_settings - Define the dimension (number of grid cells) for fine scale grid, - name of output files and specification of model parameters for - simulation of gaussian field with option to use linear trend. - Relative standard deviation specify standard deviation of - gaussian residual field relative to the trends span of value - (max trend value - min trend value) - - response_settings - Specify the coarse grid dimensions, name of file and type + Same size is used for both fine scale grid with + the simulated field and the coarse scale grid + containing upscaled values of the simulated field. + + field - Define the dimension (number of grid cells) for fine scale grid, + name of output files and specification of model parameters for + simulation of gaussian field with option to use linear trend. + Relative standard deviation specify standard deviation of + gaussian residual field relative to the trends span of value + (max trend value - min trend value) + + response - Specify the coarse grid dimensions, name of file and type of average operation to calculated upscaled values that are predictions of observations of the same grid cells. Which cell indices are observed are specified in observation settings. - observation_settings - Specify name of files for generated observations + observation - Specify name of files for generated observations and also which grid cells from coarse grid is used as observables. (Cells that have values that are used as observations) - """ - grid_size = { - "xsize": 7500.0, - "ysize": 12500.0, - "zsize": 50.0, - "use_eclipse_grid_index_origin": True, - } - field_settings = { - "grid_dimension": [150, 250, 1], - "grid_file_name": "GRID.EGRID", - "field_correlation_range": [3000.0, 1000.0, 2.0], - "field_correlation_azimuth": 45.0, - "field_correlation_dip": 0.0, - "field_variogram": "spherical", - "field_trend_params": [1.0, -1.0], - "field_trend_relstd": 0.05, - "field_trend_use": 0, - "field_name": "FIELDPARAM", - "field_updated_file_name": "FieldParam.roff", - "field_initial_file_name": "init_files/FieldParam.roff", - "field_seed_file": "randomseeds.txt", - } - response_settings = { - "grid_dimension": [15, 25, 1], - "upscaled_file_name": "Upscaled.roff", - "grid_file_name": "UpscaleGrid.EGRID", - "response_function": "average", - "gen_data_file_name": "UpscaledField_0.txt", - "all": True, - } - observation_settings = { - "observation_dir": "observations", - "observation_file": "observations.obs", - "observation_data_dir": "obs_data", - "3D_param_file_name": "init_files/UpscaledObsField.roff", - "rel_error": 0.10, - "min_abs_error": 0.01, - "selected_grid_cells": [ - [5, 10, 1], - ], - # "selected_grid_cells":[ - # [15, 1, 1], - # [15, 25, 1], - # [ 1, 25, 1], - # [ 1, 1, 1], - # [ 3, 3, 1], - # [ 5, 23, 1], - # [11, 4, 1], - # [ 3, 12, 1], - # [13, 18, 1], - # ], + optional - Specify if some optional files should be + written or not (for QC purpose) + """ + default_settings = { + "grid_size": { + "xsize": 7500.0, + "ysize": 12500.0, + "zsize": 50.0, + "use_eclipse_grid_index_origo": True, + }, + "field": { + "name": "FIELDPARAM", + "initial_file_name": "init_files/FieldParam.roff", + "updated_file_name": "FieldParam.roff", + "seed_file": "randomseeds.txt", + "variogram": "gaussian", + "correlation_range": [5000.0, 3000.0, 2.0], + "correlation_azimuth": 45.0, + "correlation_dip": 0.0, + "trend_use": 0, + "trend_params": [1.0, -1.0], + "trend_relstd": 0.05, + "grid_dimension": [150, 250, 1], + "grid_file_name": "GRID.EGRID", + }, + "response": { + "grid_dimension": [15, 25, 1], + "upscaled_file_name": "Upscaled.roff", + "grid_file_name": "UpscaleGrid.EGRID", + "response_function": "average", + "gen_data_file_name": "UpscaledField_0.txt", + "calculate_all_cells": True, + }, + "observation": { + "directory": "observations", + "file_name": "observations.obs", + "data_dir": "obs_data", + "3D_param_file_name": "init_files/UpscaledObsField.roff", + "rel_error": 0.10, + "min_abs_error": 0.01, + "selected_grid_cells": [ + [5, 10, 1], + [10, 20, 1], + ], + # "selected_grid_cells":[ + # [15, 1, 1], + # [15, 25, 1], + # [ 1, 25, 1], + # [ 1, 1, 1], + # [ 3, 3, 1], + # [ 5, 23, 1], + # [11, 4, 1], + # [ 3, 12, 1], + # [13, 18, 1], + # ], + }, + "optional": { + "write_upscaled_to_file": True, + "write_obs_pred_diff_field_file": True, + } } - return grid_size, field_settings, response_settings, observation_settings + settings = copy.deepcopy(default_settings) + if spec_dict is not None: + main_key = "settings" + if main_key not in spec_dict: + raise KeyError(f"Missing main keyword {main_key} in file: {yml_file_name}") + settings_yml_dict = spec_dict[main_key] + valid_keys1 = default_settings.keys() + for key1 in settings_yml_dict.keys(): + if key1 in valid_keys1: + valid_keys2 = default_settings[key1].keys() + for key2 in settings_yml_dict[key1].keys(): + if key2 in valid_keys2: + print(f"Modifying default setting for keyword '{key2}' under '{key1}' in file {yml_file_name} ") + settings[key1][key2] = settings_yml_dict[key1][key2] + else: + raise KeyError(f"Unknown keyword '{key2}' specified under keyword '{key1}' in {yml_file_name}") + else: + raise KeyError(f"Unknown keyword '{key1}' specified under keyword '{main_key}' in {yml_file_name}") + return settings + + +# def update_settings(settings_dict, spec_dict, main_key, sub_keys): +# if main_key in spec_dict: +# main_key_dict = spec_dict[main_key] +# print(f"main_key_dict: {main_key_dict}") +# if main_key_dict is not None: +# print(f"sub_keys: {sub_keys}") +# for key in sub_keys: +# if key in main_key_dict: +# print(f"Settings updated for:{main_key} with sub key: {key} ") +# settings_dict[key] = main_key_dict[key] +# return settings_dict + + +def read_test_config(config_file_name): + if config_file_name is None: + spec_dict = None + else: + words = config_file_name.split('.') + if words[-1].upper() not in ['YML', 'YAML']: + raise IOError( + f"Expecting input yaml file as last argument for script {__file__}. " + f"Got the file {config_file_name} ") + with open(config_file_name, "r", encoding="utf-8") as yml_file: + spec_dict = yaml.safe_load(yml_file) + + return specify_settings(spec_dict, config_file_name) def generate_field_and_upscale( - field_settings, grid_size, response_settings, observation_settings, real_number + settings, real_number ): - seed_file_name = field_settings["field_seed_file"] - relative_std = field_settings["field_trend_relstd"] - use_trend = field_settings["field_trend_use"] + seed_file_name = settings["field"]["seed_file"] + relative_std = settings["field"]["trend_relstd"] + use_trend = settings["field"]["trend_use"] start_seed = get_seed(seed_file_name, real_number) - residual_field = simulate_field(grid_size, field_settings, start_seed) + residual_field = simulate_field(settings, start_seed) if use_trend == 1: - trend_field = trend(grid_size, field_settings) + trend_field = trend(settings) field3D = trend_field + relative_std * residual_field else: field3D = residual_field # Write field parameter for fine scale grid - field_object = export_field(field_settings, field3D) + field_object = export_field(settings, field3D) field_values = field_object.values # Calculate upscaled values for selected coarse grid cells upscaled_values = upscaling( field_values, - response_settings, - observation_settings, + settings, write_field=True, iteration=0, ) @@ -168,14 +224,14 @@ def get_seed(seed_file_name, r_number): def upscaling( - field_values, response_settings, observation_settings, write_field=True, iteration=0 + field_values, settings, write_field=True, iteration=0 ): - response_function_name = response_settings["response_function"] - upscaled_file_name = response_settings["upscaled_file_name"] - NX, NY, NZ = response_settings["grid_dimension"] - calculate_all = response_settings["all"] + response_function_name = settings["response"]["response_function"] + upscaled_file_name = settings["response"]["upscaled_file_name"] + NX, NY, NZ = settings["response"]["grid_dimension"] + calculate_all = settings["response"]["calculate_all_cells"] - coarse_cell_index_list = observation_settings["selected_grid_cells"] + coarse_cell_index_list = settings["observation"]["selected_grid_cells"] upscaled_values = np.zeros((NX, NY, NZ), dtype=np.float32, order="F") upscaled_values[:, :, :] = -999 @@ -297,9 +353,9 @@ def upscale_average( return upscaled_values -def write_prediction_gen_data(upscaled_values, observation_settings, response_settings): - cell_indx_list = observation_settings["selected_grid_cells"] - response_file_name = response_settings["gen_data_file_name"] +def write_prediction_gen_data(upscaled_values, settings): + cell_indx_list = settings["observation"]["selected_grid_cells"] + response_file_name = settings["response"]["gen_data_file_name"] print(f"Write GEN_DATA file with prediction of observations: {response_file_name}") with open(response_file_name, "w", encoding="utf8") as file: # NOTE: The sequence of values must be the same as for the observations @@ -312,15 +368,15 @@ def write_prediction_gen_data(upscaled_values, observation_settings, response_se file.write(f"{value}\n") -def trend(grid_size, field_settings): +def trend(settings): """ Return 3D numpy array with values following a linear trend scaled to take values between 0 and 1. """ - nx, ny, nz = field_settings["grid_dimension"] - xsize = grid_size["xsize"] - ysize = grid_size["ysize"] - a, b = field_settings["field_trend_params"] + nx, ny, nz = settings["field"]["grid_dimension"] + xsize = settings["grid_size"]["xsize"] + ysize = settings["grid_size"]["ysize"] + a, b = settings["field"]["trend_params"] x0 = 0.0 y0 = 0.0 @@ -345,21 +401,21 @@ def trend(grid_size, field_settings): return val_normalized -def simulate_field(grid_size, field_settings, start_seed): +def simulate_field(settings, start_seed): # pylint: disable=no-member, - variogram_name = field_settings["field_variogram"] - corr_ranges = field_settings["field_correlation_range"] + variogram_name = settings["field"]["variogram"] + corr_ranges = settings["field"]["correlation_range"] xrange = corr_ranges[0] yrange = corr_ranges[1] zrange = corr_ranges[2] - azimuth = field_settings["field_correlation_azimuth"] - dip = field_settings["field_correlation_dip"] + azimuth = settings["field"]["correlation_azimuth"] + dip = settings["field"]["correlation_dip"] - nx, ny, nz = field_settings["grid_dimension"] - xsize = grid_size["xsize"] - ysize = grid_size["ysize"] - zsize = grid_size["zsize"] + nx, ny, nz = settings["field"]["grid_dimension"] + xsize = settings["grid_size"]["xsize"] + ysize = settings["grid_size"]["ysize"] + zsize = settings["grid_size"]["zsize"] dx = xsize / nx dy = ysize / ny @@ -383,11 +439,11 @@ def simulate_field(grid_size, field_settings, start_seed): return field -def export_field(field_settings, field3D): +def export_field(settings, field3D): # Export initial ensemble field - nx, ny, nz = field_settings["grid_dimension"] - field_name = field_settings["field_name"] - field_file_name = field_settings["field_initial_file_name"] + nx, ny, nz = settings["field"]["grid_dimension"] + field_name = settings["field"]["name"] + field_file_name = settings["field"]["initial_file_name"] field_object = xtgeo.grid3d.GridProperty( ncol=nx, nrow=ny, nlay=nz, values=field3D, discrete=False, name=field_name @@ -398,23 +454,23 @@ def export_field(field_settings, field3D): return field_object -def read_field_from_file(field_settings): - input_file_name = field_settings["field_updated_file_name"] - name = field_settings["field_name"] +def read_field_from_file(settings): + input_file_name = settings["field"]["updated_file_name"] + name = settings["field"]["name"] field_object = xtgeo.gridproperty_from_file( input_file_name, fformat="roff", name=name ) return field_object -def read_obs_field_from_file(observation_settings): - input_file_name = observation_settings["3D_param_file_name"] +def read_obs_field_from_file(settings): + input_file_name = settings["observation"]["3D_param_file_name"] obs_field_object = xtgeo.gridproperty_from_file(input_file_name, fformat="roff") return obs_field_object -def read_upscaled_field_from_file(response_settings, iteration): - input_file_name = response_settings["upscaled_file_name"] +def read_upscaled_field_from_file(settings, iteration): + input_file_name = settings["response"]["upscaled_file_name"] if iteration == 0: filename = "init_files/" + input_file_name else: diff --git a/tests/jobs/localisation/example_case/scripts/import_field_parameters_local.py b/tests/jobs/localisation/example_case/scripts/import_field_parameters_local.py new file mode 100644 index 000000000..72ea1e090 --- /dev/null +++ b/tests/jobs/localisation/example_case/scripts/import_field_parameters_local.py @@ -0,0 +1,103 @@ +""" +Import field parameters into RMS (Must be included as python job +in RMS workflow and edited to fit your scratch directory) +""" +from pathlib import Path + +import xtgeo + +# SCRATCH = "/scratch/fmu/olia/sim_field/" +SCRATCH = "/scratch/fmu/olia/sim_field_local/" +# CASE_NAME = "original" +CASE_NAME = "local" + + +# pylint: disable=undefined-variable, bare-except +PRJ = project # noqa: 821 + +GRID_MODEL_NAME = "GRID" +FIELD_NAMES = [ + "FieldParam", +] + + +def main(): + """ + Import files with initial ensemble and updated fields into RMS project + """ + xtgeo.grid_from_roxar(PRJ, GRID_MODEL_NAME, PRJ.current_realisation) + + path = Path(SCRATCH) + if not path.exists(): + raise IOError(f"File path: {SCRATCH} does not exist. ") + + real = PRJ.current_realisation + print("\n") + print(f"Realization: {real} ") + for name in FIELD_NAMES: + for iteration in [0, 3]: + print(f"Iteration: {iteration}") + if iteration == 0: + name_with_iter = name + "_" + CASE_NAME + "_" + str(iteration) + path = ( + SCRATCH + + "realization-" + + str(real) + + "/iter-" + + str(iteration) + + "/init_files/" + ) + file_name = path + name + ".roff" + print(f"File name: {file_name} ") + + try: + property0 = xtgeo.gridproperty_from_file(file_name, "roff") + print( + f"Import property {property0.name} from file" + f" {file_name} into {name_with_iter} " + ) + property0.to_roxar( + PRJ, GRID_MODEL_NAME, name_with_iter, realisation=real + ) + except: # noqa: E722 + print(f"Skip realization: {real} for iteration: {iteration} ") + elif iteration == 3: + name_with_iter = name + "_" + CASE_NAME + "_" + str(iteration) + path = ( + SCRATCH + + "realization-" + + str(real) + + "/iter-" + + str(iteration) + + "/" + ) + file_name = path + name + ".roff" + print(f"File name: {file_name} ") + + try: + property3 = xtgeo.gridproperty_from_file(file_name, "roff") + print( + f"Import property {property3.name} for iteration {iteration} " + f"from file {file_name} into {name_with_iter} " + ) + property3.to_roxar( + PRJ, GRID_MODEL_NAME, name_with_iter, realisation=real + ) + except: # noqa: E722 + print(f"Skip realization: {real} for iteration: {iteration} ") + try: + diff_property = property0 + diff_property.values = property3.values - property0.values + name_diff = name + "_" + CASE_NAME + "_diff" + print( + f"Calculate difference between iteration 3 and 0: {name_diff}" + ) + diff_property.to_roxar( + PRJ, GRID_MODEL_NAME, name_diff, realisation=real + ) + except: # noqa: E722 + print(f"Skip difference for realisation: {real} ") + + +if __name__ == "__main__": + main() diff --git a/tests/jobs/localisation/example_case/scripts/import_upscaled_field_parameters_local.py b/tests/jobs/localisation/example_case/scripts/import_upscaled_field_parameters_local.py new file mode 100644 index 000000000..b2d0f20a2 --- /dev/null +++ b/tests/jobs/localisation/example_case/scripts/import_upscaled_field_parameters_local.py @@ -0,0 +1,103 @@ +# Import field parameters +""" +Import upscaled field parameters into RMS (Must be included as python job +in RMS workflow and edited to fit your scratch directory) +""" +from pathlib import Path + +import xtgeo + +# Set scratch file directory for the case and name of case (one short word) +# SCRATCH = "/scratch/fmu/olia/sim_field/" +SCRATCH = "/scratch/fmu/olia/sim_field_local/" +# CASE_NAME = "original" +CASE_NAME = "local" + + +# pylint: disable=undefined-variable, bare-except +PRJ = project # noqa: 821 + +GRID_MODEL_NAME = "UpscaleGrid" +FIELD_NAMES = [ + "Upscaled", +] + + +def main(): + """ + Import files with upscaled initial ensemble and updated fields into RMS + """ + + xtgeo.grid_from_roxar(PRJ, GRID_MODEL_NAME, PRJ.current_realisation) + + path = Path(SCRATCH) + if not path.exists(): + raise IOError(f"File path: {SCRATCH} does not exist. ") + + real = PRJ.current_realisation + print("\n") + print(f"Realization: {real} ") + for name in FIELD_NAMES: + for iteration in [0, 3]: + print(f"Iteration: {iteration}") + name_with_iter = name + "_" + CASE_NAME + "_" + str(iteration) + if iteration == 0: + path = ( + SCRATCH + + "realization-" + + str(real) + + "/iter-" + + str(iteration) + + "/init_files/" + ) + file_name = path + name + ".roff" + print(f"File name: {file_name} ") + try: + property0 = xtgeo.gridproperty_from_file(file_name, "roff") + print( + f"Import property {property0.name} from file " + f"{file_name} into {name_with_iter} " + ) + property0.to_roxar( + PRJ, GRID_MODEL_NAME, name_with_iter, realisation=real + ) + except: # noqa: E722 + print(f"Skip realization: {real} for iteration: {iteration} ") + elif iteration == 3: + path = ( + SCRATCH + + "realization-" + + str(real) + + "/iter-" + + str(iteration) + + "/" + ) + file_name = path + name + ".roff" + print(f"File name: {file_name} ") + try: + property3 = xtgeo.gridproperty_from_file(file_name, "roff") + print( + f"Import property {property3.name} for iteration {iteration} " + f"from file {file_name} into {name_with_iter} " + ) + property3.to_roxar( + PRJ, GRID_MODEL_NAME, name_with_iter, realisation=real + ) + except: # noqa: E722 + print(f"Skip realization: {real} for iteration: {iteration} ") + try: + diff_property = property0 + diff_property.values = property3.values - property0.values + name_diff = name + "_" + CASE_NAME + "_diff" + print( + f"Calculate difference between iteration 3 and 0: {name_diff}" + ) + diff_property.to_roxar( + PRJ, GRID_MODEL_NAME, name_diff, realisation=real + ) + except: # noqa: E722 + print(f"Skip difference for realisation: {real} ") + + +if __name__ == "__main__": + main() diff --git a/tests/jobs/localisation/example_case/scripts/init_test_case.py b/tests/jobs/localisation/example_case/scripts/init_test_case.py index 07679a090..ab4ce8e04 100755 --- a/tests/jobs/localisation/example_case/scripts/init_test_case.py +++ b/tests/jobs/localisation/example_case/scripts/init_test_case.py @@ -5,12 +5,13 @@ import math import os import random +import sys import xtgeo from common_functions import ( - specify_settings, + read_test_config, write_upscaled_field, generate_field_and_upscale, ) @@ -20,12 +21,12 @@ # pylint: disable=too-many-locals,import-error -def generate_seed_file( - seed_file_name: str = "randomseeds.txt", +def generate_seed_file(settings, start_seed: int = 9828862224, number_of_seeds: int = 1000, ): # pylint: disable=unused-variable + seed_file_name = settings["field"]["seed_file"] print(f"Generate random seed file: {seed_file_name}") random.seed(start_seed) with open(seed_file_name, "w", encoding="utf8") as file: @@ -33,16 +34,16 @@ def generate_seed_file( file.write(f"{random.randint(1, 999999999)}\n") -def obs_positions(grid_size, response_settings, observation_settings): - NX, NY, _ = response_settings["grid_dimension"] - use_eclipse_origin = grid_size["use_eclipse_grid_index_origin"] +def obs_positions(settings): + NX, NY, _ = settings["response"]["grid_dimension"] + use_eclipse_origo = settings["grid_size"]["use_eclipse_grid_index_origo"] - xsize = grid_size["xsize"] - ysize = grid_size["ysize"] + xsize = settings["grid_size"]["xsize"] + ysize = settings["grid_size"]["ysize"] dx = xsize / NX dy = ysize / NY - cell_indx_list = observation_settings["selected_grid_cells"] - if use_eclipse_origin: + cell_indx_list = settings["observation"]["selected_grid_cells"] + if use_eclipse_origo: print("Grid index origin: Eclipse standard") else: print("Grid index origin: RMS standard") @@ -56,7 +57,7 @@ def obs_positions(grid_size, response_settings, observation_settings): Iindx = indices[0] - 1 Jindx = indices[1] - 1 x = (Iindx + 0.5) * dx - if use_eclipse_origin: + if use_eclipse_origo: y = ysize - (Jindx + 0.5) * dy else: y = (Jindx + 0.5) * dy @@ -67,21 +68,17 @@ def obs_positions(grid_size, response_settings, observation_settings): def write_localisation_config( - observation_settings, - field_settings, - grid_size, - response_settings, - config_file_name="local_config.yml", + settings, config_file_name="local_config.yml", write_scaling=True, ): - obs_index_list = observation_settings["selected_grid_cells"] - field_name = field_settings["field_name"] - corr_ranges = field_settings["field_correlation_range"] - azimuth = field_settings["field_correlation_azimuth"] + obs_index_list = settings["observation"]["selected_grid_cells"] + field_name = settings["field"]["name"] + corr_ranges = settings["field"]["correlation_range"] + azimuth = settings["field"]["correlation_azimuth"] space = " " * 2 space2 = " " * 4 space3 = " " * 6 - positions = obs_positions(grid_size, response_settings, observation_settings) + positions = obs_positions(settings) print(f"Write localisation config file: {config_file_name}") with open(config_file_name, "w", encoding="utf8") as file: file.write("log_level: 3\n") @@ -104,13 +101,13 @@ def write_localisation_config( file.write(f"{space3}ref_point: [ {pos[0]}, {pos[1]} ]\n") -def write_gen_obs(upscaled_values, observation_settings): - observation_dir = observation_settings["observation_dir"] - obs_file_name = observation_settings["observation_file"] - obs_data_dir = observation_settings["observation_data_dir"] - cell_indx_list = observation_settings["selected_grid_cells"] - rel_err = observation_settings["rel_error"] - min_err = observation_settings["min_abs_error"] +def write_gen_obs(upscaled_values, settings): + observation_dir = settings["observation"]["directory"] + obs_file_name = settings["observation"]["file_name"] + obs_data_dir = settings["observation"]["data_dir"] + cell_indx_list = settings["observation"]["selected_grid_cells"] + rel_err = settings["observation"]["rel_error"] + min_err = settings["observation"]["min_abs_error"] if not os.path.exists(observation_dir): print(f"Create directory: {observation_dir} ") os.makedirs(observation_dir) @@ -157,13 +154,13 @@ def write_gen_obs(upscaled_values, observation_settings): data_file.write(f"{value} {value_err}\n") -def create_grid(grid_size, field_settings): - grid_file_name = field_settings["grid_file_name"] - nx, ny, nz = field_settings["grid_dimension"] - xsize = grid_size["xsize"] - ysize = grid_size["ysize"] - zsize = grid_size["zsize"] - if grid_size["use_eclipse_grid_index_origin"]: +def create_grid(settings): + grid_file_name = settings["field"]["grid_file_name"] + nx, ny, nz = settings["field"]["grid_dimension"] + xsize = settings["grid_size"]["xsize"] + ysize = settings["grid_size"]["ysize"] + zsize = settings["grid_size"]["zsize"] + if settings["grid_size"]["use_eclipse_grid_index_origo"]: flip = -1 x0 = 0.0 y0 = ysize @@ -191,13 +188,13 @@ def create_grid(grid_size, field_settings): return grid_object -def create_upscaled_grid(grid_size, response_settings): - grid_file_name = response_settings["grid_file_name"] - nx, ny, nz = response_settings["grid_dimension"] - xsize = grid_size["xsize"] - ysize = grid_size["ysize"] - zsize = grid_size["zsize"] - if grid_size["use_eclipse_grid_index_origin"]: +def create_upscaled_grid(settings): + grid_file_name = settings["response"]["grid_file_name"] + nx, ny, nz = settings["response"]["grid_dimension"] + xsize = settings["grid_size"]["xsize"] + ysize = settings["grid_size"]["ysize"] + zsize = settings["grid_size"]["zsize"] + if settings["grid_size"]["use_eclipse_grid_index_origo"]: flip = -1 x0 = 0.0 y0 = ysize @@ -225,59 +222,54 @@ def create_upscaled_grid(grid_size, response_settings): return grid_object -def main(): +def main(config_file_name): """ Initialize seed file, grid files, observation files and localisation config file """ # Settings are specified here - ( - grid_size, - field_settings, - response_settings, - observation_settings, - ) = specify_settings() + settings = read_test_config(config_file_name) # Create seed file - generate_seed_file(field_settings["field_seed_file"]) + generate_seed_file(settings) # Create grid for the field parameter - create_grid(grid_size, field_settings) + create_grid(settings) # Create coarse grid to be used in QC of upscaled field parameter - create_upscaled_grid(grid_size, response_settings) + create_upscaled_grid(settings) print("Generate field parameter and upscale this.") print( - f"The upscaled field {observation_settings['3D_param_file_name']} " + f"The upscaled field {settings['observation']['3D_param_file_name']} " "is used when extracting observations." ) # Simulate field (with trend) real_number = 0 - upscaled_values = generate_field_and_upscale( - field_settings, grid_size, response_settings, observation_settings, real_number - ) + upscaled_values = generate_field_and_upscale(settings, real_number ) # Create observations by extracting from existing upscaled field - write_gen_obs(upscaled_values, observation_settings) + write_gen_obs(upscaled_values, settings) # Write upscaled field used as truth realisation write_upscaled_field( upscaled_values, - observation_settings["3D_param_file_name"], - selected_cell_index_list=observation_settings["selected_grid_cells"], + settings["observation"]["3D_param_file_name"], + selected_cell_index_list=settings["observation"]["selected_grid_cells"], ) # Write file for non-adaptive localisation using distance based localisation - write_localisation_config( - observation_settings, - field_settings, - grid_size, - response_settings, + write_localisation_config(settings, config_file_name="local_config.yml", write_scaling=True, ) if __name__ == "__main__": - main() + config_file_name = None + if len(sys.argv) < 2: + print("Use default settings") + else: + config_file_name = sys.argv[1] + print(f"Read modified settings from file: {config_file_name} ") + main(config_file_name) diff --git a/tests/jobs/localisation/example_case/scripts/sim_fields.py b/tests/jobs/localisation/example_case/scripts/sim_fields.py index 7a44aa305..77aff0749 100755 --- a/tests/jobs/localisation/example_case/scripts/sim_fields.py +++ b/tests/jobs/localisation/example_case/scripts/sim_fields.py @@ -5,9 +5,10 @@ import os import sys + # pylint: disable=import-error from common_functions import ( - specify_settings, + read_test_config, generate_field_and_upscale, read_field_from_file, upscaling, @@ -53,9 +54,9 @@ # pylint: disable=missing-function-docstring,invalid-name -def write_prediction_gen_data(upscaled_values, observation_settings, response_settings): - cell_indx_list = observation_settings["selected_grid_cells"] - response_file_name = response_settings["gen_data_file_name"] +def write_prediction_gen_data(upscaled_values, settings): + cell_indx_list = settings["observation"]["selected_grid_cells"] + response_file_name = settings["response"]["gen_data_file_name"] print(f"Write GEN_DATA file with prediction of observations: {response_file_name}") with open(response_file_name, "w", encoding="utf8") as file: # NOTE: The sequence of values must be the same as for the observations @@ -99,11 +100,7 @@ def get_iteration_and_real_number(argv): return iteration, real_number -def main( - argv, - write_upscaled_to_file=False, - write_obs_pred_diff_field_file=False, -): +def main(config_file_name, iteration, real_number): # pylint: disable=too-many-arguments """ Specify settings for fine grid and model parameters for simulating a @@ -125,58 +122,46 @@ def main( # and the coarse grid with upscaled values must have Eclipse grid index origin # Settings are specified here - ( - grid_size, - field_settings, - response_settings, - observation_settings, - ) = specify_settings() - - iteration, real_number = get_iteration_and_real_number(argv) + + settings = read_test_config(config_file_name) + + if iteration == 0: print(f"Generate new field parameter realization:{real_number} ") # Simulate field (with trend) - upscaled_values = generate_field_and_upscale( - field_settings, - grid_size, - response_settings, - observation_settings, - real_number, - ) + upscaled_values = generate_field_and_upscale(settings, real_number) else: print(f"Import updated field parameter realization: {real_number} ") - field_object = read_field_from_file(field_settings) + field_object = read_field_from_file(settings) field_values = field_object.values # Calculate upscaled values for selected coarse grid cells upscaled_values = upscaling( field_values, - response_settings, - observation_settings, - write_field=write_upscaled_to_file, + settings, + write_field=settings["optional"]["write_upscaled_to_file"], iteration=iteration, ) # Write GEN_DATA file - write_prediction_gen_data(upscaled_values, observation_settings, response_settings) + write_prediction_gen_data(upscaled_values, settings) # Optional output - if write_obs_pred_diff_field_file: - obs_field_object = read_obs_field_from_file(observation_settings) + if settings["optional"]["write_obs_pred_diff_field_file"]: + obs_field_object = read_obs_field_from_file(settings) upscaled_field_object = read_upscaled_field_from_file( - response_settings, iteration + settings, iteration ) write_obs_pred_diff_field(upscaled_field_object, obs_field_object) if __name__ == "__main__": - # Optional output: Write 3D parameter of upscaled values for the selected - # grid cells having observations - define_write_upscaled_to_file = True - define_write_obs_pred_diff_field_file = True - - main( - sys.argv, - write_upscaled_to_file=define_write_upscaled_to_file, - write_obs_pred_diff_field_file=define_write_obs_pred_diff_field_file, - ) + iteration, real_number = get_iteration_and_real_number(sys.argv) + config_file_name = None + if len(sys.argv) < 4: + print("Use default settings") + else: + config_file_name = sys.argv[3] + print(f"Read modified settings from file: {config_file_name} ") + + main(config_file_name, iteration, real_number)