def test_rox_get_modify_set_grid(roxar_project): """Get, modify and set a grid from a RMS project.""" grd = xtgeo.grid_from_roxar(roxar_project, GRIDNAME1) grd1 = grd.copy() grd.translate_coordinates(translate=(200, 3000, 300)) grd.to_roxar(roxar_project, GRIDNAME1 + "_edit1") grd2 = xtgeo.grid_from_roxar(roxar_project, GRIDNAME1 + "_edit1") assert grd2.dimensions == grd1.dimensions
def test_getwell_and_find_ijk_gfb2(): """Get well from a RMS project, and find IJK from grid.""" if not os.path.isdir(BPROJ[roxv]): pass logger.info("GFB case, reading a wells from RMS well folder") xwell = xtgeo.well.Well() xwell.from_roxar( BPROJ[roxv], "34_10-A-15", trajectory="Drilled trajectory", logrun="data", lognames=["ZONELOG"], ) tsetup.assert_equal(xwell.nrow, 3250, "NROW of well") tsetup.assert_equal(xwell.rkb, 82.20, "RKB of well") # now read a grid grd = xtgeo.grid_from_roxar(BPROJ[roxv], "gfb_sim") xwell.make_ijk_from_grid(grd) print(xwell.dataframe.head()) xwell.to_file(join(TMPD, "gfb2_well_ijk.rmswell"))
def test_getwell_and_find_ijk_gfb2(): """Get well from a RMS project, and find IJK from grid.""" if not os.path.isdir(BPROJ[roxv]): pass logger.info('GFB case, reading a wells from RMS well folder') xwell = xtgeo.well.Well() xwell.from_roxar(BPROJ[roxv], '34_10-A-15', trajectory='Drilled trajectory', logrun='data', lognames=['ZONELOG']) tsetup.assert_equal(xwell.nrow, 3250, 'NROW of well') tsetup.assert_equal(xwell.rkb, 82.20, 'RKB of well') # now read a grid grd = xtgeo.grid_from_roxar(BPROJ[roxv], 'gfb_sim') xwell.make_ijk_from_grid(grd) print(xwell.dataframe.head()) xwell.to_file(join(TMPD, 'gfb2_well_ijk.rmswell'))
def test_rox_get_modify_set_grid(): """Get, modify and set a grid from a RMS project.""" grd = xtgeo.grid_from_roxar(PRJ, GRIDNAME1) grd.translate_coordinates(translate=(200, 3000, 300)) grd.to_roxar(PRJ, GRIDNAME1 + "_edit1")
def read_grid(self, gridname, reuse): """Read 3D grid (which is required), from file or RMS""" gridname = gridname if self._project is not None else join( self._path, gridname) CMN.print_debug(f"GRIDNAME: {gridname}") CMN.print_info("Reading grid geometry...") if ("grid" not in reuse) or (gridname not in self._xtgdata["grid"]): self._grid = (xtgeo.Grid(gridname) if self._project is None else xtgeo.grid_from_roxar(self._project, gridname)) self._xtgdata["grid"][gridname] = self._grid self._xtgdata["gridprops"][gridname] = {} else: CMN.print_info(f"Reusing grid {gridname}") self._grid = self._xtgdata["grid"][gridname]
def extract_grid_zone_tops( project: Optional[_roxar.Project] = None, well_list: Optional[list] = None, logrun: str = "log", trajectory: str = "Drilled trajectory", gridzonelog: str = None, mdlogname: str = None, grid: str = None, zone_param: str = None, alias_file: str = None, rms_name: str = "RMS_WELL_NAME", ecl_name: str = "ECLIPSE_WELL_NAME", ) -> pd.DataFrame: """ Function for extracting top and base from gridzones, both in TVD and MD. A pandas dataframe will be returned. Users can either input a pre-generated gridzonelog or a grid and a zone parameter for computing the gridzonelog. The function works both inside RMS and outside with file input. If input from files, and a MD log is not present in the well a quasi md log will be computed and used. """ use_gridzonelog = False if gridzonelog is None else True if not use_gridzonelog: if grid is not None and zone_param is not None: if project is not None: mygrid = xtgeo.grid_from_roxar(project, grid) gridzones = xtgeo.gridproperty_from_roxar(project, grid, zone_param) else: mygrid = xtgeo.grid_from_file(grid) gridzones = xtgeo.gridproperty_from_file(zone_param, grid=mygrid) gridzones.name = "Zone" else: raise ValueError("Specify either 'gridzonelog' or 'grid' and 'zone_param") dfs = [] if well_list is None: well_list = [] for well in well_list: try: if project is not None: xtg_well = xtgeo.well_from_roxar( project, str(well), trajectory=trajectory, logrun=logrun, inclmd=True, ) else: xtg_well = xtgeo.well_from_file(str(well), mdlogname=mdlogname) # quasi md log will be computed xtg_well.geometrics() except (ValueError, KeyError): continue # if no gridzonelog create one from the zone parameter if not use_gridzonelog: xtg_well.get_gridproperties(gridzones, mygrid) gridzonelog = "Zone_model" if xtg_well.dataframe[gridzonelog].isnull().values.all(): continue # Set gridzonelog as zonelog and extract zonation tops from it xtg_well.zonelogname = gridzonelog dframe = xtg_well.get_zonation_points(top_prefix="", use_undef=True) dframe.rename( columns={ "Z_TVDSS": "TOP_TVD", xtg_well.mdlogname: "TOP_MD", "Zone": "ZONE_CODE", "WellName": "WELL", }, inplace=True, ) # find deepest point in well while in grid df_max = ( xtg_well.dataframe[["Z_TVDSS", xtg_well.mdlogname, gridzonelog]] .dropna() .sort_values(by=xtg_well.mdlogname) ) # create base picks also dframe["BASE_TVD"] = dframe["TOP_TVD"].shift(-1) dframe["BASE_MD"] = dframe["TOP_MD"].shift(-1) dframe.at[dframe.index[-1], "BASE_TVD"] = df_max.iloc[-1]["Z_TVDSS"] dframe.at[dframe.index[-1], "BASE_MD"] = df_max.iloc[-1][xtg_well.mdlogname] # adjust zone values to get correct zone information dframe["ZONE_CODE"] = shift_zone_values(dframe["ZONE_CODE"].values.copy()) dframe["ZONE"] = ( dframe["ZONE_CODE"] .map(xtg_well.get_logrecord(xtg_well.zonelogname)) .fillna("Outside") ) dfs.append(dframe.drop(columns=["TopName", "Q_INCL", "Q_AZI"])) df = pd.concat(dfs) if alias_file is not None: well_dict = make_alias_dict(alias_file, rms_name, ecl_name) df["WELL"] = df["WELL"].replace(well_dict) return df
def _read_from_rms(self, data): """Read data from inside RMS or via Roxar API""" _get_verbosity(self, data) self._project = data["project"] reuse_grid = False if "grid" in data.keys(): gridname = data["grid"] if gridname == self._gridname: self.print_info("Grid is already loaded") reuse_grid = True # grid is already loaded else: self.print_info("Reading grid...") self.print_debug("GRIDNAME: {}".format(gridname)) self._grid = xtgeo.grid_from_roxar(self._project, gridname) self._gridname = gridname self.print_debug("Looking for zone...") if "zone" in data.keys(): if reuse_grid and data["zone"] == self._gridzonename: self.print_info("Grid zone is already loaded") else: self._gridzone = xtgeo.gridproperty_from_roxar( self._project, data["grid"], data["zone"] ) self._gridzonename = data["zone"] self.print_debug("GRIDZONE: {}".format(self._gridzonename)) if "wells" in data.keys(): # wells area allowed to spesified by regular expressions, e.g. # ["55_33-[123]", "55_33-.*A.*"] if "zonelogname" in data: self._zonelogname = data["zonelogname"] wdata = [] rmswells = [wll.name for wll in self._project.wells] self.print_debug("All RMS wells: {}".format(rmswells)) if not isinstance(data["wells"], list): raise ValueError("Wells input must be a list") self.print_debug("Data wells to match: {}".format(data["wells"])) for rmswell in rmswells: for wreg in data["wells"]: self.print_debug("Trying match {} vs re {}".format(rmswell, wreg)) if re.match(wreg, rmswell): wdata.append( xtgeo.well_from_roxar( self._project, rmswell, logrun=self._wlogrun, trajectory=self._wtrajectory, lognames=[self._zonelogname], ) ) self.print_info("Regex match found, RMS well: {}".format(rmswell)) self._wells = xtgeo.Wells() self._wells.wells = wdata