Skip to content

Commit

Permalink
ENH: Add validation of required volume columns
Browse files Browse the repository at this point in the history
  • Loading branch information
tnatt committed Dec 15, 2024
1 parent 32cb406 commit 8b0772c
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/fmu/dataio/export/rms/inplace_volumes.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,58 @@ def _convert_table_from_legacy_to_standard_format(
table = self._add_missing_columns_to_table(table)
return self._set_table_column_order(table)

@staticmethod
def _get_required_volumetric_columns(has_oil: bool, has_gas: bool) -> list[str]:
"""
Get the required volumetric columns. If the table has any data from the 'oil'
zone a 'STOIIP' column is required. Similarly, if there is data from the 'gas'
zone, a 'GIIP' column is included.
"""
required_volumetric_columns = ["BULK", "PORV", "HCPV"]
if has_oil:
required_volumetric_columns.append("STOIIP")
if has_gas:
required_volumetric_columns.append("GIIP")

_logger.debug("Required columns are %s", required_volumetric_columns)
return required_volumetric_columns

def _validate_table(self) -> None:
"""
Validate that the final table with volumes is according to the standard
defined for the inplace_volumes product.
"""
_logger.debug("Validating the dataframe...")

has_oil = "oil" in self._dataframe[_FLUID_COLUMN].values
has_gas = "gas" in self._dataframe[_FLUID_COLUMN].values

# check that one of oil and gas fluids are present
if not (has_oil or has_gas):
raise RuntimeError(
"One or both 'oil' and 'gas' needs to be selected as 'Main types'"
"in the volumetric job. Please update and rerun the volumetric job "
"before export."
)

# create list of missing or non-defined required columns
missing_calculations = []
for col in self._get_required_volumetric_columns(has_oil, has_gas):
if col not in self._dataframe or self._dataframe[col].isna().all():
missing_calculations.append(col)

if missing_calculations:
raise RuntimeError(
f"Required calculations {missing_calculations} are missing "
f"in the volumetric table {self._volume_table_name}. Please update and "
"rerun the volumetric job before export."
)

def _export_volume_table(self) -> ExportResult:
"""Do the actual volume table export using dataio setup."""

self._validate_table()

edata = dio.ExportData(
config=self._config,
content="volumes",
Expand Down
128 changes: 128 additions & 0 deletions tests/test_export_rms/test_export_rms_volumetrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"ASSOCIATEDOIL",
]

EXPECTED_REQUIRED_VOLUMETRIC_COLUMNS = ["BULK", "PORV", "HCPV"]


@pytest.fixture(scope="package")
def voltable_legacy():
Expand Down Expand Up @@ -195,6 +197,132 @@ def test_convert_table_from_legacy_to_standard_format(
)


@pytest.mark.parametrize("required_col", EXPECTED_REQUIRED_VOLUMETRIC_COLUMNS)
def test_validate_table_required_col_missing(
mock_project_variable,
mocked_rmsapi_modules,
rmssetup_with_fmuconfig,
monkeypatch,
voltable_standard,
required_col,
):
"""Test that the job fails if a required volumetric column is missing"""

from fmu.dataio.export.rms.inplace_volumes import _ExportVolumetricsRMS

monkeypatch.chdir(rmssetup_with_fmuconfig)

instance = _ExportVolumetricsRMS(mock_project_variable, "Geogrid", "geogrid_vol")

df = voltable_standard.drop(columns=required_col)
monkeypatch.setattr(instance, "_dataframe", df)

with pytest.raises(RuntimeError, match="missing"):
instance._validate_table()


@pytest.mark.parametrize("required_col", EXPECTED_REQUIRED_VOLUMETRIC_COLUMNS)
def test_validate_table_required_col_has_nan(
mock_project_variable,
mocked_rmsapi_modules,
rmssetup_with_fmuconfig,
monkeypatch,
voltable_standard,
required_col,
):
"""Test that the job fails if a required volumetric column has nan values"""

from fmu.dataio.export.rms.inplace_volumes import _ExportVolumetricsRMS

monkeypatch.chdir(rmssetup_with_fmuconfig)

df = voltable_standard.copy()
df[required_col] = np.nan

instance = _ExportVolumetricsRMS(mock_project_variable, "Geogrid", "geogrid_vol")
monkeypatch.setattr(instance, "_dataframe", df)

with pytest.raises(RuntimeError, match="missing"):
instance._validate_table()


def test_validate_table_has_oil_or_gas(
mock_project_variable,
mocked_rmsapi_modules,
rmssetup_with_fmuconfig,
monkeypatch,
voltable_standard,
):
"""Test that the job fails if a required volumetric column has nan values"""

from fmu.dataio.export.rms.inplace_volumes import _ExportVolumetricsRMS

monkeypatch.chdir(rmssetup_with_fmuconfig)

df = voltable_standard.copy()
df = df[~df["FLUID"].isin(["oil", "gas"])]

instance = _ExportVolumetricsRMS(mock_project_variable, "Geogrid", "geogrid_vol")
monkeypatch.setattr(instance, "_dataframe", df)

with pytest.raises(RuntimeError, match="One or both 'oil' and 'gas'"):
instance._validate_table()


def test_validate_table_has_oil_and_stoiip(
mock_project_variable,
mocked_rmsapi_modules,
rmssetup_with_fmuconfig,
monkeypatch,
voltable_standard,
):
"""Test that the validation fails if oil columns are present but no STOIIP"""

from fmu.dataio.export.rms.inplace_volumes import _ExportVolumetricsRMS

monkeypatch.chdir(rmssetup_with_fmuconfig)

df = voltable_standard.copy()
df = df.drop(columns="STOIIP")

instance = _ExportVolumetricsRMS(mock_project_variable, "Geogrid", "geogrid_vol")
monkeypatch.setattr(instance, "_dataframe", df)

with pytest.raises(RuntimeError, match="missing"):
instance._validate_table()

# validation shoul pass when no oil columns are present
instance._dataframe = df[~(df["FLUID"] == "oil")]
instance._validate_table()


def test_validate_table_has_gas_and_giip(
mock_project_variable,
mocked_rmsapi_modules,
rmssetup_with_fmuconfig,
monkeypatch,
voltable_standard,
):
"""Test that the validations fails if gas columns are present but no GIIP"""

from fmu.dataio.export.rms.inplace_volumes import _ExportVolumetricsRMS

monkeypatch.chdir(rmssetup_with_fmuconfig)

df = voltable_standard.copy()
df = df.drop(columns="GIIP")

instance = _ExportVolumetricsRMS(mock_project_variable, "Geogrid", "geogrid_vol")
monkeypatch.setattr(instance, "_dataframe", df)

with pytest.raises(RuntimeError, match="missing"):
instance._validate_table()

# validation shoul pass when no gas columns are present
instance._dataframe = df[~(df["FLUID"] == "gas")]
instance._validate_table()


@inside_rms
def test_rms_volumetrics_export_config_missing(
mock_project_variable,
Expand Down

0 comments on commit 8b0772c

Please sign in to comment.