diff --git a/pyproject.toml b/pyproject.toml index eef52a957..fcf5456c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ classifiers = [ dynamic = ["version"] dependencies = [ "configsuite", - "ecl", + "resdata", "ecl2df", "ert>=2.38.0b7", "fmu-tools", diff --git a/src/subscript/co2_containment/co2_calculation.py b/src/subscript/co2_containment/co2_calculation.py index 5d96c2be1..c98302502 100644 --- a/src/subscript/co2_containment/co2_calculation.py +++ b/src/subscript/co2_containment/co2_calculation.py @@ -5,8 +5,8 @@ import numpy as np import xtgeo -from ecl.eclfile import EclFile -from ecl.grid import EclGrid +from resdata.grid import Grid +from resdata.resfile import ResdataFile DEFAULT_CO2_MOLAR_MASS = 44.0 DEFAULT_WATER_MOLAR_MASS = 18.0 @@ -235,12 +235,12 @@ class Co2Data: zone: Optional[np.ndarray] = None -def _try_prop(unrst: EclFile, prop_name: str): +def _try_prop(unrst: ResdataFile, prop_name: str): """ - Function to determine if a property (prop_name) is part of an EclFile (unrst) + Function to determine if a property (prop_name) is part of an ResdataFile (unrst) Args: - unrst (EclFile): EclFile to fetch property names from + unrst (ResdataFile): ResdataFile to fetch property names from prop_name (str): The property name to be searched in unrst Returns: @@ -255,14 +255,14 @@ def _try_prop(unrst: EclFile, prop_name: str): def _read_props( - unrst: EclFile, + unrst: ResdataFile, prop_names: List, ) -> dict: """ - Reads the properties in prop_names from an EclFile named unrst + Reads the properties in prop_names from an ResdataFile named unrst Args: - unrst (EclFile): EclFile to read prop_names from + unrst (ResdataFile): ResdataFile to read prop_names from prop_names (List): List with property names to be read Returns: @@ -275,14 +275,14 @@ def _read_props( def _fetch_properties( - unrst: EclFile, properties_to_extract: List + unrst: ResdataFile, properties_to_extract: List ) -> Tuple[Dict[str, Dict[str, List[np.ndarray]]], List[str]]: """ - Fetches the properties in properties_to_extract from an EclFile + Fetches the properties in properties_to_extract from an ResdataFile named unrst Args: - unrst (EclFile): EclFile to fetch properties_to_extract from + unrst (ResdataFile): ResdataFile to fetch properties_to_extract from properties_to_extract: List with property names to be fetched Returns: @@ -362,7 +362,7 @@ def _extract_source_data( ) -> SourceData: # pylint: disable-msg=too-many-locals """ - Extracts the properties in properties_to_extract from EclGrid files + Extracts the properties in properties_to_extract from Grid files Args: grid_file (str): Path to EGRID-file @@ -376,9 +376,9 @@ def _extract_source_data( """ print("Start extracting source data") - grid = EclGrid(grid_file) - unrst = EclFile(unrst_file) - init = EclFile(init_file) + grid = Grid(grid_file) + unrst = ResdataFile(unrst_file) + init = ResdataFile(init_file) properties, dates = _fetch_properties(unrst, properties_to_extract) print("Done fetching properties") diff --git a/src/subscript/restartthinner/restartthinner.py b/src/subscript/restartthinner/restartthinner.py index be52db99a..2ad3c8af0 100644 --- a/src/subscript/restartthinner/restartthinner.py +++ b/src/subscript/restartthinner/restartthinner.py @@ -10,7 +10,7 @@ import numpy import pandas -from ecl.eclfile import EclFile +from resdata.resfile import ResdataFile from subscript import __version__ @@ -26,8 +26,8 @@ """ -def find_libecl_app(toolname: str) -> str: - """Locate path of apps in libecl. +def find_resdata_app(toolname: str) -> str: + """Locate path of apps in resdata. These have varying suffixes due through the history of libecl Makefiles. @@ -61,10 +61,10 @@ def date_slicer(slicedates: list, restartdates: list, restartindices: list) -> d return slicedatemap -def ecl_repacker(rstfilename: str, slicerstindices: list, quiet: bool) -> None: +def rd_repacker(rstfilename: str, slicerstindices: list, quiet: bool) -> None: """ Wrapper for ecl_unpack.x and ecl_pack.x utilities. These - utilities are from libecl. + utilities are from resdata. First unpacking a UNRST file, then deleting dates the dont't want, then pack the remainding files into a new UNRST file @@ -79,11 +79,11 @@ def ecl_repacker(rstfilename: str, slicerstindices: list, quiet: bool) -> None: out = "" # Error early if libecl tools are not available try: - find_libecl_app("ecl_unpack") - find_libecl_app("ecl_pack") + find_resdata_app("rd_unpack") + find_resdata_app("rd_pack") except IOError: sys.exit( - "ERROR: ecl_unpack.x and/or ecl_pack.x not found.\n" + "ERROR: rd_unpack.x and/or rd_pack.x not found.\n" "These tools are required and must be installed separately" ) @@ -99,13 +99,13 @@ def ecl_repacker(rstfilename: str, slicerstindices: list, quiet: bool) -> None: ) os.chdir(tempdir) os.system( - find_libecl_app("ecl_unpack") + " " + os.path.basename(rstfilename) + out + find_resdata_app("rd_unpack") + " " + os.path.basename(rstfilename) + out ) unpackedfiles = glob.glob("*.X*") for file in unpackedfiles: if int(file.split(".X")[1]) not in slicerstindices: os.remove(file) - os.system(find_libecl_app("ecl_pack") + " *.X*" + out) + os.system(find_resdata_app("rd_pack") + " *.X*" + out) # We are inside the tmp directory, move file one step up: os.rename( os.path.join(os.getcwd(), os.path.basename(rstfilename)), @@ -120,7 +120,7 @@ def get_restart_indices(rstfilename: str) -> list: """Extract a list of RST indices for a filename""" if Path(rstfilename).exists(): # This function segfaults if file does not exist - return EclFile.file_report_list(str(rstfilename)) + return ResdataFile.file_report_list(str(rstfilename)) raise FileNotFoundError(f"{rstfilename} not found") @@ -134,7 +134,7 @@ def restartthinner( """ Thin an existing UNRST file to selected number of restarts. """ - rst = EclFile(filename) + rst = ResdataFile(filename) restart_indices = get_restart_indices(filename) restart_dates = [ rst.iget_restart_sim_time(index) for index in range(0, len(restart_indices)) @@ -177,7 +177,7 @@ def restartthinner( if not quiet: print(f"Info: Backing up {filename} to {backupname}") shutil.copyfile(filename, backupname) - ecl_repacker(filename, slicerstindices, quiet) + rd_repacker(filename, slicerstindices, quiet) print(f"Written to {filename}") diff --git a/src/subscript/sector2fluxnum/flux_obj.py b/src/subscript/sector2fluxnum/flux_obj.py index 7857158a3..78a644761 100644 --- a/src/subscript/sector2fluxnum/flux_obj.py +++ b/src/subscript/sector2fluxnum/flux_obj.py @@ -1,9 +1,9 @@ import os import sys -from ecl import EclDataType -from ecl.eclfile import EclKW -from ecl.grid import EclRegion +from resdata import ResDataType +from resdata.grid import ResdataRegion +from resdata.resfile import ResdataKW from subscript.sector2fluxnum import flux_util @@ -20,9 +20,9 @@ def __init__(self, grid): Creates a non-initialized FLUXNUM keyword """ - int_type = EclDataType.ECL_INT + int_type = ResDataType.RD_INT self.grid = grid - self.fluxnum_kw = EclKW("FLUXNUM", grid.getGlobalSize(), int_type) + self.fluxnum_kw = ResdataKW("FLUXNUM", grid.getGlobalSize(), int_type) self.included_wells = [] self.dummy_lgr_cell = [] self.dummy_lgr_well = [] @@ -44,7 +44,7 @@ def set_inner_region(self): Initializes inner region used to define the FLUXNUM """ - self.inner_region = EclRegion(self.grid, False) + self.inner_region = ResdataRegion(self.grid, False) self.inner_region.select_all() def set_lgr_box_region(self, i, j, k): @@ -54,7 +54,7 @@ def set_lgr_box_region(self, i, j, k): Only works for Box regions """ - self.lgr_region = EclRegion(self.grid, False) + self.lgr_region = ResdataRegion(self.grid, False) ijk_list = flux_util.unpack_ijk(i, j, k) # Drags lgr boundaries one cell from box region @@ -91,11 +91,11 @@ def set_fluxnum_kw_from_file(self, fluxnum_file): print("ERROR: FLUXNUM input file not found!") sys.exit(1) - int_type = EclDataType.ECL_INT + int_type = ResDataType.RD_INT with open(fluxnum_file, "r", encoding="utf8") as file_handle: - self.fluxnum_kw = EclKW.read_grdecl( - file_handle, "FLUXNUM", ecl_type=int_type + self.fluxnum_kw = ResdataKW.read_grdecl( + file_handle, "FLUXNUM", rd_type=int_type ) def get_fluxnum_kw(self): @@ -203,11 +203,11 @@ def __init__(self, grid, i_start, i_end, j_start, j_end, k_start=0, k_end=0): self.set_outer_region(i_start, i_end, j_start, j_end, k_start, k_end) def set_inner_region(self, i_start, i_end, j_start, j_end, k_start, k_end): - self.inner_region = EclRegion(self.grid, False) + self.inner_region = ResdataRegion(self.grid, False) self.inner_region.select_box((i_start, j_start, k_start), (i_end, j_end, k_end)) def set_outer_region(self, i_start, i_end, j_start, j_end, k_start, k_end): - self.outer_region = EclRegion(self.grid, False) + self.outer_region = ResdataRegion(self.grid, False) self.outer_region.select_box((i_start, j_start, k_start), (i_end, j_end, k_end)) self.outer_region.invert() @@ -247,8 +247,8 @@ def set_inner_region(self, i, j, k, fipnum_region, fipnum_file): raise Exception("ERROR: FIPNUM input file not found!") with open(fipnum_file, "r", encoding="utf8") as file_handle: - fipnum = EclKW.read_grdecl( - file_handle, "FIPNUM", ecl_type=EclDataType.ECL_INT + fipnum = ResdataKW.read_grdecl( + file_handle, "FIPNUM", rd_type=ResDataType.RD_INT ) else: diff --git a/src/subscript/sector2fluxnum/flux_util.py b/src/subscript/sector2fluxnum/flux_util.py index 75fb84a03..315d5d92a 100644 --- a/src/subscript/sector2fluxnum/flux_util.py +++ b/src/subscript/sector2fluxnum/flux_util.py @@ -1,16 +1,16 @@ -from ecl.grid import EclRegion +from resdata.grid import ResdataRegion def filter_region( grid, idx_i, idx_j, idx_k, fipnum, fipnum_kw, combine_operator="intersect" ): # Filter out the selected grid cells - region = EclRegion(grid, False) - region1 = EclRegion(grid, False) - region_i = EclRegion(grid, False) - region_j = EclRegion(grid, False) - region_k = EclRegion(grid, False) - region_fip = EclRegion(grid, False) + region = ResdataRegion(grid, False) + region1 = ResdataRegion(grid, False) + region_i = ResdataRegion(grid, False) + region_j = ResdataRegion(grid, False) + region_k = ResdataRegion(grid, False) + region_fip = ResdataRegion(grid, False) # Create selected regions for each filter type if idx_i: diff --git a/src/subscript/sector2fluxnum/sector2fluxnum.py b/src/subscript/sector2fluxnum/sector2fluxnum.py index b36755cc5..82e834fe5 100755 --- a/src/subscript/sector2fluxnum/sector2fluxnum.py +++ b/src/subscript/sector2fluxnum/sector2fluxnum.py @@ -3,8 +3,8 @@ import os import cwrap -from ecl.eclfile import EclFile, FortIO -from ecl.grid import EclGrid +from resdata.grid import Grid +from resdata.resfile import FortIO, ResdataFile from subscript.sector2fluxnum import completions, datafile_obj, flux_obj, fluxfile_obj @@ -105,11 +105,11 @@ def sector_to_fluxnum(args): print("Reading grid ...") if args.egrid: args.egrid = os.path.abspath(args.egrid).split(".")[0:1] - grid = EclGrid(f"{args.egrid[0]}.EGRID") + grid = Grid(f"{args.egrid[0]}.EGRID") else: - grid = EclGrid(f"{args.ECLIPSE_CASE[0]}.EGRID") + grid = Grid(f"{args.ECLIPSE_CASE[0]}.EGRID") - init = EclFile(f"{args.ECLIPSE_CASE[0]}.INIT") + init = ResdataFile(f"{args.ECLIPSE_CASE[0]}.INIT") # Finding well completions completion_list, well_list = completions.get_completion_list( @@ -170,9 +170,9 @@ def sector_to_fluxnum(args): # Needs the coordinates from the print("Generating new FLUX file...") - grid_coarse = EclGrid(f"{args.test[0]}.EGRID") - grid_fine = EclGrid(f"{args.test[0]}.EGRID") - flux_fine = EclFile(f"{args.test[0]}.FLUX") + grid_coarse = Grid(f"{args.test[0]}.EGRID") + grid_fine = Grid(f"{args.test[0]}.EGRID") + flux_fine = ResdataFile(f"{args.test[0]}.FLUX") else: print("Executing DUMPFLUX NOSIM run ...") @@ -187,15 +187,15 @@ def sector_to_fluxnum(args): # Needs the coordinates from the print("Generating new FLUX file...") - grid_coarse = EclGrid(f"DUMPFLUX_{eclipse_case_root}.EGRID") - grid_fine = EclGrid(f"DUMPFLUX_{eclipse_case_root}.EGRID") - flux_fine = EclFile(f"DUMPFLUX_{eclipse_case_root}.FLUX") + grid_coarse = Grid(f"DUMPFLUX_{eclipse_case_root}.EGRID") + grid_fine = Grid(f"DUMPFLUX_{eclipse_case_root}.EGRID") + flux_fine = ResdataFile(f"DUMPFLUX_{eclipse_case_root}.FLUX") # Reads restart file if args.restart: - rst_coarse = EclFile(f"{args.restart[0]}.UNRST") + rst_coarse = ResdataFile(f"{args.restart[0]}.UNRST") else: - rst_coarse = EclFile(f"{args.ECLIPSE_CASE[0]}.UNRST") + rst_coarse = ResdataFile(f"{args.ECLIPSE_CASE[0]}.UNRST") flux_object_fine = fluxfile_obj.Fluxfile(grid_fine, flux_fine) diff --git a/src/subscript/summaryplot/summaryplot.py b/src/subscript/summaryplot/summaryplot.py index efc2a19e8..4b07d3947 100644 --- a/src/subscript/summaryplot/summaryplot.py +++ b/src/subscript/summaryplot/summaryplot.py @@ -32,12 +32,12 @@ import matplotlib.pyplot import numpy as np -from ecl.eclfile import EclFile # type: ignore -from ecl.grid import EclGrid # type: ignore -from ecl.summary import EclSum # type: ignore # Get rid of FutureWarning from pandas/plotting.py from pandas.plotting import register_matplotlib_converters +from resdata.grid import Grid # type: ignore +from resdata.resfile import ResdataFile # type: ignore +from resdata.summary import Summary # type: ignore import subscript @@ -146,7 +146,7 @@ def summaryplotter( Will plot Eclipse summary vectors to screen or dump to file based on kwargs. Args: - eclsums: List of EclSum objects + summaryfiles: List of Summary objects datafiles: List of Eclipse DATA files vectors: List of strings, with Eclipse summary vectors parameterfiles: @@ -161,7 +161,7 @@ def summaryplotter( logcolourby: """ rstfiles = [] # EclRst objects - gridfiles = [] # EclGrid objects + gridfiles = [] # Grid objects parametervalues = [] # Vector of values pr. realization for colouring if parameterfiles is None: @@ -169,7 +169,7 @@ def summaryplotter( if datafiles and not summaryfiles: logger.info("Reloading summary files from disk") - summaryfiles = [EclSum(datafile) for datafile in datafiles] + summaryfiles = [Summary(datafile) for datafile in datafiles] if maxlabels == 0: nolegend = True @@ -308,8 +308,8 @@ def summaryplotter( logger.info("Loading grid and restart file %s", rstfile) # TODO: Allow some of the rstfiles to be missing # TODO: Handle missing rstfiles gracefully - rst = EclFile(rstfile) - grid = EclGrid(gridfile) + rst = ResdataFile(rstfile) + grid = Grid(gridfile) rstfiles.append(rst) gridfiles.append(grid) logger.info("RST loading done") @@ -574,24 +574,24 @@ def summaryplotter( def split_vectorsdatafiles(vectorsdatafiles): """ Takes a list of strings and determines which of the arguments are Eclipse runs - (by attempting to construct an EclSum object), and which are summary - vector names/wildcards (that is, those that are not openable as EclSum) + (by attempting to construct an Summary object), and which are summary + vector names/wildcards (that is, those that are not openable as Summary) Args: vectorsdatafiles (list): List of strings Returns: - tuple: 4-tuple of lists, with EclSum-filenames, datafilename-strings, + tuple: 4-tuple of lists, with Summary-filenames, datafilename-strings, vector-strings, parameterfilename-strings """ - summaryfiles = [] # Eclsum instances corresponding to datafiles + summaryfiles = [] # Summary instances corresponding to datafiles datafiles = [] # strings vectors = [] # strings parameterfiles = [] # strings for vecdata in vectorsdatafiles: try: - sumfn = EclSum(vecdata) + sumfn = Summary(vecdata) datafiles.append(vecdata) summaryfiles.append(sumfn) diff --git a/src/subscript/welltest_dpds/welltest_dpds.py b/src/subscript/welltest_dpds/welltest_dpds.py index 7a81f64c9..ff3cab585 100755 --- a/src/subscript/welltest_dpds/welltest_dpds.py +++ b/src/subscript/welltest_dpds/welltest_dpds.py @@ -6,7 +6,7 @@ import numpy as np import pandas as pd -from ecl.summary import EclSum +from resdata.summary import Summary from scipy.interpolate import interp1d from subscript import __version__ @@ -181,7 +181,7 @@ def summary_vec(summary, key, required=True): Read vector corresponding to key from summary instance Args: - summary: (ecl.summary.EclSum) + summary: (resdata.summary.Summary) key: (str) required: (bool) @@ -478,7 +478,7 @@ def main(): if not Path(outdir).exists(): raise FileNotFoundError("No such outputdirectory:", outdir) - summary = EclSum(eclcase) + summary = Summary(eclcase) time = np.array(summary.days) * 24.0 wbhp = summary_vec(summary, "WBHP:" + well_name) diff --git a/tests/test_presentvalue.py b/tests/test_presentvalue.py index 9a13fc11f..6bde32b9b 100644 --- a/tests/test_presentvalue.py +++ b/tests/test_presentvalue.py @@ -3,11 +3,11 @@ import subprocess from pathlib import Path -import ecl import ecl2df import numpy as np import pandas as pd import pytest +from resdata.summary import Summary from subscript.presentvalue import presentvalue @@ -329,7 +329,7 @@ def test_no_gasinj(tmp_path): smry["DATE"] = pd.to_datetime(smry["DATE"]) smry.set_index("DATE") eclsum = ecl2df.summary.df2eclsum(smry, "NOGASINJ") - ecl.summary.EclSum.fwrite(eclsum) + Summary.fwrite(eclsum) econ_df = presentvalue.prepare_econ_table( oilprice=100, gasprice=0, usdtonok=10, discountrate=0 ) @@ -354,7 +354,7 @@ def test_no_gas(tmp_path): smry["DATE"] = pd.to_datetime(smry["DATE"]) smry.set_index("DATE") eclsum = ecl2df.summary.df2eclsum(smry, "NOGAS") - ecl.summary.EclSum.fwrite(eclsum) + Summary.fwrite(eclsum) econ_df = presentvalue.prepare_econ_table( oilprice=100, gasprice=0, usdtonok=10, discountrate=0 ) @@ -379,7 +379,7 @@ def test_no_oil(tmp_path): smry["DATE"] = pd.to_datetime(smry["DATE"]) smry.set_index("DATE") eclsum = ecl2df.summary.df2eclsum(smry, "NOOIL") - ecl.summary.EclSum.fwrite(eclsum) + Summary.fwrite(eclsum) econ_df = presentvalue.prepare_econ_table( oilprice=0, gasprice=10, usdtonok=10, discountrate=0 ) diff --git a/tests/test_summaryplot.py b/tests/test_summaryplot.py index cfce8929e..00f4e4d20 100644 --- a/tests/test_summaryplot.py +++ b/tests/test_summaryplot.py @@ -3,8 +3,8 @@ import subprocess from pathlib import Path -import ecl import pytest +from resdata.summary import Summary from subscript.summaryplot import summaryplot @@ -144,7 +144,7 @@ def test_sysexit(cmd_args, tmp_path, mocker): def test_splitvectorsdatafiles(): """Test that we can separate vectors from DATA files""" result = summaryplot.split_vectorsdatafiles(["FOPT", "FOPR", str(DATAFILE)]) - assert isinstance(result[0][0], ecl.summary.EclSum) + assert isinstance(result[0][0], Summary) print(result) assert result[1:] == ( [str(DATAFILE)], diff --git a/tests/test_welltest_dpds.py b/tests/test_welltest_dpds.py index 73f299e8c..7f5a3724d 100644 --- a/tests/test_welltest_dpds.py +++ b/tests/test_welltest_dpds.py @@ -5,7 +5,7 @@ import numpy as np import pandas as pd import pytest -from ecl.summary import EclSum +from resdata.summary import Summary from subscript.welltest_dpds import welltest_dpds @@ -103,7 +103,7 @@ def test_main(tmp_path, mocker): def test_summary_vec(): """Test that summary reading is handled correctly""" - summary = EclSum(DATAFILEPATH) + summary = Summary(DATAFILEPATH) with pytest.raises(KeyError, match=r".*No such key.*"): welltest_dpds.summary_vec(summary, "no_well") welltest_dpds.summary_vec(summary, "NOVEC:55_33-1") @@ -140,7 +140,7 @@ def test_get_buildup_indices(): assert bu_start == [2, 4] assert bu_end == [2, 5] - summary = EclSum(DATAFILEPATH) + summary = Summary(DATAFILEPATH) wbhp = welltest_dpds.summary_vec(summary, "WBHP:55_33-1") bu_start, bu_end = welltest_dpds.get_buildup_indices(wbhp) @@ -156,7 +156,7 @@ def test_get_buildup_indices(): def test_supertime(): """Test that superpositied time is calculated correctly""" - summary = EclSum(DATAFILEPATH) + summary = Summary(DATAFILEPATH) rate = welltest_dpds.summary_vec(summary, "WOPR:55_33-1") time = np.array(summary.days) * 24.0 @@ -172,7 +172,7 @@ def test_supertime(): def test_weighted_avg_press_time_derivative_lag1(): """Test that weighted_avg_press_time_derivative_lag1 is calculated correctly""" - summary = EclSum(DATAFILEPATH) + summary = Summary(DATAFILEPATH) wbhp = welltest_dpds.summary_vec(summary, "WBHP:55_33-1") rate = welltest_dpds.summary_vec(summary, "WOPR:55_33-1") @@ -194,7 +194,7 @@ def test_weighted_avg_press_time_derivative_lag1(): def test_get_weighted_avg_press_time_derivative_lag2(): """Test that weighted_avg_press_time_derivative_lag2 is calcuated correctly""" - summary = EclSum(DATAFILEPATH) + summary = Summary(DATAFILEPATH) wbhp = welltest_dpds.summary_vec(summary, "WBHP:55_33-1") rate = welltest_dpds.summary_vec(summary, "WOPR:55_33-1")