def scan_dates(pfile, maxdates=1000, dataframe=False): """Quick scan dates in a simulation restart file. Cf. grid_properties.py description """ seq = _cxtgeo.new_intarray(maxdates) day = _cxtgeo.new_intarray(maxdates) mon = _cxtgeo.new_intarray(maxdates) yer = _cxtgeo.new_intarray(maxdates) local_fhandle = False fhandle = pfile if isinstance(pfile, str): pfile = xtgeo._XTGeoCFile(pfile) fhandle = pfile.fhandle local_fhandle = True nstat = _cxtgeo.grd3d_ecl_tsteps(fhandle, seq, day, mon, yer, maxdates, XTGDEBUG) if local_fhandle: pfile.close(cond=local_fhandle) sq = [] da = [] for i in range(nstat): sq.append(_cxtgeo.intarray_getitem(seq, i)) dday = _cxtgeo.intarray_getitem(day, i) dmon = _cxtgeo.intarray_getitem(mon, i) dyer = _cxtgeo.intarray_getitem(yer, i) date = "{0:4}{1:02}{2:02}".format(dyer, dmon, dday) da.append(int(date)) for item in [seq, day, mon, yer]: _cxtgeo.delete_intarray(item) zdates = list(zip(sq, da)) # list for PY3 if dataframe: cols = ["SEQNUM", "DATE"] df = pd.DataFrame.from_records(zdates, columns=cols) return df return zdates
def _scan_ecl_keywords(pfile, maxkeys=100000, dataframe=False): # In case pfile is not a file name but a swig pointer to a file handle, # the file must not be closed ultramax = int(1000000 / 9) # cf *swig_bnd_char_1m in cxtgeo.i if maxkeys > ultramax: raise ValueError("maxkeys value is too large, must be < {}".format(ultramax)) rectypes = _cxtgeo.new_intarray(maxkeys) reclens = _cxtgeo.new_longarray(maxkeys) recstarts = _cxtgeo.new_longarray(maxkeys) fhandle, pclose = _get_fhandle(pfile) nkeys, keywords = _cxtgeo.grd3d_scan_eclbinary( fhandle, rectypes, reclens, recstarts, maxkeys, XTGDEBUG ) _close_fhandle(fhandle, pclose) keywords = keywords.replace(" ", "") keywords = keywords.split("|") # record types translation (cf: grd3d_scan_eclbinary.c in cxtgeo) rct = { "1": "INTE", "2": "REAL", "3": "DOUB", "4": "CHAR", "5": "LOGI", "6": "MESS", "-1": "????", } rc = [] rl = [] rs = [] for i in range(nkeys): rc.append(rct[str(_cxtgeo.intarray_getitem(rectypes, i))]) rl.append(_cxtgeo.longarray_getitem(reclens, i)) rs.append(_cxtgeo.longarray_getitem(recstarts, i)) _cxtgeo.delete_intarray(rectypes) _cxtgeo.delete_longarray(reclens) _cxtgeo.delete_longarray(recstarts) result = list(zip(keywords, rc, rl, rs)) if dataframe: cols = ["KEYWORD", "TYPE", "NITEMS", "BYTESTART"] df = pd.DataFrame.from_records(result, columns=cols) return df return result
def scan_dates(pfile, fformat="unrst", maxdates=1000, dataframe=False): """Quick scan dates in a simulation restart file. Cf. grid_properties.py description """ logger.info("Format supported as default is %s", fformat) seq = _cxtgeo.new_intarray(maxdates) day = _cxtgeo.new_intarray(maxdates) mon = _cxtgeo.new_intarray(maxdates) yer = _cxtgeo.new_intarray(maxdates) fhandle, pclose = _get_fhandle(pfile) nstat = _cxtgeo.grd3d_ecl_tsteps(fhandle, seq, day, mon, yer, maxdates, XTGDEBUG) _close_fhandle(fhandle, pclose) sq = [] da = [] for i in range(nstat): sq.append(_cxtgeo.intarray_getitem(seq, i)) dday = _cxtgeo.intarray_getitem(day, i) dmon = _cxtgeo.intarray_getitem(mon, i) dyer = _cxtgeo.intarray_getitem(yer, i) date = "{0:4}{1:02}{2:02}".format(dyer, dmon, dday) da.append(int(date)) for item in [seq, day, mon, yer]: _cxtgeo.delete_intarray(item) zdates = list(zip(sq, da)) # list for PY3 if dataframe: cols = ["SEQNUM", "DATE"] df = pd.DataFrame.from_records(zdates, columns=cols) return df return zdates
def _import_roff_v1(self, pfile, name): """Import ROFF format, version 1""" # pylint: disable=too-many-locals # there is a todo here to get it more robust for various cases, # e.g. that a ROFF file may contain both a grid an numerous # props logger.info("Looking for %s in file %s", name, pfile) ptr_ncol = _cxtgeo.new_intpointer() ptr_nrow = _cxtgeo.new_intpointer() ptr_nlay = _cxtgeo.new_intpointer() ptr_ncodes = _cxtgeo.new_intpointer() ptr_type = _cxtgeo.new_intpointer() ptr_idum = _cxtgeo.new_intpointer() ptr_ddum = _cxtgeo.new_doublepointer() # read with mode 0, to scan for ncol, nrow, nlay and ndcodes, and if # property is found... ier, _codenames = _cxtgeo.grd3d_imp_prop_roffbin( pfile, 0, ptr_type, ptr_ncol, ptr_nrow, ptr_nlay, ptr_ncodes, name, ptr_idum, ptr_ddum, ptr_idum, 0, XTGDEBUG, ) if ier == -1: msg = "Cannot find property name {}".format(name) logger.warning(msg) raise SystemExit("Error from ROFF import") self._ncol = _cxtgeo.intpointer_value(ptr_ncol) self._nrow = _cxtgeo.intpointer_value(ptr_nrow) self._nlay = _cxtgeo.intpointer_value(ptr_nlay) self._ncodes = _cxtgeo.intpointer_value(ptr_ncodes) ptype = _cxtgeo.intpointer_value(ptr_type) ntot = self._ncol * self._nrow * self._nlay if self._ncodes <= 1: self._ncodes = 1 self._codes = {0: "undef"} logger.debug("Number of codes: %s", self._ncodes) # allocate if ptype == 1: # float, assign to double ptr_pval_v = _cxtgeo.new_doublearray(ntot) ptr_ival_v = _cxtgeo.new_intarray(1) self._isdiscrete = False self._dtype = "float64" elif ptype > 1: ptr_pval_v = _cxtgeo.new_doublearray(1) ptr_ival_v = _cxtgeo.new_intarray(ntot) self._isdiscrete = True self._dtype = "int32" # number of codes and names ptr_ccodes_v = _cxtgeo.new_intarray(self._ncodes) # NB! note the SWIG trick to return modified char values; use cstring.i # inn the config and %cstring_bounded_output(char *p_codenames_v, NN); # Then the argument for *p_codevalues_v in C is OMITTED here! ier, cnames = _cxtgeo.grd3d_imp_prop_roffbin( pfile, 1, ptr_type, ptr_ncol, ptr_nrow, ptr_nlay, ptr_ncodes, name, ptr_ival_v, ptr_pval_v, ptr_ccodes_v, 0, XTGDEBUG, ) if self._isdiscrete: _gridprop_lowlevel.update_values_from_carray(self, ptr_ival_v, np.int32, delete=True) else: _gridprop_lowlevel.update_values_from_carray(self, ptr_pval_v, np.float64, delete=True) # now make dictionary of codes if self._isdiscrete: cnames = cnames.replace(";", "") cname_list = cnames.split("|") cname_list.pop() # some rubbish as last entry ccodes = [] for ino in range(0, self._ncodes): ccodes.append(_cxtgeo.intarray_getitem(ptr_ccodes_v, ino)) self._codes = dict(zip(ccodes, cname_list)) self._name = name