Skip to content

Commit

Permalink
Add new fipname option (equinor#748)
Browse files Browse the repository at this point in the history
* New fipname option

* Improved solution, fipname option (equinor#370)

* corrected a test, +1 column (equinor#370))

* Corrections and renamed option (rename2fipnum) (equinor#370)
  • Loading branch information
lilbe66 authored Oct 4, 2024
1 parent e9d6566 commit 107d6d1
Show file tree
Hide file tree
Showing 7 changed files with 7,123 additions and 31 deletions.
13 changes: 10 additions & 3 deletions docs/scripts/prtvol2csv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ The script will read numbers from the line with ``CURRENTLY IN PLACE`` in Eclips
====================================================================================================================================
Additionally, if the Eclipse DATA file includes::
Additionally, if the Eclipse DATA file includes

.. code-block:: none
RPTSOL
FIP=2 'FIPRESV' /
the PRT-file will also contain a table with pore volumes pr. phase and pr.
FIPNUM, which will be added to the exported table.
the PRT-file will also contain a table with pore volumes per phase and per FIPNUM,
which will be added to the exported table. FIPRESV will include reservoir volumes (RM3).

.. code-block:: none
Expand All @@ -56,6 +58,11 @@ FIPNUM, which will be added to the exported table.
: 2 : 79481140.: 0.: 79481140.: 0.: 0.:
===========================================================================================
If `FIP=3` in RPTSOL, the PRT file will also contain report of in-place volumes for any additional
FIP-vectors. Default is to export volumes per FIPNUM, but any FIP-vector can be specified
using the ``fipname`` option. By using the ``rename2fipnum`` option, the column name would be set to FIPNUM
in the csv-file for any FIP-vector, as required by ``webviz-subsurface`` plugin ``VolumetricAnalysis``.
This renaming is not needed for ``Webviz-Sumo``. An additional column with the actual FIPNAME is included for information.


Region and zone support
Expand Down
8 changes: 4 additions & 4 deletions src/subscript/config_jobs/PRTVOL2CSV
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
EXECUTABLE prtvol2csv


DEFAULT <DIR> share/results/volumes
DEFAULT <OUTPUTFILENAME> simulator_volume_fipnum.csv

DEFAULT <REGIONS> ""
DEFAULT <FIPNAME> "FIPNUM"

ARG_TYPE 0 STRING
ARG_TYPE 1 STRING
ARG_TYPE 2 STRING
ARG_TYPE 3 STRING
ARG_TYPE 4 STRING
ARG_TYPE 5 STRING

ARGLIST "--verbose" "--dir" <DIR> "--outputfilename" <OUTPUTFILENAME> "--yaml" <REGIONS> <DATAFILE>
ARGLIST "--verbose" "--dir" <DIR> "--outputfilename" <OUTPUTFILENAME> "--yaml" <REGIONS> "--rename2fipnum" "--fipname" <FIPNAME> <DATAFILE>

MIN_ARG 1
MAX_ARG 5
MAX_ARG 6
101 changes: 83 additions & 18 deletions src/subscript/prtvol2csv/prtvol2csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,36 @@
from subscript import __version__, getLogger

DESCRIPTION = """
Extract reservoir volumes pr FIPNUM from Eclipse PRT files and dump to CSV.
Extract in-place volumes per FIPNUM, or any FIP vector specified, from an
Eclipse PRT file and dump to CSV file.
If a yaml file is specified through options, it is possible to add columns
with region and zone information to each FIPNUM. The YAML file must contain
the keys "region2fipnum" and/or "zone2fipnum".
the keys "region2fipnum" and/or "zone2fipnum". A YAML file can only be used together
with FIPNUM, - not with any additional FIP vector.
"""

CATEGORY = "utility.eclipse"


EXAMPLES = """
.. code-block:: console
FORWARD_MODEL PRTVOL2CSV(<DATAFILE>=<ECLBASE>, <REGIONS>=regions.yml, <DIR>=., <OUTPUTFILENAME>=simulator_volume_fipnum.csv)
FORWARD_MODEL PRTVOL2CSV(<DATAFILE>=<ECLBASE>, <REGIONS>=regions.yml, <FIPNAME>=FIPNUM, <DIR>=., <OUTPUTFILENAME>=simulator_volume_fipnum.csv)
where ``ECLBASE`` is already defined in your ERT config, pointing to the Eclipse
basename relative to ``RUNPATH`` and ``regions.yml`` is a YAML file defining
the map from regions and/or zones to FIPNUM.
the map from regions and/or zones to FIPNUM. The YAML file could be omitted in the
FORWARD_MODEL and specified directly in the Webviz config file, if the REGIONS argument
is not given a default value in the forward model job configuration.
The ``FIPNAME`` argument is by default set to ``FIPNUM``, but any FIP-vector can be used.
Ensure the PRT file has volume reports for the additional FIP-vector.
By using the ``rename2fipnum`` option, the column name would be set to FIPNUM in
the csv-file for any FIP-vector, as required by ``webviz-subsurface`` plugin ``VolumetricAnalysis``.
This renaming is not needed for ``Webviz-Sumo``. An additional column with the actual
FIPNAME is included for information.
Using anything else than "." in the ``DIR`` argument is deprecated. To write to a CSV
file in a specific directory, add the path in the ``OUTPUTFILENAME`` argument.
Expand All @@ -57,13 +70,29 @@ def get_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
formatter_class=CustomFormatter, description=DESCRIPTION
)
parser.add_argument("DATAfile", type=str, help="Name of Eclipse DATA file")
parser.add_argument(
"DATAfile",
type=str,
help="Name of Eclipse or OPM Flow DATA file, PRT file or fileroot",
)
parser.add_argument(
"--outputfilename",
type=str,
help="CSV filename to write, including path. Directory must exist.",
default="simulator_volume_fipnum.csv", # FMU standard
)
parser.add_argument(
"--fipname",
type=str,
help="Specify FIP-name, for an additional FIP vector.",
default="FIPNUM",
)
parser.add_argument(
"--rename2fipnum",
action="store_true",
help="Rename the additional FIP vector to FIPNUM.",
required=False,
)
parser.add_argument(
"--yaml",
"--regions", # Deprecated option name
Expand Down Expand Up @@ -175,6 +204,10 @@ def currently_in_place_from_prt(
"""
inplace_df = res2df.fipreports.df(prt_file, fipname=fipname)

if inplace_df.empty:
logger.warning("The PRT file %s has no volume report for %s", prt_file, fipname)
return inplace_df

available_dates = inplace_df.sort_values("DATE")["DATE"].unique()
if date is None or date == "first":
date_str = available_dates[0]
Expand All @@ -194,13 +227,13 @@ def currently_in_place_from_prt(
["DATATYPE", "TO_REGION", "FIPNAME", "DATE"], axis="columns", inplace=True
)
inplace_df.set_index("REGION", inplace=True)
inplace_df.index.name = "FIPNUM"
inplace_df.index.name = fipname # Use "FIPNUM" if not handled by Webviz

logger.info("Extracted CURRENTLY IN PLACE from %s at date %s", prt_file, date_str)
return inplace_df


def reservoir_volumes_from_prt(prt_file: str) -> pd.DataFrame:
def reservoir_volumes_from_prt(prt_file: str, fipname: str = "FIPNUM") -> pd.DataFrame:
"""Extracts numbers from the table "RESERVOIR VOLUMES" in an Eclipse PRT
file, example table is::
Expand Down Expand Up @@ -233,9 +266,16 @@ def reservoir_volumes_from_prt(prt_file: str) -> pd.DataFrame:
table_found = (
False # State determining if current line is in our interesting table or not.
)
# The Reservoir Volume table is not tagged with the "FIPNAME", but will appear
# after the in-place volume table (see the "BALANCE" report) in the PRT file.
fipname_found = fipname == "FIPNUM" # found the corrent fipname, FIPNUM OK

with Path(prt_file).open(encoding="utf8") as f_handle:
for line in f_handle:
if start_matcher.search(line) is not None:
if line.startswith(" " + "BAL" + fipname[3:6]):
fipname_found = True
continue
if fipname_found and start_matcher.search(line) is not None:
table_found = True
continue
if table_found and line.strip().startswith("======================="):
Expand All @@ -253,7 +293,7 @@ def reservoir_volumes_from_prt(prt_file: str) -> pd.DataFrame:
continue
records.append(
{
"FIPNUM": int(line_split[0]),
fipname: int(line_split[0]),
"PORV_TOTAL": float(line_split[1]),
"HCPV_OIL": float(line_split[2]),
"WATPV_TOTAL": float(line_split[3]),
Expand All @@ -264,10 +304,12 @@ def reservoir_volumes_from_prt(prt_file: str) -> pd.DataFrame:

if not records:
logger.warning("No RESERVOIR VOLUMES table found in PRT file %s", prt_file)
logger.warning("Include RPTSOL <newline> FIP=2 'FIPRESV' in Eclipse DATA file")
logger.warning(
"Include RPTSOL with FIP=2 (or 3) and 'FIPRESV' in Eclipse DATA file"
)
return pd.DataFrame()

return pd.DataFrame(records).set_index("FIPNUM")
return pd.DataFrame(records).set_index(fipname)


def main() -> None:
Expand All @@ -292,22 +334,31 @@ def main() -> None:
logger.error("PRT-file %s does not exist", prt_file)
return

simvolumes_df = currently_in_place_from_prt(prt_file, "FIPNUM")
simvolumes_df = currently_in_place_from_prt(prt_file, args.fipname)
simvolumes_df.to_csv(Path(tablesdir) / args.outputfilename)
logger.info(
"Written CURRENTLY_IN_PLACE data to %s",
str(Path(tablesdir) / args.outputfilename),
)

resvolumes_df = reservoir_volumes_from_prt(prt_file)
resvolumes_df = reservoir_volumes_from_prt(prt_file, args.fipname)

fipmapper: Optional[FipMapper]
if args.yaml:
fipmapper = FipMapper(yamlfile=args.yaml, skipstring="Totals")
if args.fipname != "FIPNUM":
logger.error("Cannot use yaml file if fipname is different from FIPNUM")
return
else:
fipmapper = None

volumes = prtvol2df(simvolumes_df, resvolumes_df, fipmapper=fipmapper)
volumes = prtvol2df(
simvolumes_df,
resvolumes_df,
rename2fipnum=args.rename2fipnum,
fipmapper=fipmapper,
fipname=args.fipname,
)

volumes.to_csv(Path(tablesdir) / args.outputfilename)
logger.info("Written CSV file %s", str(Path(tablesdir) / args.outputfilename))
Expand All @@ -317,18 +368,32 @@ def prtvol2df(
simvolumes_df: pd.DataFrame,
resvolumes_df: pd.DataFrame,
fipmapper: Optional[FipMapper] = None,
fipname: str = "FIPNUM",
rename2fipnum: bool = False,
) -> pd.DataFrame:
"""
Concatenate two dataframes (with common index) horizontally,
and add REGION and ZONE parameter.
and if fipname="FIPNUM", add REGION and ZONE parameter.
"""
# Concatenate dataframes horizontally. Both are/must be indexed by FIPNUM:

# Remove extra empty 'regions' (from the reservoir volume table in .PRT)
# Concatenate dataframes horizontally. Both are/must be indexed by value
# of fipname (FIPNUM):
volumes = (
pd.concat([simvolumes_df, resvolumes_df], axis=1)
pd.concat([simvolumes_df, resvolumes_df[: len(simvolumes_df)]], axis=1)
.apply(pd.to_numeric)
.fillna(value=0.0)
)

# Rename the index to "FIPNUM", as required by webviz-subsurface, if requested
if rename2fipnum:
volumes.index = volumes.index.rename("FIPNUM")
else:
volumes.index = volumes.index.rename(fipname)

# Add new column with the actual FIPNAME, for info and traceability
volumes["FIPNAME"] = fipname

if fipmapper is not None:
if fipmapper.has_fip2region:
volumes["REGION"] = [
Expand All @@ -341,7 +406,7 @@ def prtvol2df(
for fipnum in volumes.index
]
if any(volumes.index < 1):
logger.warning("FIPNUM values should be 1 or larger")
logger.warning("%s values should be 1 or larger", fipname)
return volumes


Expand Down
Loading

0 comments on commit 107d6d1

Please sign in to comment.