def _import_eclbinary_checks2(kwlist, name, etype, date): """More checks, and returns what's needed for actual import""" datefound = True kwfound = False datefoundhere = False usedate = "0" restart = False kwname = "unset" kwlen = 0 kwtype = "unset" kwbyte = 0 if etype == 5: usedate = str(date) restart = True kwxlist = list(kwlist.itertuples(index=False, name=None)) for kwitem in kwxlist: kwname, kwtype, kwlen, kwbyte, kwdate = kwitem logger.debug("Keyword %s - date: %s usedate: %s", kwname, kwdate, usedate) if name == kwname: kwfound = True if name == kwname and usedate == str(kwdate): logger.info("Keyword %s ok at date %s", name, usedate) kwname, kwtype, kwlen, kwbyte, kwdate = kwitem datefoundhere = True break if restart: if datefound and not kwfound: msg = "Date <{}> is found, but not keyword <{}>".format(date, name) xtg.warn(msg) raise xtgeo.KeywordNotFoundError(msg) if not datefoundhere and kwfound: msg = "The keyword <{}> exists but not for " "date <{}>".format( name, date) xtg.warn(msg) raise xtgeo.KeywordFoundNoDateError(msg) else: if not kwfound: msg = "The keyword <{}> is not found".format(name) xtg.warn(msg) raise xtgeo.KeywordNotFoundError(msg) return kwname, kwlen, kwtype, kwbyte
def from_file(self, pfile, fformat=None, name="unknown", grid=None, date=None, _roffapiv=1): # _roffapiv for devel. """Import grid property from file, and makes an instance of this.""" # pylint: disable=too-many-branches, too-many-statements self._filesrc = pfile # it may be that pfile already is an open file; hence a filehandle # instead. Check for this, and skip tests if so pfile_is_not_fhandle = True _fhandle, pclose = _get_fhandle(pfile) if not pclose: pfile_is_not_fhandle = False if pfile_is_not_fhandle: if os.path.isfile(pfile): logger.debug("File %s exists OK", pfile) else: raise IOError("No such file: {}".format(pfile)) # work on file extension _froot, fext = os.path.splitext(pfile) if fformat is None or fformat == "guess": if not fext: raise ValueError("File extension missing. STOP") fformat = fext.lower().replace(".", "") logger.debug("File name to be used is %s", pfile) logger.debug("File format is %s", fformat) ier = 0 if fformat == "roff": logger.info("Importing ROFF...") ier = import_roff(self, pfile, name, grid=grid, _roffapiv=_roffapiv) elif fformat.lower() == "init": ier = import_eclbinary(self, pfile, name=name, etype=1, date=None, grid=grid) elif fformat.lower() == "unrst": if date is None: raise ValueError("Restart file, but no date is given") if isinstance(date, str): if "-" in date: date = int(date.replace("-", "")) elif date == "first": date = 0 elif date == "last": date = 9 else: date = int(date) if not isinstance(date, int): raise RuntimeError("Date is not int format") ier = import_eclbinary(self, pfile, name=name, etype=5, date=date, grid=grid) elif fformat.lower() == "grdecl": ier = import_grdecl_prop(self, pfile, name=name, grid=grid) elif fformat.lower() == "bgrdecl": ier = import_bgrdecl_prop(self, pfile, name=name, grid=grid) else: logger.warning("Invalid file format") raise SystemExit("Invalid file format") # if grid, then append this gridprop to the current grid object if ier == 0: if grid: grid.append_prop(self) elif ier == 22: raise xtgeo.DateNotFoundError( "Date {} not found when importing {}".format(date, name)) elif ier == 23: raise xtgeo.KeywordNotFoundError( "Keyword {} not found for date {} when importing".format( name, date)) elif ier == 24: raise xtgeo.KeywordFoundNoDateError( "Keyword {} found but not for date " "{} when importing".format(name, date)) elif ier == 25: raise xtgeo.KeywordNotFoundError( "Keyword {} not found when importing".format(name)) else: raise RuntimeError("Something went wrong, code {}".format(ier)) return self
def _import_eclbinary(self, pfile, name=None, etype=1, date=None, grid=None): """Import, private to this routine. Raises: DateNotFoundError: If restart do not contain requested date. KeywordFoundNoDateError: If keyword is found but not at given date. KeywordNotFoundError: If Keyword is not found. RuntimeError: Mismatch in grid vs property, etc. """ # This function requires simplification! # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements fhandle, pclose = _get_fhandle(pfile) nentry = 0 datefound = True if etype == 5: datefound = False logger.info("Look for date %s", date) # scan for date and find SEQNUM entry number dtlist = utils.scan_dates(fhandle) if date == 0: date = dtlist[0][1] elif date == 9: date = dtlist[-1][1] logger.info("Redefined date is %s", date) for ientry, dtentry in enumerate(dtlist): if str(dtentry[1]) == str(date): datefound = True nentry = ientry break if not datefound: msg = "In {}: Date {} not found, nentry={}".format( pfile, date, nentry) xtg.warn(msg) raise xtgeo.DateNotFoundError(msg) # scan file for property logger.info("Make kwlist") kwlist = utils.scan_keywords(fhandle, fformat="xecl", maxkeys=100000, dataframe=False, dates=True) # first INTEHEAD is needed to verify grid dimensions: for kwitem in kwlist: if kwitem[0] == "INTEHEAD": kwname, kwtype, kwlen, kwbyte, kwdate = kwitem break # read INTEHEAD record: intehead = eclbin_record(fhandle, kwname, kwlen, kwtype, kwbyte) ncol, nrow, nlay = intehead[8:11].tolist() self._ncol = ncol self._nrow = nrow self._nlay = nlay logger.info("Grid dimensions in INIT or RESTART file: %s %s %s", ncol, nrow, nlay) logger.info("Grid dimensions from GRID file: %s %s %s", grid.ncol, grid.nrow, grid.nlay) if grid.ncol != ncol or grid.nrow != nrow or grid.nlay != nlay: msg = "In {}: Errors in dimensions prop: {} {} {} vs grid: {} {} {} ".format( pfile, ncol, nrow, nlay, grid.ncol, grid.ncol, grid.nlay) raise RuntimeError(msg) # Restarts (etype == 5): # there are cases where keywords do not exist for all dates, e.g .'RV'. # The trick is to check for dates also... kwfound = False datefoundhere = False usedate = "0" restart = False if etype == 5: usedate = str(date) restart = True for kwitem in kwlist: kwname, kwtype, kwlen, kwbyte, kwdate = kwitem logger.debug("Keyword %s - date: %s usedate: %s", kwname, kwdate, usedate) if name == kwname: kwfound = True if name == kwname and usedate == str(kwdate): logger.info("Keyword %s ok at date %s", name, usedate) kwname, kwtype, kwlen, kwbyte, kwdate = kwitem datefoundhere = True break if restart: if datefound and not kwfound: msg = "For {}: Date <{}> is found, but not keyword <{}>".format( pfile, date, name) xtg.warn(msg) raise xtgeo.KeywordNotFoundError(msg) if not datefoundhere and kwfound: msg = "For {}: The keyword <{}> exists but not for " "date <{}>".format( pfile, name, date) xtg.warn(msg) raise xtgeo.KeywordFoundNoDateError(msg) else: if not kwfound: msg = "For {}: The keyword <{}> is not found".format(pfile, name) xtg.warn(msg) raise xtgeo.KeywordNotFoundError(msg) # read record: values = eclbin_record(fhandle, kwname, kwlen, kwtype, kwbyte) if kwtype == "INTE": self._isdiscrete = True use_undef = xtgeo.UNDEF_INT # make the code list uniq = np.unique(values).tolist() codes = dict(zip(uniq, uniq)) codes = {key: str(val) for key, val in codes.items()} # val: strings self.codes = codes else: self._isdiscrete = False values = values.astype(np.float64) # cast REAL (float32) to float64 use_undef = xtgeo.UNDEF self.codes = {} # arrays from Eclipse INIT or UNRST are usually for inactive values only. # Use the ACTNUM index array for vectorized numpy remapping actnum = grid.get_actnum().values allvalues = np.zeros((ncol * nrow * nlay), dtype=values.dtype) + use_undef msg = "\n" msg = msg + "grid.actnum_indices.shape[0] = {}\n".format( grid.actnum_indices.shape[0]) msg = msg + "values.shape[0] = {}\n".format(values.shape[0]) msg = msg + "ncol nrow nlay {} {} {}, nrow*nrow*nlay = {}\n".format( ncol, nrow, nlay, ncol * nrow * nlay) logger.info(msg) if grid.actnum_indices.shape[0] == values.shape[0]: allvalues[grid.get_actnum_indices(order="F")] = values elif values.shape[0] == ncol * nrow * nlay: # often case for PORV array allvalues = values.copy() else: msg = ("BUG somehow... Is the file corrupt? If not contact " "the library developer(s)!\n" + msg) raise SystemExit(msg) allvalues = allvalues.reshape((ncol, nrow, nlay), order="F") allvalues = np.asanyarray(allvalues, order="C") allvalues = ma.masked_where(actnum < 1, allvalues) _close_fhandle(fhandle, pclose) self._values = allvalues if etype == 1: self._name = name else: self._name = name + "_" + str(date) self._date = date return 0