diff --git a/src/fmu/dataio/export/rms/inplace_volumes.py b/src/fmu/dataio/export/rms/inplace_volumes.py index 30de69cbf..adc39bfaa 100644 --- a/src/fmu/dataio/export/rms/inplace_volumes.py +++ b/src/fmu/dataio/export/rms/inplace_volumes.py @@ -145,6 +145,43 @@ def _convert_table_from_rms_to_legacy_format(table: pd.DataFrame) -> pd.DataFram columns="REAL", errors="ignore" ) + @staticmethod + def _compute_water_zone_volumes_from_totals(table: pd.DataFrame) -> pd.DataFrame: + """ + Calculate 'water' zone volumes by subtracting HC-zone volumes from + Total volumes. + """ + _logger.debug("Computing water volumes from Totals...") + + total_suffix = "_TOTAL" + total_columns = [col for col in table.columns if col.endswith(total_suffix)] + + if not total_columns: + raise RuntimeError( + "Found no 'Totals' volumes in the table. Please ensure 'Totals' " + "are reported and rerun the volumetric job before export." + ) + + for total_col in total_columns: + volumetric_col = total_col.replace(total_suffix, "") + + # first set water volumes equal to the Total + water_volumes = table[total_col] + + # then subtract oil/gas zone data + for fluid in [_Fluid.OIL.value, _Fluid.GAS.value]: + fluid_zone_column = f"{volumetric_col}_{fluid}" + if fluid_zone_column in table: + water_volumes -= table[fluid_zone_column] + + # store the water volumes as column in table + table[f"{volumetric_col}_{_Fluid.WATER.value}"] = water_volumes + + # drop the total column once the water zone volumes have been added + table = table.drop(columns=total_col) + + return table + @staticmethod def _add_missing_columns_to_table(table: pd.DataFrame) -> pd.DataFrame: """Add columns with nan values if not present in table.""" @@ -170,10 +207,9 @@ def _transform_and_add_fluid_column_to_table( are renamed into 'BULK' and 'PORV' columns. To separate the data an additional FLUID column is added that indicates the type of fluid the row represents. """ - table_index = [col for col in _TABLE_INDEX_COLUMNS if col in table] tables = [] - for fluid in [_Fluid.GAS.value, _Fluid.OIL.value]: + for fluid in [_Fluid.GAS.value, _Fluid.OIL.value, _Fluid.WATER.value]: fluid_columns = [col for col in table.columns if col.endswith(f"_{fluid}")] if fluid_columns: fluid_table = table[table_index + fluid_columns].copy() @@ -196,6 +232,7 @@ def _convert_table_from_legacy_to_standard_format( product. The standard format has a fluid column, and all table_index and volumetric columns are present with a standard order in the table. """ + table = self._compute_water_zone_volumes_from_totals(table) table_index = [col for col in _TABLE_INDEX_COLUMNS if col in table] table = self._transform_and_add_fluid_column_to_table(table, table_index) table = self._add_missing_columns_to_table(table) diff --git a/tests/data/drogon/tabular/volumes/geogrid.csv b/tests/data/drogon/tabular/volumes/geogrid.csv index 2f10386e6..36cd6a5c7 100644 --- a/tests/data/drogon/tabular/volumes/geogrid.csv +++ b/tests/data/drogon/tabular/volumes/geogrid.csv @@ -335,3 +335,171 @@ oil,Volon,EastLowland,Calcite,,86379.79939277154,,0.0,0.0,0.0,,0.0, oil,Volon,EastLowland,Offshore,,0.0,,0.0,0.0,0.0,,0.0, oil,Volon,EastLowland,Lowershoreface,,0.0,,0.0,0.0,0.0,,0.0, oil,Volon,EastLowland,Uppershoreface,,0.0,,0.0,0.0,0.0,,0.0, +water,Valysar,WestLowland,Floodplain,,199635209.06231964,,19889504.858085632,,,,, +water,Valysar,WestLowland,Channel,,188904690.15197682,,49852644.8797493,,,,, +water,Valysar,WestLowland,Crevasse,,66498186.74765427,,13614114.21556282,,,,, +water,Valysar,WestLowland,Coal,,47005819.028200254,,0.0,,,,, +water,Valysar,WestLowland,Calcite,,0.0,,0.0,,,,, +water,Valysar,WestLowland,Offshore,,0.0,,0.0,,,,, +water,Valysar,WestLowland,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,WestLowland,Uppershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralSouth,Floodplain,,28174636.855486907,,2711703.3576335907,,,,, +water,Valysar,CentralSouth,Channel,,22735443.45432435,,6156691.954032898,,,,, +water,Valysar,CentralSouth,Crevasse,,9887763.792533554,,2015381.9916992192,,,,, +water,Valysar,CentralSouth,Coal,,4107955.788754794,,0.0,,,,, +water,Valysar,CentralSouth,Calcite,,0.0,,0.0,,,,, +water,Valysar,CentralSouth,Offshore,,0.0,,0.0,,,,, +water,Valysar,CentralSouth,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralSouth,Uppershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralNorth,Floodplain,,38746747.15721468,,3257848.738916397,,,,, +water,Valysar,CentralNorth,Channel,,20313542.091495283,,5319292.084007263,,,,, +water,Valysar,CentralNorth,Crevasse,,12964778.222036486,,2584124.102832794,,,,, +water,Valysar,CentralNorth,Coal,,14076425.203160832,,0.0,,,,, +water,Valysar,CentralNorth,Calcite,,0.0,,0.0,,,,, +water,Valysar,CentralNorth,Offshore,,0.0,,0.0,,,,, +water,Valysar,CentralNorth,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralNorth,Uppershoreface,,0.0,,0.0,,,,, +water,Valysar,NorthHorst,Floodplain,,8210484.753254818,,770498.3396244047,,,,, +water,Valysar,NorthHorst,Channel,,2578974.2676892485,,687172.2579650879,,,,, +water,Valysar,NorthHorst,Crevasse,,761616.8469049805,,157481.72686386108,,,,, +water,Valysar,NorthHorst,Coal,,2037701.0165579505,,0.0,,,,, +water,Valysar,NorthHorst,Calcite,,0.0,,0.0,,,,, +water,Valysar,NorthHorst,Offshore,,0.0,,0.0,,,,, +water,Valysar,NorthHorst,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,NorthHorst,Uppershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralRamp,Floodplain,,1061413.6835421966,,82375.53680419922,,,,, +water,Valysar,CentralRamp,Channel,,689661.5301341028,,178625.55529785156,,,,, +water,Valysar,CentralRamp,Crevasse,,68555.0179801248,,13122.741760253906,,,,, +water,Valysar,CentralRamp,Coal,,133394.72849460552,,0.0,,,,, +water,Valysar,CentralRamp,Calcite,,0.0,,0.0,,,,, +water,Valysar,CentralRamp,Offshore,,0.0,,0.0,,,,, +water,Valysar,CentralRamp,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralRamp,Uppershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralHorst,Floodplain,,8923441.539376646,,737789.9258155823,,,,, +water,Valysar,CentralHorst,Channel,,3874852.635276627,,1028251.5404396057,,,,, +water,Valysar,CentralHorst,Crevasse,,1046442.6939407401,,212083.40999984718,,,,, +water,Valysar,CentralHorst,Coal,,4122777.8013486303,,0.0,,,,, +water,Valysar,CentralHorst,Calcite,,0.0,,0.0,,,,, +water,Valysar,CentralHorst,Offshore,,0.0,,0.0,,,,, +water,Valysar,CentralHorst,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,CentralHorst,Uppershoreface,,0.0,,0.0,,,,, +water,Valysar,EastLowland,Floodplain,,138781101.69286424,,10602248.395273207,,,,, +water,Valysar,EastLowland,Channel,,57556967.579790935,,14855282.31137085,,,,, +water,Valysar,EastLowland,Crevasse,,32904003.154506125,,6366257.547336578,,,,, +water,Valysar,EastLowland,Coal,,33782575.87539426,,0.0,,,,, +water,Valysar,EastLowland,Calcite,,0.0,,0.0,,,,, +water,Valysar,EastLowland,Offshore,,0.0,,0.0,,,,, +water,Valysar,EastLowland,Lowershoreface,,0.0,,0.0,,,,, +water,Valysar,EastLowland,Uppershoreface,,0.0,,0.0,,,,, +water,Therys,WestLowland,Floodplain,,0.0,,0.0,,,,, +water,Therys,WestLowland,Channel,,0.0,,0.0,,,,, +water,Therys,WestLowland,Crevasse,,0.0,,0.0,,,,, +water,Therys,WestLowland,Coal,,0.0,,0.0,,,,, +water,Therys,WestLowland,Calcite,,53179530.480960734,,0.0,,,,, +water,Therys,WestLowland,Offshore,,224308300.77785882,,27138859.65850281,,,,, +water,Therys,WestLowland,Lowershoreface,,157251330.06353703,,40617617.03001963,,,,, +water,Therys,WestLowland,Uppershoreface,,111674468.20940188,,34788357.914711,,,,, +water,Therys,CentralSouth,Floodplain,,0.0,,0.0,,,,, +water,Therys,CentralSouth,Channel,,0.0,,0.0,,,,, +water,Therys,CentralSouth,Crevasse,,0.0,,0.0,,,,, +water,Therys,CentralSouth,Coal,,0.0,,0.0,,,,, +water,Therys,CentralSouth,Calcite,,1570953.4599857288,,0.0,,,,, +water,Therys,CentralSouth,Offshore,,5148527.537121184,,480000.0074880719,,,,, +water,Therys,CentralSouth,Lowershoreface,,5091024.065522364,,1325732.81913805,,,,, +water,Therys,CentralSouth,Uppershoreface,,3061684.296614888,,994067.8604154126,,,,, +water,Therys,CentralNorth,Floodplain,,0.0,,0.0,,,,, +water,Therys,CentralNorth,Channel,,0.0,,0.0,,,,, +water,Therys,CentralNorth,Crevasse,,0.0,,0.0,,,,, +water,Therys,CentralNorth,Coal,,0.0,,0.0,,,,, +water,Therys,CentralNorth,Calcite,,8246046.31052004,,0.0,,,,, +water,Therys,CentralNorth,Offshore,,30136718.68757325,,2900918.633241721,,,,, +water,Therys,CentralNorth,Lowershoreface,,20880188.429421045,,5023761.500228882,,,,, +water,Therys,CentralNorth,Uppershoreface,,12440213.544097727,,4028126.994163514,,,,, +water,Therys,NorthHorst,Floodplain,,0.0,,0.0,,,,, +water,Therys,NorthHorst,Channel,,0.0,,0.0,,,,, +water,Therys,NorthHorst,Crevasse,,0.0,,0.0,,,,, +water,Therys,NorthHorst,Coal,,0.0,,0.0,,,,, +water,Therys,NorthHorst,Calcite,,3910879.9040033277,,0.0,,,,, +water,Therys,NorthHorst,Offshore,,8525384.040342128,,898389.3357550651,,,,, +water,Therys,NorthHorst,Lowershoreface,,1813954.4037235645,,448523.21085357666,,,,, +water,Therys,NorthHorst,Uppershoreface,,2230344.651985049,,726788.3869018554,,,,, +water,Therys,CentralRamp,Floodplain,,0.0,,0.0,,,,, +water,Therys,CentralRamp,Channel,,0.0,,0.0,,,,, +water,Therys,CentralRamp,Crevasse,,0.0,,0.0,,,,, +water,Therys,CentralRamp,Coal,,0.0,,0.0,,,,, +water,Therys,CentralRamp,Calcite,,14269.20473185298,,0.0,,,,, +water,Therys,CentralRamp,Offshore,,570056.6082884455,,42336.00001788139,,,,, +water,Therys,CentralRamp,Lowershoreface,,573928.800745388,,133559.80555534363,,,,, +water,Therys,CentralRamp,Uppershoreface,,283942.140126402,,93575.89129638672,,,,, +water,Therys,CentralHorst,Floodplain,,0.0,,0.0,,,,, +water,Therys,CentralHorst,Channel,,0.0,,0.0,,,,, +water,Therys,CentralHorst,Crevasse,,0.0,,0.0,,,,, +water,Therys,CentralHorst,Coal,,0.0,,0.0,,,,, +water,Therys,CentralHorst,Calcite,,1873912.9772147671,,0.0,,,,, +water,Therys,CentralHorst,Offshore,,4164290.322972057,,413992.2520942539,,,,, +water,Therys,CentralHorst,Lowershoreface,,7019327.266154291,,1655530.3278546333,,,,, +water,Therys,CentralHorst,Uppershoreface,,4653060.394801656,,1524199.657714963,,,,, +water,Therys,EastLowland,Floodplain,,0.0,,0.0,,,,, +water,Therys,EastLowland,Channel,,0.0,,0.0,,,,, +water,Therys,EastLowland,Crevasse,,0.0,,0.0,,,,, +water,Therys,EastLowland,Coal,,0.0,,0.0,,,,, +water,Therys,EastLowland,Calcite,,7565198.396226491,,0.0,,,,, +water,Therys,EastLowland,Offshore,,32971054.08148795,,2403078.7679725736,,,,, +water,Therys,EastLowland,Lowershoreface,,42226056.55160797,,9751004.178666055,,,,, +water,Therys,EastLowland,Uppershoreface,,30247661.497023392,,9434800.083554983,,,,, +water,Volon,WestLowland,Floodplain,,151553410.404796,,13848884.900240175,,,,, +water,Volon,WestLowland,Channel,,314039375.983029,,76394654.75561242,,,,, +water,Volon,WestLowland,Crevasse,,0.0,,0.0,,,,, +water,Volon,WestLowland,Coal,,0.0,,0.0,,,,, +water,Volon,WestLowland,Calcite,,42194832.373705655,,0.0,,,,, +water,Volon,WestLowland,Offshore,,0.0,,0.0,,,,, +water,Volon,WestLowland,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,WestLowland,Uppershoreface,,0.0,,0.0,,,,, +water,Volon,CentralSouth,Floodplain,,50301143.083524644,,4752792.43396759,,,,, +water,Volon,CentralSouth,Channel,,111281241.46517287,,27250731.639530182,,,,, +water,Volon,CentralSouth,Crevasse,,0.0,,0.0,,,,, +water,Volon,CentralSouth,Coal,,0.0,,0.0,,,,, +water,Volon,CentralSouth,Calcite,,13374219.834380861,,0.0,,,,, +water,Volon,CentralSouth,Offshore,,0.0,,0.0,,,,, +water,Volon,CentralSouth,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,CentralSouth,Uppershoreface,,0.0,,0.0,,,,, +water,Volon,CentralNorth,Floodplain,,13437653.734824093,,1219808.1165828705,,,,, +water,Volon,CentralNorth,Channel,,18540833.941328164,,4579542.983924866,,,,, +water,Volon,CentralNorth,Crevasse,,0.0,,0.0,,,,, +water,Volon,CentralNorth,Coal,,0.0,,0.0,,,,, +water,Volon,CentralNorth,Calcite,,2912524.102400574,,0.0,,,,, +water,Volon,CentralNorth,Offshore,,0.0,,0.0,,,,, +water,Volon,CentralNorth,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,CentralNorth,Uppershoreface,,0.0,,0.0,,,,, +water,Volon,NorthHorst,Floodplain,,2485998.1940900474,,220445.77733993536,,,,, +water,Volon,NorthHorst,Channel,,5144868.677435892,,1311122.0843620305,,,,, +water,Volon,NorthHorst,Crevasse,,0.0,,0.0,,,,, +water,Volon,NorthHorst,Coal,,0.0,,0.0,,,,, +water,Volon,NorthHorst,Calcite,,755851.579945738,,0.0,,,,, +water,Volon,NorthHorst,Offshore,,0.0,,0.0,,,,, +water,Volon,NorthHorst,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,NorthHorst,Uppershoreface,,0.0,,0.0,,,,, +water,Volon,CentralRamp,Floodplain,,1002797.0335718896,,106327.63387680054,,,,, +water,Volon,CentralRamp,Channel,,2912622.8234018395,,755271.9564285278,,,,, +water,Volon,CentralRamp,Crevasse,,0.0,,0.0,,,,, +water,Volon,CentralRamp,Coal,,0.0,,0.0,,,,, +water,Volon,CentralRamp,Calcite,,183954.78222594503,,0.0,,,,, +water,Volon,CentralRamp,Offshore,,0.0,,0.0,,,,, +water,Volon,CentralRamp,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,CentralRamp,Uppershoreface,,0.0,,0.0,,,,, +water,Volon,CentralHorst,Floodplain,,14479252.611059882,,1352125.556652069,,,,, +water,Volon,CentralHorst,Channel,,21087337.78153704,,5291756.395442961,,,,, +water,Volon,CentralHorst,Crevasse,,0.0,,0.0,,,,, +water,Volon,CentralHorst,Coal,,0.0,,0.0,,,,, +water,Volon,CentralHorst,Calcite,,2670829.178936201,,0.0,,,,, +water,Volon,CentralHorst,Offshore,,0.0,,0.0,,,,, +water,Volon,CentralHorst,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,CentralHorst,Uppershoreface,,0.0,,0.0,,,,, +water,Volon,EastLowland,Floodplain,,44700188.399142474,,3830575.4531288147,,,,, +water,Volon,EastLowland,Channel,,112391110.29544623,,26596352.009635925,,,,, +water,Volon,EastLowland,Crevasse,,0.0,,0.0,,,,, +water,Volon,EastLowland,Coal,,0.0,,0.0,,,,, +water,Volon,EastLowland,Calcite,,14198059.664785597,,0.0,,,,, +water,Volon,EastLowland,Offshore,,0.0,,0.0,,,,, +water,Volon,EastLowland,Lowershoreface,,0.0,,0.0,,,,, +water,Volon,EastLowland,Uppershoreface,,0.0,,0.0,,,,, diff --git a/tests/test_export_rms/test_export_rms_volumetrics.py b/tests/test_export_rms/test_export_rms_volumetrics.py index c0c531812..714376efa 100644 --- a/tests/test_export_rms/test_export_rms_volumetrics.py +++ b/tests/test_export_rms/test_export_rms_volumetrics.py @@ -142,31 +142,32 @@ def test_convert_table_from_legacy_to_standard_format( # check that the fluid column exists and contains oil and gas assert _FLUID_COLUMN in exported_table - assert set(exported_table[_FLUID_COLUMN].unique()) == {"oil", "gas"} + assert set(exported_table[_FLUID_COLUMN].unique()) == {"oil", "gas", "water"} # check the column order assert list(exported_table.columns) == EXPECTED_COLUMN_ORDER # check that the legacy format and the standard format gives # the same sum for volumetric columns + hc_filter = exported_table["FLUID"].isin(["oil", "gas"]) assert np.isclose( - exported_table["STOIIP"].sum(), + exported_table[hc_filter]["STOIIP"].sum(), voltable_legacy["STOIIP_OIL"].sum(), ) assert np.isclose( - exported_table["GIIP"].sum(), + exported_table[hc_filter]["GIIP"].sum(), voltable_legacy["GIIP_GAS"].sum(), ) assert np.isclose( - exported_table["BULK"].sum(), + exported_table[hc_filter]["BULK"].sum(), (voltable_legacy["BULK_OIL"] + voltable_legacy["BULK_GAS"]).sum(), ) assert np.isclose( - exported_table["PORV"].sum(), + exported_table[hc_filter]["PORV"].sum(), (voltable_legacy["PORV_OIL"] + voltable_legacy["PORV_GAS"]).sum(), ) assert np.isclose( - exported_table["HCPV"].sum(), + exported_table[hc_filter]["HCPV"].sum(), (voltable_legacy["HCPV_OIL"] + voltable_legacy["HCPV_GAS"]).sum(), )