Skip to content

Commit

Permalink
Added possibility to also calculate field paramter statistics for tem…
Browse files Browse the repository at this point in the history
…porary field parameters located in rms/output/aps directory
  • Loading branch information
oddvarlia committed Oct 24, 2024
1 parent c6cef12 commit b6f720e
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 14 deletions.
175 changes: 161 additions & 14 deletions src/subscript/field_statistics/field_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,14 @@ def field_stat(args):
if rms_load_script:
generate_script(rms_load_script, ert_config_path, result_path, config_file)

calc_temporary_field_stats(
field_stat,
ens_path,
result_path,
ert_config_path,
ertbox_size,
)

logger.info(
"Finished running workflow to calculate statistics "
"for ensemble of field parameters"
Expand Down Expand Up @@ -790,13 +798,13 @@ def write_mean_stdev_nactive(
param_name=param_name,
)

logger.info(f"Write parameter: {name_mean}")
logger.info(f" Write parameter: {name_mean}")
xtgeo_ertbox_mean.to_file(result_mean_file_path, fformat="roff")

logger.info(f"Write parameter: {name_stdev}")
logger.info(f" Write parameter: {name_stdev}")
xtgeo_ertbox_stdev.to_file(result_stdev_file_path, fformat="roff")

logger.info(f"Write parameter: {name_nactive}")
logger.info(f" Write parameter: {name_nactive}")
xtgeo_ertbox_ncount_active.to_file(result_nactive_file_path, fformat="roff")


Expand Down Expand Up @@ -852,7 +860,7 @@ def ertbox_to_geogrid_statistics(
zone_conformity,
initialize_geogrid_property_param_values=init_geogrid_param,
)
logger.info(f"Update geogrid parameter: {xtgeo_prop_geogrid_stat.name}")
logger.info(f" Update geogrid parameter: {xtgeo_prop_geogrid_stat.name}")
xtgeo_prop_geogrid_stat.to_file(geogrid_stat_file_name, fformat="roff")


Expand Down Expand Up @@ -892,7 +900,7 @@ def write_fraction_nactive(
values=ertbox_fraction,
)

logger.info(f"Write parameter: {name_fraction}")
logger.info(f" Write parameter: {name_fraction}")
xtgeo_ertbox_fraction.to_file(ertbox_result_fraction_file_path, fformat="roff")

if ncount_active_values is not None:
Expand All @@ -904,7 +912,7 @@ def write_fraction_nactive(
values=ncount_active_values,
)

logger.info(f"Write parameter: {name_nactive}")
logger.info(f" Write parameter: {name_nactive}")
xtgeo_ertbox_ncount_active.to_file(
ertbox_result_nactive_file_path, fformat="roff"
)
Expand Down Expand Up @@ -1001,6 +1009,30 @@ def get_specifications(input_dict, ertbox_size, ert_config_path):

check_used_params(zone_names_used, param_name_dict, disc_param_name_dict)

temporary_ertbox_field = None
init_path = None
param_list = None
key = "temporary_ertbox_fields"
if key in input_dict:
temporary_ertbox_field = input_dict[key]

key = "initial_relative_path"
if key in temporary_ertbox_field:
init_path = temporary_ertbox_field[key]
else:
raise KeyError(
f"Missing keyword: {key} "
"specifying relative path for initial temporary fields."
)
key = "parameter_names"
if key in temporary_ertbox_field:
param_list = temporary_ertbox_field[key]
else:
raise KeyError(
f"Missing keyword: {key} "
"specifying list of temporary field parameter names."
)

return (
ertbox_size,
nreal,
Expand All @@ -1011,6 +1043,8 @@ def get_specifications(input_dict, ertbox_size, ert_config_path):
use_population_stdev,
param_name_dict,
disc_param_name_dict,
init_path,
param_list,
)


Expand Down Expand Up @@ -1142,6 +1176,8 @@ def calc_stats(
use_population_stdev,
param_name_dict,
disc_param_name_dict,
_,
_,
) = get_specifications(input_dict, ertbox_size, ert_config_path)

ensemble_path = ens_path
Expand All @@ -1156,7 +1192,7 @@ def calc_stats(
if zone_name not in param_name_dict:
continue
for param_name in param_name_dict[zone_name]:
logger.info(f"Property: {param_name}")
logger.info(f" Property: {param_name}")
all_values = np.ma.masked_all(
(ertbox_size[0], ertbox_size[1], ertbox_size[2], nreal),
dtype=np.float32,
Expand Down Expand Up @@ -1235,7 +1271,7 @@ def calc_stats(
if zone_name not in disc_param_name_dict:
continue
for param_name in disc_param_name_dict[zone_name]:
logger.info(f"Property: {param_name}")
logger.info(f" Property: {param_name}")
all_values = np.ma.masked_all(
(ertbox_size[0], ertbox_size[1], ertbox_size[2], nreal),
dtype=np.int32,
Expand Down Expand Up @@ -1291,17 +1327,19 @@ def calc_stats(
sum_total_active = np.ma.sum(sum_active) / nreal
sum_total_code = np.ma.sum(number_of_cells) / nreal
fraction = sum_total_code / sum_total_active
txt1 = f"Average number of active cells: {sum_total_active}"
txt1 = (
f" Average number of active cells: {sum_total_active}"
)
logger.info(txt1)

txt2 = (
f"Average number of cells with facies "
f" Average number of cells with facies "
f"{facies_name} is {sum_total_code}"
)
logger.info(txt2)

txt3 = (
"Average estimated facies probability for facies "
" Average estimated facies probability for facies "
f"{facies_name}: {fraction}"
)
logger.info(txt3)
Expand Down Expand Up @@ -1338,7 +1376,7 @@ def calc_stats(
zone_code_names,
copy_to_geogrid_realization=copy_to_geogrid_realization,
)
txt4 = f"Sum facies volume fraction: {sum_fraction}"
txt4 = f" Sum facies volume fraction: {sum_fraction}"
logger.info(txt4)
else:
txt = (
Expand All @@ -1349,6 +1387,112 @@ def calc_stats(
logger.info(txt)


def calc_temporary_field_stats(
input_dict,
ens_path,
result_path,
ert_config_path,
ertbox_size,
):
(
ertbox_size,
nreal,
iter_list,
_,
_,
_,
use_population_stdev,
_,
_,
init_path,
param_list,
) = get_specifications(input_dict, ertbox_size, ert_config_path)

# Check if any need to continue to calculation
if not init_path or not param_list:
return

# Import realizations of temporary field parameters
for param_name in param_list:
for iteration in iter_list:
param_filename = param_name + ".roff"
if iteration == 0:
full_param_filename = init_path + "/" + param_filename
elif iteration == iter_list[-1]:
full_param_filename = param_filename
logger.info(f"Property: {param_name}")
all_values = np.ma.masked_all(
(ertbox_size[0], ertbox_size[1], ertbox_size[2], nreal),
dtype=np.float32,
)

number_of_skipped = 0
for real_number in range(nreal):
filepath = (
ens_path
/ Path(
"realization-" + str(real_number) + "/iter-" + str(iteration)
)
/ Path(full_param_filename)
)
print(f"File: {filepath} ")
if not filepath.exists():
txt = f" Skip non-existing realization: {real_number}"
logger.info(txt)
number_of_skipped += 1
continue
property = xtgeo.gridproperty_from_file(filepath, fformat="roff")
values = property.values
all_values[:, :, :, real_number] = values

# Calculate statistics
calc_mean = False
calc_stdev = False
mean_values_masked = None
stdev_values_masked = None
if number_of_skipped < nreal:
# Mean value
mean_values_masked = all_values.mean(axis=3)
calc_mean = True
if number_of_skipped < (nreal - 1):
# Std deviation
if use_population_stdev:
stdev_values_masked = all_values.std(axis=3, ddof=0)
else:
stdev_values_masked = all_values.std(axis=3, ddof=1)
calc_stdev = True

# Write results to result directory
# Fill masked values with 0
if calc_mean:
ertbox_mean_values = mean_values_masked.filled(fill_value=0.0)
name_mean = "mean_" + param_name
result_mean_file_path = result_path / Path(name_mean + ".roff")
xtgeo_ertbox_mean = xtgeo.GridProperty(
ncol=ertbox_size[0],
nrow=ertbox_size[1],
nlay=ertbox_size[2],
name=name_mean,
values=ertbox_mean_values,
)
logger.info(f" Write parameter: {name_mean}")
xtgeo_ertbox_mean.to_file(result_mean_file_path, fformat="roff")

if calc_stdev:
ertbox_stdev_values = stdev_values_masked.filled(fill_value=0.0)
name_stdev = "stdev_" + param_name
result_stdev_file_path = result_path / Path(name_stdev + ".roff")
xtgeo_ertbox_stdev = xtgeo.GridProperty(
ncol=ertbox_size[0],
nrow=ertbox_size[1],
nlay=ertbox_size[2],
name=name_stdev,
values=ertbox_stdev_values,
)
logger.info(f" Write parameter: {name_stdev}")
xtgeo_ertbox_stdev.to_file(result_stdev_file_path, fformat="roff")


def generate_script(
rms_load_script, ert_config_path, result_path, field_stat_config_file
):
Expand All @@ -1360,6 +1504,11 @@ def generate_script(
import yaml
import fmu.config.utilities as utils
# Edit this label to fit your case
LABEL = "drogon"
# -------- Usually no need to edit the code below to fit your case ----------
PRJ = project
GRIDNAME = "ERTBOX"
Expand All @@ -1374,8 +1523,6 @@ def generate_script(
RESULT_PATH = Path("{result_path}")
LABEL = "drogon"
def read_field_stat_config(config_file_name):
print(f"Read file: {{config_file_name}}")
with open(config_file_name, encoding="utf-8") as yml_file:
Expand Down
2 changes: 2 additions & 0 deletions tests/test_field_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,8 @@ def test_get_specification(
use_population_stdev,
param_name_dict,
disc_param_name_dict,
_,
_,
) = get_specifications(input_dict, ertbox_size, ert_config_path)
assert ertbox_size == reference_dict["ertbox_size"]
assert zone_names == reference_dict["use_zones"]
Expand Down

0 comments on commit b6f720e

Please sign in to comment.