Пример #1
0
def show_stats_inside_rms():
    """Get statistics for one realisation, poro/perm filtered on facies.

    This is an 'inside RMS' version; should work given runrmsx <project>
    but not tested. Focus on syntax for getting properties, otherwise code
    is quite similar.
    """
    prj = project  # type: ignore # noqa # pylint: disable=undefined-variable

    # names of icons...
    gridmodel = "Reek"
    faciesname = "Facies"
    propnames = ["Poro", "Perm"]

    # read facies (to be used as filter)
    facies = xtgeo.gridproperty_from_roxar(prj, gridmodel, faciesname)
    print("Facies codes are: {}".format(facies.codes))

    for propname in propnames:
        prop = xtgeo.gridproperty_from_roxar(prj, gridmodel, propname)
        print("Working with {}".format(prop.name))

        # now find statistics for each facies, and all facies
        for key, fname in facies.codes.items():
            avg = prop.values[facies.values == key].mean()
            std = prop.values[facies.values == key].std()
            print("For property {} in facies {}, avg is {:10.3f} and "
                  "stddev is {:9.3f}".format(propname, fname, avg, std))

        avg = prop.values.mean()
        std = prop.values.std()
        print("For property {} in ALL facies, avg is {:10.3f} and "
              "stddev is {:9.3f}".format(propname, avg, std))
Пример #2
0
def test_rox_get_gridproperty():
    """Get a grid property from a RMS project."""
    print("Project is {}".format(PRJ))

    poro = xtgeo.gridproperty_from_roxar(PRJ, GRIDNAME1, PORONAME1)

    assert poro.values.mean() == pytest.approx(0.16774, abs=0.001)
    assert poro.dimensions == (40, 64, 14)

    zone = xtgeo.gridproperty_from_roxar(PRJ, GRIDNAME1, ZONENAME1)
    assert "int" in str(zone.values.dtype)

    zone._roxar_dtype = np.int32
    with pytest.raises(TypeError):
        zone.to_roxar(PRJ, GRIDNAME1, ZONENAME1)
Пример #3
0
def test_rox_get_gridproperty():
    """Get a grid property from a RMS project."""

    print("Project is {}".format(PRJ))

    poro = xtgeo.gridproperty_from_roxar(PRJ, GRIDNAME1, PORONAME1)

    tsetup.assert_almostequal(poro.values.mean(), 0.16774, 0.001)
    assert poro.dimensions == (40, 64, 14)
Пример #4
0
def test_rox_get_modify_set_gridproperty():
    """Get and set a grid property from a RMS project."""
    poro = xtgeo.gridproperty_from_roxar(PRJ, GRIDNAME1, PORONAME1)

    adder = 0.9
    poro.values = poro.values + adder

    poro.to_roxar(PRJ, GRIDNAME1, PORONAME1 + "_NEW")

    poro.from_roxar(PRJ, GRIDNAME1, PORONAME1 + "_NEW")
    assert poro.values[1, 0, 0] == pytest.approx(0.14942 + adder, abs=0.0001)
Пример #5
0
def test_rox_get_modify_set_gridproperty():
    """Get and set a grid property from a RMS project."""

    poro = xtgeo.gridproperty_from_roxar(PRJ, GRIDNAME1, PORONAME1)

    adder = 0.9
    poro.values = poro.values + adder

    poro.to_roxar(PRJ, GRIDNAME1, PORONAME1 + "_NEW")

    poro.from_roxar(PRJ, GRIDNAME1, PORONAME1 + "_NEW")
    tsetup.assert_almostequal(poro.values[1, 0, 0], 0.14942 + adder, 0.0001)
Пример #6
0
    def read_gridprops(self, gridprops, gridname=None, reuse=None):
        """Read 3D grid props, from file or RMS."""

        gridname = gridname if self._project is not None else join(
            self._path, gridname)

        CMN.print_info("Reading grid properties...")
        gprops = []
        if "gridprops" in reuse:
            reused_gprops, gridprops = self._reuse_gridprops(
                gridprops, gridname)
            gprops = reused_gprops

        if self._project is None:
            for gprop in gridprops:
                if isinstance(gprop, list):
                    pname, pfile = gprop
                else:
                    pfile = gprop
                    pname = "unknown"

                gridproppath = join(self._path, pfile)

                xtg_gprop = xtgeo.gridproperty_from_file(gridproppath,
                                                         name=pname,
                                                         grid=self.grid)
                xtg_gprop.name = pname if pname != "unknown" else pfile
                gprops.append(xtg_gprop)
                if isinstance(gprop, list):
                    self._xtgdata["gridprops"][gridname][tuple(
                        gprop)] = xtg_gprop
                else:
                    self._xtgdata["gridprops"][gridname][gprop] = xtg_gprop
        else:
            # read from RMS/ROXAPI
            for pname in gridprops:
                xtg_gprop = xtgeo.gridproperty_from_roxar(
                    self._project, gridname, pname)
                gprops.append(xtg_gprop)
                self._xtgdata["gridprops"][gridname][pname] = xtg_gprop

        self._gridprops = xtgeo.GridProperties()
        self._gridprops.append_props(gprops)
Пример #7
0
def test_qcreset():
    """Test qcreset metod in roxapi."""
    # ==================================================================================
    # pylint: disable=invalid-name
    from fmu.tools.rms import qcreset

    rox = xtgeo.RoxUtils(project=PRJ)

    SETUP1 = {
        "project": rox._project,
        "horizons": {
            "DS_whatever": ["TopReek", "MidReek"],
        },
        "grid_models": {
            "Simgrid": ["PORO"],
        },
        "value": 0.088,
    }

    SETUP2 = {
        "project": rox._project,
        "horizons": {
            "DS_whatever": ["TopReek", "MidReek"],
        },
        "grid_models": {
            "Simgrid": ["PORO"],
        },
    }

    qcreset.set_data_constant(SETUP1)

    topr = xtgeo.surface_from_roxar(rox._project, "TopReek", "DS_whatever")
    assert topr.values.mean() == pytest.approx(0.088)

    poro = xtgeo.gridproperty_from_roxar(rox._project, "Simgrid", "PORO")
    assert poro.values.mean() == pytest.approx(0.088)

    qcreset.set_data_empty(SETUP2)

    top = rox._project.horizons["TopReek"]["DS_whatever"]

    assert top.is_empty() is True
Пример #8
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
Пример #9
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