def import_ecl_run(self, groot, initprops=None, restartprops=None, restartdates=None): """Import combo ECL runs.""" ecl_grid = groot + ".EGRID" ecl_init = groot + ".INIT" ecl_rsta = groot + ".UNRST" ecl_grid = xtgeo._XTGeoFile(ecl_grid) ecl_init = xtgeo._XTGeoFile(ecl_init) ecl_rsta = xtgeo._XTGeoFile(ecl_rsta) # import the grid import_ecl_egrid(self, ecl_grid) grdprops = xtgeo.grid3d.GridProperties() # import the init properties unless list is empty if initprops: grdprops.from_file( ecl_init.name, names=initprops, fformat="init", dates=None, grid=self ) # import the restart properties for dates unless lists are empty if restartprops and restartdates: grdprops.from_file( ecl_rsta.name, names=restartprops, fformat="unrst", dates=restartdates, grid=self, ) self.gridprops = grdprops
def scan_dates(pfile, fformat="unrst", maxdates=1000, dataframe=False): """Quick scan dates in a simulation restart file. Args: pfile (str): Name of file or file handle with properties fformat (str): unrst (so far) maxdates (int): Maximum number of dates to collect dataframe (bool): If True, return a Pandas dataframe instead Return: A list of tuples or a dataframe with (seqno, date), date is on YYYYMMDD form. Example:: >>> props = GridProperties() >>> dlist = props.scan_dates('ECL.UNRST') """ pfile = xtgeo._XTGeoFile(pfile) logger.info("Format supported as default is %s", fformat) dlist = utils.scan_dates(pfile, maxdates=maxdates, dataframe=dataframe) return dlist
def export_xtgeo(self, gfile): """Export grid to binary XTGeo format (in prep). Args: gfile(str): Name of output file """ self._xtgformat2() gfile = xtgeo._XTGeoFile(gfile, mode="wb") logger.debug("Export to binary XTGEO...") # TODO: Improve metadata meta = {"subgrids": self.get_subgrids()} jmeta = json.dumps(meta) _cxtgeo.grdcp3d_export_xtgeo_grid( self._ncol, self._nrow, self._nlay, self._coordsv, self._zcornsv, self._actnumsv, jmeta, gfile.get_cfhandle(), ) gfile.cfclose() logger.debug("Export to binary XTGEO... done")
def from_file( self, wfile, fformat="rms_ascii", mdlogname=None, zonelogname=None, strict=False, lognames="all", lognames_strict=False, ): """Import well from file. Args: wfile (str): Name of file as string or pathlib.Path fformat (str): File format, rms_ascii (rms well) is currently supported and default format. mdlogname (str): Name of measured depth log, if any zonelogname (str): Name of zonation log, if any strict (bool): If True, then import will fail if zonelogname or mdlogname are asked for but not present in wells. If False, and e.g. zonelogname is not present, the attribute ``zonelogname`` will be set to None. lognames (str or list): Name or list of lognames to import, default is "all" lognames_strict (bool): Flag to require all logs in lognames (unless "all") or to just accept that subset that is present. Default is `False`. Returns: Object instance (optionally) Example: Here the from_file method is used to initiate the object directly:: >>> mywell = Well('31_2-6.w') .. versionchanged:: 2.1.0 ``lognames`` and ``lognames_strict`` added .. versionchanged:: 2.1.0 ``strict`` now defaults to False """ wfile = xtgeo._XTGeoFile(wfile) wfile.check_file(raiseerror=OSError) if fformat is None or fformat == "rms_ascii": _well_io.import_rms_ascii( self, wfile.name, mdlogname=mdlogname, zonelogname=zonelogname, strict=strict, lognames=lognames, lognames_strict=lognames_strict, ) else: logger.error("Invalid file format") self._ensure_consistency() self._filesrc = wfile.name return self
def to_file(self, wfile, fformat="rms_ascii"): """ Export well to file Args: wfile (str): Name of file or pathlib.Path instance fformat (str): File format ('rms_ascii'/'rmswell', 'hdf5') Example:: xwell = Well("somefile.rmswell") xwell.dataframe['PHIT'] += 0.1 xwell.to_file("somefile_copy.rmswell") """ wfile = xtgeo._XTGeoFile(wfile, mode="wb") wfile.check_folder(raiseerror=OSError) self._ensure_consistency() if fformat in (None, "rms_ascii", "rmswell"): _well_io.export_rms_ascii(self, wfile.name) elif fformat == "hdf5": with pd.HDFStore(wfile, "a", complevel=9, complib="zlib") as store: logger.info("export to HDF5 %s", wfile.name) store[self._wname] = self._df meta = dict() meta["name"] = self._wname store.get_storer(self._wname).attrs["metadata"] = meta
def to_file(self, pfile, fformat="roff", name=None, append=False, dtype=None, fmt=None): """Export the grid property to file.""" logger.debug("Export property to file %s", pfile) fobj = xtgeo._XTGeoFile(pfile, mode="rb") fobj.check_folder(raiseerror=OSError) if name is None: name = self.name if "roff" in fformat: binary = True if "asc" in fformat: binary = False # for later usage append = False last = True export_roff(self, fobj.name, name, append=append, last=last, binary=binary) elif fformat == "grdecl": export_grdecl( self, fobj.name, name, append=append, binary=False, dtype=dtype, fmt=fmt ) elif fformat == "bgrdecl": export_grdecl(self, fobj.name, name, append=append, binary=True, dtype=dtype) else: raise ValueError("Cannot export, invalid fformat: {}".format(fformat))
def test_detect_fformat_hdf_to_file(tmp_path, testpath, filename): newfile = tmp_path / "hdf_surf.hdf" surf = xtgeo.RegularSurface(testpath / filename) surf.to_hdf(newfile) gfile = xtgeo._XTGeoFile(newfile) assert gfile.detect_fformat() == "hdf" assert gfile.detect_fformat(details=True) == "hdf RegularSurface xtgeo"
def test_detect_fformat_hdf_stream(testpath, filename): stream = io.BytesIO() surf = xtgeo.RegularSurface(testpath / filename) surf.to_hdf(stream) sfile = xtgeo._XTGeoFile(stream) assert sfile.memstream is True assert sfile.detect_fformat() == "hdf"
def test_surface_file_roundtrip_stream(testpath, filename): stream = io.BytesIO() surf = xtgeo.RegularSurface(testpath / filename) surf.to_file(stream) stream_file = xtgeo._XTGeoFile(stream) assert stream_file.memstream is True assert stream_file.detect_fformat() == "irap_binary"
def test_xtgeocfile(): """Test basic system file io etc functions""" gfile = xtgeo._XTGeoFile(TESTFILE) xfile = xtgeo._XTGeoFile(TESTNOEXISTFILE) yfile = xtgeo._XTGeoFile(TESTNOEXISTFOLDER) gfolder = xtgeo._XTGeoFile(TESTFOLDER) assert isinstance(gfile, xtgeo._XTGeoFile) assert isinstance(gfile._file, pathlib.Path) assert gfile._memstream is False assert gfile._mode == "rb" assert gfile._delete_after is False assert gfile.name == os.path.abspath(TESTFILE) assert xfile.name == os.path.abspath(TESTNOEXISTFILE) # exists, check_* assert gfile.exists() is True assert gfolder.exists() is True assert xfile.exists() is False assert gfile.check_file() is True assert xfile.check_file() is False assert yfile.check_file() is False with pytest.raises(OSError): xfile.check_file(raiseerror=OSError) assert gfile.check_folder() is True assert xfile.check_folder() is True assert yfile.check_folder() is False with pytest.raises(OSError): yfile.check_folder(raiseerror=OSError) assert "Swig" in str(gfile.get_cfhandle()) assert gfile.cfclose() is True # extensions: stem, suff = gfile.splitext(lower=False) assert stem == "REEK" assert suff == "EGRID"
def from_file(self, pfile, fformat="guess"): """Import Points or Polygons from a file. Supported import formats (fformat): * 'xyz' or 'poi' or 'pol': Simple XYZ format * 'zmap': ZMAP line format as exported from RMS (e.g. fault lines) * 'rms_attr': RMS points formats with attributes (extra columns) * 'guess': Try to choose file format based on extension Args: pfile (str): Name of file or pathlib.Path instance fformat (str): File format, see list above Returns: Object instance (needed optionally) Raises: OSError: if file is not present or wrong permissions. """ pfile = xtgeo._XTGeoFile(pfile) logger.info("Reading from file %s...", pfile.name) pfile.check_file(raiseerror=OSError) froot, fext = pfile.splitext(lower=True) if fformat == "guess": if not fext: logger.critical("File extension missing. STOP") raise SystemExit fformat = fext if fformat in ["xyz", "poi", "pol"]: _xyz_io.import_xyz(self, pfile.name) elif fformat == "zmap": _xyz_io.import_zmap(self, pfile.name) elif fformat in ("rms_attr", "rmsattr"): _xyz_io.import_rms_attr(self, pfile.name) else: logger.error("Invalid file format (not supported): %s", fformat) raise SystemExit logger.info("Reading from file %s... done", pfile.name) logger.debug("Dataframe head:\n%s", self._df.head()) self._filesrc = pfile.name return self
def test_resolve_alias(): """Testing resolving file alias function.""" surf = xtgeo.RegularSurface(TESTSURF) md5hash = surf.generate_hash("md5") mname = xtgeo._XTGeoFile("whatever/$md5sum.gri", obj=surf) assert str(mname.file) == f"whatever/{md5hash}.gri" mname = xtgeo._XTGeoFile(pathlib.Path("whatever/$md5sum.gri"), obj=surf) assert str(mname.file) == f"whatever/{md5hash}.gri" mname = xtgeo._XTGeoFile("whatever/$random.gri", obj=surf) assert len(str(mname.file)) == 45 # use $fmu.v1 schema surf.metadata.opt.shortname = "topValysar" surf.metadata.opt.description = "Depth surface" mname = xtgeo._XTGeoFile(pathlib.Path("whatever/$fmu-v1.gri"), obj=surf) assert str(mname.file) == "whatever/topvalysar--depth_surface.gri"
def test_surf_export_petromod_exception(): gfile = xtgeo._XTGeoFile(io.BytesIO(b"\x00")) with pytest.raises( xtgeo.XTGeoCLibError, match= "Error writing to Storm format. Bug in: surf_export_petromod_bi", ): _cxtgeo.surf_export_petromod_bin( gfile.get_cfhandle(), "not_relevant", [1, 2], )
def _export_roff_v2(self, gfile, ascii_fmt): """Export grid to ROFF format (binary/ascii) _xtgformat=2""" self._xtgformat2() gfile = xtgeo._XTGeoFile(gfile, mode="wb") gfile.check_folder(raiseerror=OSError) cfhandle = gfile.get_cfhandle() logger.debug("Export to ROFF... ascii_fmt = %s", ascii_fmt) subs = self.get_subgrids() if subs: sublist = np.array(list(subs.values()), dtype=np.int32) else: sublist = np.zeros((1), dtype=np.int32) # for *shift values midi, midj, midk = (self.ncol // 2, self.nrow // 2, self.nlay // 2) midx = float(self._coordsv[midi, midj, 0]) midy = float(self._coordsv[midi, midj, 1]) midz = float(self._zcornsv[midi, midj, midk, 0]) info = "#" + xtg.get_xtgeo_info( ) + "#$" # last $ is for lineshift trick in roffasc _cxtgeo.grdcp3d_export_roff_bin_start_end(0, info, ascii_fmt, "grid", self.ncol, self.nrow, self.nlay, cfhandle) _cxtgeo.grdcp3d_export_roff_grid( ascii_fmt, self._ncol, self._nrow, self._nlay, midx, midy, midz, sublist, self._coordsv, self._zcornsv, self._actnumsv, cfhandle, ) # # TODO: export assosiated properties # end tag _cxtgeo.grdcp3d_export_roff_bin_start_end(1, info, ascii_fmt, "xxxx", self.ncol, self.nrow, self.nlay, cfhandle) gfile.cfclose()
def xtgeo_file_properties(testpath, filename): gfile = xtgeo._XTGeoFile(testpath / filename) assert isinstance(gfile, xtgeo._XTGeoFile) assert isinstance(gfile._file, pathlib.Path) assert gfile._memstream is False assert gfile._mode == "rb" assert gfile._delete_after is False assert gfile.name == (testpath / filename).absolute() assert "Swig" in str(gfile.get_cfhandle()) assert gfile.cfclose() is True
def to_file(self, pfile, fformat="roff", name=None, append=False, dtype=None, fmt=None): """Export the grid property to file.""" logger.info("Export property to file %s as %s", pfile, fformat) fobj = xtgeo._XTGeoFile(pfile, mode="rb") fobj.check_folder(raiseerror=OSError) if name is None: name = self.name if "roff" in fformat: binary = True if "asc" in fformat: binary = False if append: logger.warning( "Append is not implemented for roff format, defaulting to write." ) export_roff(self, fobj.name, name, binary=binary) elif fformat == "grdecl": export_grdecl(self, fobj.name, name, append=append, binary=False, dtype=dtype, fmt=fmt) elif fformat == "bgrdecl": export_grdecl(self, fobj.name, name, append=append, binary=True, dtype=dtype) elif fformat == "xtgcpprop": export_xtgcpprop(self, fobj.name) else: raise ValueError("Cannot export, invalid fformat: {}".format(fformat))
def test_xtgeocfile_fhandle(): """Test in particular C handle SWIG system.""" gfile = xtgeo._XTGeoFile(TESTFILE) chandle1 = gfile.get_cfhandle() chandle2 = gfile.get_cfhandle() assert gfile._cfhandlecount == 2 assert chandle1 == chandle2 assert gfile.cfclose() is False assert gfile.cfclose() is True # try to close a cfhandle that does not exist with pytest.raises(RuntimeError): gfile.cfclose()
def scan_keywords(pfile, fformat="xecl", maxkeys=100000, dataframe=False, dates=False): """Quick scan of keywords in Eclipse binary restart/init/... file, or ROFF binary files. For Eclipse files: Returns a list of tuples (or dataframe), e.g. ('PRESSURE', 'REAL', 355299, 3582700), where (keyword, type, no_of_values, byteposition_in_file) For ROFF files Returns a list of tuples (or dataframe), e.g. ('translate!xoffset', 'float', 1, 3582700), where (keyword, type, no_of_values, byteposition_in_file). For Eclipse, the byteposition is to the KEYWORD, while for ROFF the byte position is to the beginning of the actual data. Args: pfile (str): Name or a filehandle to file with properties fformat (str): xecl (Eclipse INIT, RESTART, ...) or roff for ROFF binary, maxkeys (int): Maximum number of keys dataframe (bool): If True, return a Pandas dataframe instead dates (bool): if True, the date is the last column (only menaingful for restart files). Default is False. Return: A list of tuples or dataframe with keyword info Example:: >>> props = GridProperties() >>> dlist = props.scan_keywords('ECL.UNRST') """ pfile = xtgeo._XTGeoFile(pfile) dlist = utils.scan_keywords(pfile, fformat=fformat, maxkeys=maxkeys, dataframe=dataframe, dates=dates) return dlist
def export_xtgcpgeom(self, gfile, subformat=844): """Export grid to binary XTGeo xtgcpgeom format, in prep. and experimental""" self._xtgformat2() self.metadata.required = self gfile = xtgeo._XTGeoFile(gfile, mode="wb") # subformat processing, indicating number of bytes per datatype # here, 844 is native XTGeo (float64, float32, int32) if int(subformat) not in (444, 844, 841, 881, 884): raise ValueError("The subformat value ins not valid") coordfmt, zcornfmt, actnumfmt = [int(nbyte) for nbyte in str(subformat)] coordsv = self._coordsv zcornsv = self._zcornsv actnumv = self._actnumsv if coordfmt != 8: coordsv = self._coordsv.astype("float" + str(coordfmt * 8)) if zcornfmt != 4: zcornsv = self._zcornsv.astype("float" + str(zcornfmt * 8)) if actnumfmt != 4: actnumv = self._actnumsv.astype("int" + str(actnumfmt * 8)) prevalues = (1, 1301, int(subformat), self.ncol, self.nrow, self.nlay) mystruct = struct.Struct("= i i i q q q") hdr = mystruct.pack(*prevalues) meta = self.metadata.get_metadata() with open(gfile.name, "wb") as fout: fout.write(hdr) with open(gfile.name, "ab") as fout: coordsv.tofile(fout) zcornsv.tofile(fout) actnumv.tofile(fout) with open(gfile.name, "ab") as fout: fout.write("\nXTGMETA.v01\n".encode()) with open(gfile.name, "ab") as fout: fout.write(json.dumps(meta).encode())
def test_file_c_handle(testpath, filename): any_xtgeo_file = xtgeo._XTGeoFile(testpath / filename) handle_count = any_xtgeo_file._cfhandlecount c_handle_1 = any_xtgeo_file.get_cfhandle() assert handle_count + 1 == any_xtgeo_file._cfhandlecount c_handle_2 = any_xtgeo_file.get_cfhandle() assert handle_count + 2 == any_xtgeo_file._cfhandlecount assert c_handle_1 == c_handle_2 assert any_xtgeo_file.cfclose() is False assert any_xtgeo_file.cfclose() is True # try to close a cfhandle that does not exist with pytest.raises(RuntimeError): any_xtgeo_file.cfclose()
def scan_dates(pfile, fformat="unrst", maxdates=1000, dataframe=False, datesonly=False): """Quick scan dates in a simulation restart file. Args: pfile (str): Name of file or file handle with properties fformat (str): unrst (so far) maxdates (int): Maximum number of dates to collect dataframe (bool): If True, return a Pandas dataframe instead datesonly (bool): If True, SEQNUM is skipped, Return: A list of tuples or a dataframe with (seqno, date), date is on YYYYMMDD form. If datesonly is True and dataframe is False, the returning list will be a simple list of dates. Example:: >>> props = GridProperties() >>> dlist = props.scan_dates('ECL.UNRST') or getting all dates a simple list: >>> from xtgeo import GridProperties as GPS >>> dlist = GPS().scan_dates("ECL.UNRST", datesonly=True) .. versionchanged:: 2.13 Added datesonly keyword """ pfile = xtgeo._XTGeoFile(pfile) logger.info("Format supported as default is %s", fformat) dlist = utils.scan_dates(pfile, maxdates=maxdates, dataframe=dataframe) if datesonly and dataframe: dlist.drop("SEQNUM", axis=1, inplace=True) if datesonly and not dataframe: dlist = [date for (_, date) in dlist] return dlist
def _export_roff_v1(self, gfile, option): """Export grid to ROFF format (binary)""" self._xtgformat1() gfile = xtgeo._XTGeoFile(gfile, mode="wb") gfile.check_folder(raiseerror=OSError) logger.debug("Export to ROFF...") nsubs = 0 if self.subgrids is None: logger.debug("Create a pointer for subgrd_v ...") subgrd_v = _cxtgeo.new_intpointer() else: nsubs = len(self.subgrids) subgrd_v = _cxtgeo.new_intarray(nsubs) for inum, (sname, sarray) in enumerate(self.subgrids.items()): logger.info("INUM SUBGRID: %s %s", inum, sname) _cxtgeo.intarray_setitem(subgrd_v, inum, len(sarray)) # get the geometrics list to find the xshift, etc gx = self.get_geometrics() _cxtgeo.grd3d_export_roff_grid( option, self._ncol, self._nrow, self._nlay, nsubs, 0, gx[3], gx[5], gx[7], self._coordsv, self._zcornsv, self._actnumsv, subgrd_v, gfile.name, ) # end tag _cxtgeo.grd3d_export_roff_end(option, gfile.name)
def test_grd3d_imp_ecl_egrid(): with pytest.raises( xtgeo.XTGeoCLibError, match="Errors in array lengths checks in", ): _cxtgeo.grd3d_imp_ecl_egrid( xtgeo._XTGeoFile(io.BytesIO(b"")).get_cfhandle(), 1, 1, 1, 0, 0, 0, 0, np.array([0.0], dtype=np.float64), np.array([1.0], dtype=np.float64), np.array([1], dtype=np.int32), _cxtgeo.new_longarray(1), 1, )
def test_check_file(reek_grid_path, filename): xtgeo_file = xtgeo._XTGeoFile(reek_grid_path / filename) assert xtgeo_file.check_file() is False with pytest.raises(OSError): xtgeo_file.check_file(raiseerror=OSError)
def to_file( self, pfile, fformat="xyz", attributes=False, pfilter=None, filter=None, # deprecated, not in use (only signature) wcolumn=None, hcolumn=None, mdcolumn="M_MDEPTH", ): # pylint: disable=redefined-builtin """Export XYZ (Points/Polygons) to file. Args: pfile (str): Name of file fformat (str): File format xyz/poi/pol / rms_attr /rms_wellpicks attributes (bool or list): List of extra columns to export (some formats) or True for all attributes present pfilter (dict): Filter on e.g. top name(s) with keys TopName or ZoneName as {'TopName': ['Top1', 'Top2']} wcolumn (str): Name of well column (rms_wellpicks format only) hcolumn (str): Name of horizons column (rms_wellpicks format only) mdcolumn (str): Name of MD column (rms_wellpicks format only) Returns: Number of points exported Note that the rms_wellpicks will try to output to: * HorizonName, WellName, MD if a MD (mdcolumn) is present, * HorizonName, WellName, X, Y, Z otherwise Raises: KeyError if pfilter is set and key(s) are invalid """ pfile = xtgeo._XTGeoFile(pfile) pfile.check_folder(raiseerror=OSError) if self.dataframe is None: ncount = 0 logger.warning("Nothing to export!") return ncount if fformat is None or fformat in ["xyz", "poi", "pol"]: # NB! reuse export_rms_attr function, but no attributes # are possible ncount = _xyz_io.export_rms_attr(self, pfile.name, attributes=False, pfilter=pfilter) elif fformat == "rms_attr": ncount = _xyz_io.export_rms_attr(self, pfile.name, attributes=attributes, pfilter=pfilter) elif fformat == "rms_wellpicks": ncount = _xyz_io.export_rms_wpicks(self, pfile.name, hcolumn, wcolumn, mdcolumn=mdcolumn) if ncount is None: ncount = 0 if ncount == 0: logger.warning("Nothing to export!") return ncount
def from_file( self, pfile, fformat=None, name="unknown", grid=None, gridlink=True, date=None, fracture=False, _roffapiv=1, ): # _roffapiv for devel. """ Import grid property from file, and makes an instance of this class. Note that the the property may be linked to its geometrical grid, through the ``grid=`` option. Sometimes this is required, for instance for most Eclipse input. Args: pfile (str): name of file to be imported fformat (str): file format to be used roff/init/unrst/grdecl (None is default, which means "guess" from file extension). name (str): name of property to import date (int or str): For restart files, date on YYYYMMDD format. Also the YYYY-MM-DD form is allowed (string), and for Eclipse, mnemonics like 'first', 'last' is also allowed. grid (Grid object): Grid Object for checks (optional for ROFF, required for Eclipse). gridlink (bool): If True, and grid is not None, a link from the grid instance to the property is made. If False, no such link is made. Avoiding gridlink is recommended when running statistics of multiple realisations of a property. fracture (bool): Only applicable for DUAL POROSITY systems, if True then the fracture property is read; if False then the matrix property is read. Names will be appended with "M" or "F" Examples:: x = GridProperty() x.from_file('somefile.roff', fformat='roff') # mygrid = Grid('ECL.EGRID') pressure_1 = GridProperty() pressure_1.from_file('ECL.UNRST', name='PRESSURE', date='first', grid=mygrid) Returns: True if success, otherwise False .. versionchanged:: 2.8 Added gridlink option, default is True """ pfile = xtgeo._XTGeoFile(pfile, mode="rb") obj = _gridprop_import.from_file( self, pfile, fformat=fformat, name=name, grid=grid, date=date, fracture=fracture, _roffapiv=_roffapiv, ) if grid and gridlink: grid.append_prop(self) return obj
def test_detect_fformat_suffix_only(testpath, filename, expected_format): xtgeo_file = xtgeo._XTGeoFile(testpath / filename) assert xtgeo_file.detect_fformat(suffixonly=True) == expected_format
def test_file_does_not_exist(reek_grid_path, filename): xtgeo_file = xtgeo._XTGeoFile(reek_grid_path / filename) assert xtgeo_file.exists() is False
def test_check_file_is_ok(reek_grid_path, filename): xtgeo_file = xtgeo._XTGeoFile(reek_grid_path / filename) assert xtgeo_file.check_file() is True
def from_file(self, pfile, fformat="roff", names=None, dates=None, grid=None, namestyle=0): """Import grid properties from file in one go. This class is particulary useful for Eclipse INIT and RESTART files. In case of names='all' then all vectors which have a valid length (number of total or active cells in the grid) will be read Args: pfile (str or Path): Name of file with properties fformat (str): roff/init/unrst names: list of property names, e.g. ['PORO', 'PERMX'] or 'all' dates: list of dates on YYYYMMDD format, for restart files grid (obj): The grid geometry object (optional if ROFF) namestyle (int): 0 (default) for style SWAT_20110223, 1 for SWAT--2011_02_23 (applies to restart only) Example:: >>> props = GridProperties() >>> props.from_file('ECL.UNRST', fformat='unrst', dates=[20110101, 20141212], names=['PORO', 'DZ'] Raises: FileNotFoundError: if input file is not found ValueError: if a property is not found RuntimeWarning: if some dates are not found """ pfile = xtgeo._XTGeoFile(pfile, mode="rb") # work on file extension froot, fext = pfile.splitext(lower=True) if not fext: # file extension is missing, guess from format logger.info("File extension missing; guessing...") useext = "" if fformat == "init": useext = ".INIT" elif fformat == "unrst": useext = ".UNRST" elif fformat == "roff": useext = ".roff" pfile = froot + useext logger.info("File name to be used is %s", pfile) pfile.check_file(raiseerror=OSError) if fformat.lower() == "roff": lst = list() for name in names: lst.append(GridProperty(pfile, fformat="roff", name=name)) self.append_props(lst) elif fformat.lower() in ("init", "unrst"): _gridprops_io.import_ecl_output(self, pfile, dates=dates, grid=grid, names=names, namestyle=namestyle) else: raise OSError("Invalid file format")