Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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