Пример #1
0
    def read_wells(self, wells, welltype="wells", settings=False, reuse=None):
        """Reading wells"""

        settings = settings if settings else {}
        wellist = self._well_preparations(wells)

        CMN.print_info("Reading wells...")
        xtg_wells = []
        if "wells" in reuse:
            reused_wells, wellist = self._reuse_wells(wellist, welltype)
            xtg_wells = reused_wells

        for well in wellist:
            try:
                if welltype == "wells":
                    mywell = (xtgeo.well_from_file(
                        well, lognames=settings.get("lognames", "all")) if
                              self._project is None else xtgeo.well_from_roxar(
                                  project=self._project,
                                  name=well,
                                  lognames=settings.get("lognames", "all"),
                                  logrun=wells.get("logrun", "log"),
                                  trajectory=wells.get("trajectory",
                                                       "Drilled trajectory"),
                              ))
                else:
                    mywell = (xtgeo.blockedwell_from_file(well)
                              if self._project is None else
                              xtgeo.blockedwell_from_roxar(
                                  project=self._project,
                                  gname=wells.get("grid", "Geogrid"),
                                  bwname=wells.get("bwname", "BW"),
                                  wname=well,
                                  lognames=settings.get("lognames", "all"),
                              ))
                xtg_wells.append(mywell)
                self._xtgdata[welltype][well] = mywell
                CMN.print_debug(well)

            except ValueError as verr:
                print(f"Could not read well {well}: {verr}")

        CMN.print_debug(f"All valid welldata: {xtg_wells}")

        for mywell in xtg_wells:
            if "depthrange" in settings and settings["depthrange"] is not None:
                tmin, tmax = settings["depthrange"]
                mywell.limit_tvd(tmin, tmax)
            if "rescale" in settings and settings["rescale"] is not None:
                mywell.rescale(settings["rescale"])

        if xtg_wells:
            if welltype == "wells":
                self._wells = xtgeo.Wells()
                self._wells.wells = xtg_wells
            else:
                self._bwells = xtgeo.BlockedWells()
                self._bwells.wells = xtg_wells
        else:
            raise RuntimeError("No wells read, wrong settings?")
Пример #2
0
def test_rox_wells():
    """Various tests on Roxar wells."""
    well = xtgeo.well_from_roxar(PRJ,
                                 "OP_2",
                                 trajectory="My trajectory",
                                 logrun="log")
    assert "Zonelog" in well.lognames

    assert well.dataframe["Poro"].mean() == pytest.approx(0.1637623936)
Пример #3
0
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
Пример #4
0
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