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 16, 2024
1 parent 8ebbbb4 commit e82ce98
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 1 deletion.
44 changes: 43 additions & 1 deletion src/fmu/dataio/export/rms/inplace_volumes.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,47 @@ def _convert_table_from_legacy_to_standard_format(
table = self._add_missing_columns_to_table(table)
return self._set_table_column_order(table)

def _is_column_missing_in_table(self, column: str) -> bool:
"""Check if a column is present in the final dataframe and has values"""
return column not in self._dataframe or self._dataframe[column].isna().all()

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 ["BULK", "PORV", "HCPV"]:
if self._is_column_missing_in_table(col):
missing_calculations.append(col)

if has_oil and self._is_column_missing_in_table("STOIIP"):
missing_calculations.append("STOIIP")

if has_gas and self._is_column_missing_in_table("GIIP"):
missing_calculations.append("GIIP")

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."""

Expand All @@ -227,7 +268,8 @@ def _export_volume_table(self) -> ExportResult:
)

def export(self) -> ExportResult:
"""Export the volume table."""
"""Validate and export the volume table."""
self._validate_table()
return self._export_volume_table()


Expand Down
72 changes: 72 additions & 0 deletions tests/test_export_rms/test_export_rms_volumetrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,78 @@ def test_convert_table_from_legacy_to_standard_format(
)


@pytest.mark.parametrize("required_col", ["BULK", "PORV", "HCPV"])
def test_validate_table_required_col_missing(
exportvolumetrics, voltable_standard, required_col
):
"""Test that the job fails if a required volumetric column is missing"""

df = voltable_standard.drop(columns=required_col)
exportvolumetrics._dataframe = df

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


@pytest.mark.parametrize("required_col", ["BULK", "PORV", "HCPV"])
def test_validate_table_required_col_has_nan(
exportvolumetrics, voltable_standard, required_col
):
"""Test that the job fails if a required volumetric column has nan values"""

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

exportvolumetrics._dataframe = df

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


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

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

exportvolumetrics._dataframe = df

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


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

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

exportvolumetrics._dataframe = df

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

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


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

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

exportvolumetrics._dataframe = df

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

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


@inside_rms
def test_rms_volumetrics_export_config_missing(
mock_project_variable,
Expand Down

0 comments on commit e82ce98

Please sign in to comment.