Skip to content

Commit

Permalink
Replace ecl with resdata (#460)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanSava committed Nov 14, 2023
1 parent 7d9a800 commit 798ee62
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 82 deletions.
68 changes: 30 additions & 38 deletions ecl2df/eclfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
except ImportError:
HAVE_OPM = False

from ecl import EclFileFlagEnum
from ecl.eclfile import EclFile
from ecl.grid import EclGrid
from ecl.summary import EclSum
from resdata.grid import Grid
from resdata.rd_util import FileMode
from resdata.resfile import ResdataFile
from resdata.summary import Summary

from ecl2df import common

Expand Down Expand Up @@ -44,7 +44,7 @@ class EclFiles(object):
Class for holding an Eclipse deck with result files
Exists only for convenience, so that loading of
EclFile/EclSum objects is easy for users, and with
ResdataFile/Summary objects is easy for users, and with
caching if wanted.
Various functions that needs some of the Eclipse output
Expand All @@ -68,14 +68,14 @@ def __init__(self, eclbase):
self._eclbase = eclbase

# Set class variables to None
self._egridfile = None # Should be EclFile
self._initfile = None # Should be EclFile
self._eclsum = None # Should be EclSum
self._egridfile = None # Should be ResdataFile
self._initfile = None # Should be ResdataFile
self._eclsum = None # Should be Summary

self._egrid = None # Should be EclGrid
self._egrid = None # Should be Grid

self._rstfile = None # EclFile
self._rftfile = None # EclFile
self._rstfile = None # ResdataFile
self._rftfile = None # ResdataFile

self._deck = None

Expand Down Expand Up @@ -111,20 +111,20 @@ def file2deck(filename: Union[str, Path]) -> "opm.libopmcommon_python.Deck":
"""Try to convert standalone files into opm.io Deck objects"""
return EclFiles.str2deck(Path(filename).read_text(encoding="utf-8"))

def get_egrid(self) -> EclGrid:
"""Find and return EGRID file as an EclGrid object"""
def get_egrid(self) -> Grid:
"""Find and return EGRID file as an Grid object"""
if not self._egrid:
egridfilename = self._eclbase + ".EGRID"
if not Path(egridfilename).is_file():
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), egridfilename
)
logger.info("Opening grid data from EGRID file: %s", egridfilename)
self._egrid = EclGrid(egridfilename)
self._egrid = Grid(egridfilename)
return self._egrid

def get_egridfile(self) -> EclFile:
"""Find and return the EGRID file as a EclFile object
def get_egridfile(self) -> ResdataFile:
"""Find and return the EGRID file as a ResdataFile object
This gives access to data vectors defined on the grid."""
if not self._egridfile:
Expand All @@ -134,15 +134,13 @@ def get_egridfile(self) -> EclFile:
errno.ENOENT, os.strerror(errno.ENOENT), egridfilename
)
logger.info("Opening data vectors from EGRID file: %s", egridfilename)
self._egridfile = EclFile(
egridfilename, flags=EclFileFlagEnum.ECL_FILE_CLOSE_STREAM
)
self._egridfile = ResdataFile(egridfilename, flags=FileMode.CLOSE_STREAM)

return self._egridfile

def get_eclsum(self, include_restart: bool = True) -> EclSum:
def get_eclsum(self, include_restart: bool = True) -> Summary:
"""Find and return the summary file and
return as EclSum object
return as Summary object
Args:
include_restart: Sent to libecl for whether restart files
Expand All @@ -155,49 +153,43 @@ def get_eclsum(self, include_restart: bool = True) -> EclSum:
errno.ENOENT, os.strerror(errno.ENOENT), smryfilename
)
logger.info("Opening UNSMRY file: %s", smryfilename)
self._eclsum = EclSum(smryfilename, include_restart=include_restart)
self._eclsum = Summary(smryfilename, include_restart=include_restart)
return self._eclsum

def get_initfile(self) -> EclFile:
"""Find and return the INIT file as an EclFile object"""
def get_initfile(self) -> ResdataFile:
"""Find and return the INIT file as an ResdataFile object"""
if not self._initfile:
initfilename = self._eclbase + ".INIT"
if not Path(initfilename).is_file():
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), initfilename
)
logger.info("Opening INIT file: %s", initfilename)
self._initfile = EclFile(
initfilename, flags=EclFileFlagEnum.ECL_FILE_CLOSE_STREAM
)
self._initfile = ResdataFile(initfilename, flags=FileMode.CLOSE_STREAM)
return self._initfile

def get_rftfile(self) -> EclFile:
"""Find and return the RFT file as an EclFile object"""
def get_rftfile(self) -> ResdataFile:
"""Find and return the RFT file as an ResdataFile object"""
if not self._rftfile:
rftfilename = self._eclbase + ".RFT"
if not Path(rftfilename).is_file():
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), rftfilename
)
logger.info("Opening RFT file: %s", rftfilename)
self._rftfile = EclFile(
rftfilename, flags=EclFileFlagEnum.ECL_FILE_CLOSE_STREAM
)
self._rftfile = ResdataFile(rftfilename, flags=FileMode.CLOSE_STREAM)
return self._rftfile

def get_rstfile(self) -> EclFile:
"""Find and return the UNRST file as an EclFile object"""
def get_rstfile(self) -> ResdataFile:
"""Find and return the UNRST file as an ResdataFile object"""
if not self._rstfile:
rstfilename = self._eclbase + ".UNRST"
if not Path(rstfilename).is_file():
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), rstfilename
)
logger.info("Opening RST file: %s", rstfilename)
self._rstfile = EclFile(
rstfilename, flags=EclFileFlagEnum.ECL_FILE_CLOSE_STREAM
)
self._rstfile = ResdataFile(rstfilename, flags=FileMode.CLOSE_STREAM)
return self._rstfile

def get_rstfilename(self) -> str:
Expand All @@ -214,7 +206,7 @@ def close(self) -> None:
for this function."""
self._egridfile = None
self._initfile = None
# This is necessary for garbage collection to close the EclSum file:
# This is necessary for garbage collection to close the Summary file:
self._eclsum = None
self._rstfile = None
self._rftfile = None
Expand Down
6 changes: 3 additions & 3 deletions ecl2df/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import pandas as pd
import pyarrow
import pyarrow.feather
from ecl.eclfile import EclFile
from resdata.resfile import ResdataFile

from ecl2df import __version__, common, getLogger_ecl2csv

Expand All @@ -33,7 +33,7 @@

def get_available_rst_dates(eclfiles: EclFiles) -> List[datetime.date]:
"""Return a list of datetime objects for the available dates in the RST file"""
report_indices = EclFile.file_report_list(eclfiles.get_rstfilename())
report_indices = ResdataFile.file_report_list(eclfiles.get_rstfilename())
logger.info(
"Restart report indices (count %s): %s",
str(len(report_indices)),
Expand Down Expand Up @@ -307,7 +307,7 @@ def gridgeometry2df(

logger.info("Extracting grid geometry from %s", str(egrid_file))
index_frame = grid.export_index(active_only=True)
ijk = index_frame.values[:, 0:3] + 1 # ijk from ecl.grid is off by one
ijk = index_frame.values[:, 0:3] + 1 # ijk from resdata.grid is off by one

xyz = grid.export_position(index_frame)
vol = grid.export_volume(index_frame)
Expand Down
16 changes: 8 additions & 8 deletions ecl2df/rft.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import numpy as np
import pandas as pd
from ecl.eclfile import EclFile
from resdata.resfile import ResdataFile

from ecl2df import getLogger_ecl2csv

Expand Down Expand Up @@ -60,9 +60,9 @@
}


def _rftrecords2df(rftfile: EclFile) -> pd.DataFrame:
def _rftrecords2df(rftfile: ResdataFile) -> pd.DataFrame:
"""Construct a dataframe just for navigation on the RFT records,
from the attribute 'headers' in EclFile object constructed from the
from the attribute 'headers' in ResdataFile object constructed from the
binary RFT file
The dataframe will consist of the columns and with example data:
Expand All @@ -80,7 +80,7 @@ def _rftrecords2df(rftfile: EclFile) -> pd.DataFrame:
rftfile[89] = EclKW(size=14, name="SWAT", ...)
Args:
rftfile (EclFile)
rftfile (ResdataFile)
"""
nav_df = pd.DataFrame(rftfile.headers)
nav_df.columns = ["recordname", "recordlength", "recordtype"]
Expand All @@ -104,14 +104,14 @@ def _rftrecords2df(rftfile: EclFile) -> pd.DataFrame:
return nav_df.reset_index()


def rftrecords(rftfile: EclFile) -> Iterable[Dict[str, Any]]:
"""Generator for looping over RFT records in a EclFile object.
def rftrecords(rftfile: ResdataFile) -> Iterable[Dict[str, Any]]:
"""Generator for looping over RFT records in a ResdataFile object.
Each returned RFT record is represented as a dict with the keys:
headers: pd.DataFrame, indexed by recordname
Args:
EclFile made from a binary RFT file.
ResdataFile made from a binary RFT file.
"""
navigation_frame = _rftrecords2df(rftfile)
for timeindex, headers in navigation_frame.groupby("timeindex"):
Expand All @@ -138,7 +138,7 @@ def rftrecords(rftfile: EclFile) -> Iterable[Dict[str, Any]]:


def get_con_seg_data(
rftrecord: Dict[str, Any], rftfile: EclFile, datatype: str
rftrecord: Dict[str, Any], rftfile: ResdataFile, datatype: str
) -> pd.DataFrame:
"""
Build a dataframe of CON* or SEG* data for a specific RFT record,
Expand Down
Loading

0 comments on commit 798ee62

Please sign in to comment.