예제 #1
0
def show_stats():
    """Get statistics for one realisation, poro/perm filtered on facies.

    But note that values here are unweighted as total volume is not present.
    """
    # read grid
    grd = xtgeo.grid_from_file(GRIDFILE)

    # read facies (to be used as filter)
    facies = xtgeo.gridproperty_from_file(FACIESFILE, name=FACIES, grid=grd)
    print("Facies codes are: {}".format(facies.codes))

    for propname in PROPS:
        pfile = ojn(EXPATH1, ROOT + "--" + propname + EXT)
        pname = "geogrid--" + propname
        prop = xtgeo.gridproperty_from_file(pfile, name=pname, grid=grd)
        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 fixture_create_project():
    """Create a tmp RMS project for testing, populate with basic data.

    After the yield command, the teardown phase will remove the tmp RMS project.
    """
    prj1 = str(PRJ)

    print("\n******** Setup RMS project!\n")
    if isdir(prj1):
        print("Remove existing project! (1)")
        shutil.rmtree(prj1)

    project = roxar.Project.create()

    rox = xtgeo.RoxUtils(project)
    print("Roxar version is", rox.roxversion)
    print("RMS version is", rox.rmsversion(rox.roxversion))
    assert "1." in rox.roxversion

    for wfile in WELLS1:
        wobj = xtgeo.well_from_file(WELLSFOLDER1 / wfile)
        if "XP_with" in wfile:
            wobj.name = "OP2_w_repeat"

        wobj.to_roxar(project,
                      wobj.name,
                      logrun="log",
                      trajectory="My trajectory")

    # populate with cube data
    cube = xtgeo.cube_from_file(CUBEDATA1)
    cube.to_roxar(project, CUBENAME1, domain="depth")

    # populate with surface data
    rox.create_horizons_category(SURFCAT1)
    for num, name in enumerate(SURFNAMES1):
        srf = xtgeo.surface_from_file(SURFTOPS1[num])
        project.horizons.create(name, roxar.HorizonType.interpreted)
        srf.to_roxar(project, name, SURFCAT1)

    # populate with grid and props
    grd = xtgeo.grid_from_file(GRIDDATA1)
    grd.to_roxar(project, GRIDNAME1)
    por = xtgeo.gridproperty_from_file(PORODATA1, name=PORONAME1)
    por.to_roxar(project, GRIDNAME1, PORONAME1)
    zon = xtgeo.gridproperty_from_file(ZONEDATA1, name=ZONENAME1)
    zon.values = zon.values.astype(np.uint8)
    zon.to_roxar(project, GRIDNAME1, ZONENAME1)

    # save project (both an initla version and a work version) and exit
    project.save_as(prj1)
    project.close()

    yield project

    print("\n******* Teardown RMS project!\n")

    if isdir(prj1):
        print("Remove existing project! (1)")
        shutil.rmtree(prj1)
예제 #3
0
def test_import_dualperm_grid_soil():
    """Test grid with flag for dual perm setup (will also mean dual poro also)"""

    grd = xtgeo.grid_from_file(DUALFILE2.with_suffix(".EGRID"))
    grd._dualactnum.to_file("TMP/dualact.roff")

    sgas = xtgeo.gridproperty_from_file(
        DUALFILE2.with_suffix(".UNRST"),
        grid=grd,
        name="SGAS",
        date=20170121,
        fracture=False,
    )
    sgas.describe()
    tsetup.assert_almostequal(sgas.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(sgas.values[0, 1, 0], 0.0, 0.001)

    soil = xtgeo.gridproperty_from_file(
        DUALFILE2.with_suffix(".UNRST"),
        grid=grd,
        name="SOIL",
        date=20170121,
        fracture=False,
    )
    soil.describe()
    tsetup.assert_almostequal(soil.values[3, 0, 0], 0.44525, 0.001)
    tsetup.assert_almostequal(soil.values[0, 1, 0], 0.0, 0.001)
    tsetup.assert_almostequal(soil.values[3, 2, 0], 0.0, 0.0001)

    # fractures

    sgas = xtgeo.gridproperty_from_file(
        DUALFILE2.with_suffix(".UNRST"),
        grid=grd,
        name="SGAS",
        date=20170121,
        fracture=True,
    )
    tsetup.assert_almostequal(sgas.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(sgas.values[0, 1, 0], 0.0, 0.0001)

    soil = xtgeo.gridproperty_from_file(
        DUALFILE2.with_suffix(".UNRST"),
        grid=grd,
        name="SOIL",
        date=20170121,
        fracture=True,
    )
    tsetup.assert_almostequal(soil.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(soil.values[0, 1, 0], 0.011741, 0.0001)
    tsetup.assert_almostequal(soil.values[3, 2, 0], 0.11676, 0.0001)
예제 #4
0
def test_import_dualporo_grid():
    """Test grid with flag for dual porosity setup, oil water"""

    grd = xtgeo.grid_from_file(DUALFILE1.with_suffix(".EGRID"))

    assert grd.dualporo is True
    assert grd.dualperm is False
    assert grd.dimensions == (5, 3, 1)

    poro = xtgeo.gridproperty_from_file(DUALFILE1.with_suffix(".INIT"),
                                        grid=grd,
                                        name="PORO")

    tsetup.assert_almostequal(poro.values[0, 0, 0], 0.1, 0.001)
    tsetup.assert_almostequal(poro.values[1, 1, 0], 0.16, 0.001)
    tsetup.assert_almostequal(poro.values[4, 2, 0], 0.24, 0.001)
    assert poro.name == "POROM"
    poro.describe()

    poro = xtgeo.gridproperty_from_file(DUALFILE1.with_suffix(".INIT"),
                                        grid=grd,
                                        name="PORO",
                                        fracture=True)

    tsetup.assert_almostequal(poro.values[0, 0, 0], 0.25, 0.001)
    tsetup.assert_almostequal(poro.values[4, 2, 0], 0.39, 0.001)
    assert poro.name == "POROF"
    poro.describe()

    swat = xtgeo.gridproperty_from_file(
        DUALFILE1.with_suffix(".UNRST"),
        grid=grd,
        name="SWAT",
        date=20170121,
        fracture=False,
    )
    swat.describe()
    tsetup.assert_almostequal(swat.values[0, 0, 0], 0.60924, 0.001)

    swat = xtgeo.gridproperty_from_file(
        DUALFILE1.with_suffix(".UNRST"),
        grid=grd,
        name="SWAT",
        date=20170121,
        fracture=True,
    )
    swat.describe()
    tsetup.assert_almostequal(swat.values[0, 0, 0], 0.989687, 0.001)
    swat.to_file("TMP/swat.roff")
예제 #5
0
def make_map():
    """Make a map of poro or perm in lowermost K layer of the grid"""

    # read grid
    grd = xtgeo.grid_from_file(GNAMEROOT + ".EGRID")

    _ = xtgeo.gridproperty_from_file(GNAMEROOT + ".INIT",
                                     name="PORO",
                                     grid=grd)

    df = grd.dataframe()

    # make a map from the grid geometry to be used as a template

    surf = xtgeo.RegularSurface()
    surf.from_grid3d(grd)

    # get only bottom layer:
    lastlayer = df["KZ"].max()
    df = df[df["KZ"] == lastlayer].reset_index()

    # prepare as input to a Points dataframe (3 columns X Y Z)
    df = df[["X_UTME", "Y_UTMN", "PORO"]].copy()

    points = xtgeo.Points()
    points.zname = "PORO"
    points.dataframe = df

    # do gridding:
    surf.gridding(points)

    # optional plot
    surf.quickplot()
예제 #6
0
    def get_property_from_restart(self, name, date, **kwargs):

        return xtgeo.gridproperty_from_file(self.path + ".UNRST",
                                            grid=self.grid,
                                            date=date,
                                            name=name,
                                            **kwargs)
예제 #7
0
def test_values_samedate(reek_data):
    """Verify that the same date yields zero change"""
    ecldiff2roff.ecldiff2roff_main("2_R001_REEK-0", "PRESSURE",
                                   [("20000101", "20000101")])
    pressure_diff = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000101_20000101.roff")
    assert np.isclose(pressure_diff.values.mean(), 0.0)
예제 #8
0
def export_geogrid_parameters():
    """Export geogrid assosiated parameters based on user defined lists"""

    props = PROPS_SEISMIC + PROPS_OTHER

    print("Write grid properties...")
    for propname in props:
        filename = (FOLDER / (GFILE + "_" + propname)).with_suffix(".roff")
        prop = xtgeo.gridproperty_from_file(filename)
        ed = dataio.ExportData(
            name=propname,
            # parent={"name": GNAME},
            config=CFG,
            content="depth",
            unit="m",
            vertical_domain={"depth": "msl"},
            timedata=None,
            is_prediction=True,
            is_observation=False,
            verbosity=VERBOSITY,
            workflow="rms property model",
        )

        out = ed.export(prop)
        print(f"Stored {propname} as {out}")
예제 #9
0
def test_convert_grid_format_restart(tmp_path, mocker):
    """Convert an ECLIPSE SOIL from restart to roff"""

    outfile = tmp_path / "reek_grid.roff"

    mocker.patch(
        "sys.argv",
        [
            "convert_grid_format",
            "--file",
            str(RFILE2),
            "--output",
            str(outfile),
            "--mode",
            "restart",
            "--propnames",
            "SOIL",
            "--dates",
            "20000701",
            "--standardfmu",
        ],
    )
    cgf.main()

    actual_outfile = tmp_path / "reek_grid--soil--20000701.roff"

    gprop = xtgeo.gridproperty_from_file(actual_outfile)

    assert gprop.values.mean() == pytest.approx(0.0857, abs=0.001)
예제 #10
0
def loop_for_compute(
    config: dict, sinfo: ScreenInfo, _dryrun: bool = False
) -> EnsembleWellProps:
    """Collect for computing the ensemble statistics.

    Args:
        config: The input configuration dictonary
        sinfo: Messages to screen instance
        _dryrun: For testing, skipping computation
    """
    cfg = ConfigData(config)
    wcase = WellCase(
        xtgeo.well_from_file(cfg.wellfile, lognames=cfg.lognames),
        cfg.mdlog,
        cfg.mdranges,
        cfg.welldelta,
    )

    grd = None

    sinfo.oprint("Loop data over realizations...")
    used_realizations = []

    for real in cfg.reals:
        sinfo.oprint(f"Realization no. {real}")
        realiterpath = cfg.root / f"realization-{real}" / cfg.itera

        if not isinstance(grd, xtgeo.Grid) or not cfg.gridreuse:
            # one may choose to reuse grid if not structural uncertainty
            sinfo.oprint(f"Read grid geometry for realization {real}")
            gpath = realiterpath / cfg.gridfilestub
            try:
                grd = xtgeo.grid_from_file(gpath)
            except OSError:
                sinfo.oprint(f"Not able to read grid {gpath}, skip realization...")
                continue
            wcase.well.delete_logs(GCELLNAMES)
            wcase.well.make_ijk_from_grid(grd)

        for propcase in cfg.proplist:
            proppath = realiterpath / propcase.filestub
            sinfo.oprint(f"Read: {proppath}...")
            try:
                theprop = xtgeo.gridproperty_from_file(proppath)
            except OSError:
                sinfo.oprint(
                    f"Not able to read property {propcase.name} from {proppath}, "
                    "skip realization..."
                )
                continue
            theprop.geometry = grd

            if _dryrun is False:
                run_compute(real, wcase.well, propcase, theprop)
        used_realizations.append(real)

    sinfo.xprint("Delete logs referring to cells...")
    wcase.well.delete_logs(GCELLNAMES)
    return EnsembleWellProps(wcase.well, used_realizations, cfg, sinfo)
예제 #11
0
def test_values_dateorder(reek_data):
    """Verify the handling of date order in date pairs, that the
    sign of values gets correct and it negated when dates are reversed"""
    ecldiff2roff.ecldiff2roff_main("2_R001_REEK-0", "PRESSURE",
                                   [("20000101", "20000701")])
    pressure_diff1 = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000101_20000701.roff")

    # This tools works such that a reduction in pressure gives a positive value when
    # the dates "increase". This test assumes that the Reek dataset declines
    # in pressure:
    assert pressure_diff1.values.mean() > 0.0

    # Also verify the actual mean value:
    assert np.isclose(pressure_diff1.values.mean(), 29.6174076)

    # Check that when the dates are reversed, the difference is negated:
    ecldiff2roff.ecldiff2roff_main("2_R001_REEK-0", "PRESSURE",
                                   [("20000701", "20000101")])
    pressure_diff_reverse = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000701_20000101.roff")
    assert np.isclose(pressure_diff1.values.mean(),
                      -pressure_diff_reverse.values.mean())
예제 #12
0
def test_create_project():
    """Create a tmp RMS project for testing, populate with basic data"""

    prj1 = PRJ
    prj2 = PRJ + "_initial"

    if isdir(prj1):
        print("Remove existing project! (1)")
        shutil.rmtree(prj1)

    if isdir(prj2):
        print("Remove existing project! (2)")
        shutil.rmtree(prj2)

    project = roxar.Project.create()

    rox = xtgeo.RoxUtils(project)
    print("Roxar version is", rox.roxversion)
    print("RMS version is", rox.rmsversion(rox.roxversion))
    assert "1." in rox.roxversion

    # populate with cube data
    cube = xtgeo.cube_from_file(CUBEDATA1)
    cube.to_roxar(project, CUBENAME1, domain="depth")

    # populate with surface data
    rox.create_horizons_category(SURFCAT1)
    for num, name in enumerate(SURFNAMES1):
        srf = xtgeo.surface_from_file(SURFTOPS1[num])
        project.horizons.create(name, roxar.HorizonType.interpreted)
        srf.to_roxar(project, name, SURFCAT1)

    # populate with grid and props
    grd = xtgeo.grid_from_file(GRIDDATA1)
    grd.to_roxar(project, GRIDNAME1)
    por = xtgeo.gridproperty_from_file(PORODATA1, name=PORONAME1)
    por.to_roxar(project, GRIDNAME1, PORONAME1)

    # populate with well data (postponed)

    # save project (both an initla version and a work version) and exit
    project.save_as(prj1)
    project.save_as(prj2)
    project.close()
예제 #13
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)
예제 #14
0
def test_compute_some_props(configdata):
    """Test the actual compute of one well on one realization."""

    cfg = ensemble_well_props.ConfigData(configdata)

    wcase = ensemble_well_props.WellCase(
        xtgeo.well_from_file(WELLNAME2, lognames=cfg.lognames), cfg.mdlog,
        cfg.mdranges)
    grd = xtgeo.grid_from_file(GFILE1)
    wcase.well.make_ijk_from_grid(grd)

    myprops = [FACIESFILE1, POROFILE1]
    for ncount, pcase in enumerate(myprops):

        prop = xtgeo.gridproperty_from_file(pcase)
        prop.geometry = grd

        ensemble_well_props.run_compute(0, wcase.well, cfg.proplist[ncount],
                                        prop)

    assert "Facies_r0" in wcase.well.dataframe
    assert wcase.well.dataframe["PHIT_r0"].mean() == pytest.approx(0.171533,
                                                                   abs=0.001)
예제 #15
0
def test_values_multiple_datepairs(reek_data):
    """Check that differences for multiple date pairs are handled correctly

    This was a bug in subscript up to v0.12.0"""

    # First establish some thruths:
    ecldiff2roff.ecldiff2roff_main("2_R001_REEK-0", "PRESSURE",
                                   [("20000101", "20000701")])
    pressure_diff1_singlerun = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000101_20000701.roff")
    assert np.isclose(pressure_diff1_singlerun.values.mean(), 29.6174076)

    ecldiff2roff.ecldiff2roff_main("2_R001_REEK-0", "PRESSURE",
                                   [("20000701", "20010201")])
    pressure_diff2_singlerun = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000701_20010201.roff")
    assert np.isclose(pressure_diff2_singlerun.values.mean(), 12.570824)

    ecldiff2roff.ecldiff2roff_main("2_R001_REEK-0", "PRESSURE",
                                   [("20000101", "20010201")])
    pressure_diff3_singlerun = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000101_20010201.roff")
    assert np.isclose(pressure_diff3_singlerun.values.mean(), 42.18823213)

    # Then run with multiple datepairs:
    ecldiff2roff.ecldiff2roff_main(
        "2_R001_REEK-0",
        "PRESSURE",
        [("20000101", "20000701"), ("20000701", "20010201"),
         ("20000101", "20010201")],
    )
    pressure_diff1 = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000101_20000701.roff")
    pressure_diff2 = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000701_20010201.roff")
    pressure_diff3 = xtgeo.gridproperty_from_file(
        "eclgrid--pressure--20000101_20010201.roff")
    assert np.isclose(pressure_diff1.values.mean(),
                      pressure_diff1_singlerun.values.mean())
    assert np.isclose(pressure_diff2.values.mean(),
                      pressure_diff2_singlerun.values.mean())
    assert np.isclose(pressure_diff3.values.mean(),
                      pressure_diff3_singlerun.values.mean())
예제 #16
0
def test_import_dualperm_grid():
    """Test grid with flag for dual perm setup (hence dual poro also) water/oil"""

    grd = xtgeo.grid_from_file(DUALFILE2 + ".EGRID")

    assert grd.dualporo is True
    assert grd.dualperm is True
    assert grd.dimensions == (5, 3, 1)
    grd.to_file(os.path.join(TMPDIR, "dual2.roff"))

    poro = xtgeo.gridproperty_from_file(DUALFILE2 + ".INIT",
                                        grid=grd,
                                        name="PORO")
    print(poro.values)

    tsetup.assert_almostequal(poro.values[0, 0, 0], 0.1, 0.001)
    tsetup.assert_almostequal(poro.values[1, 1, 0], 0.16, 0.001)
    tsetup.assert_almostequal(poro.values[4, 2, 0], 0.24, 0.001)
    assert poro.name == "POROM"
    poro.describe()

    poro = xtgeo.gridproperty_from_file(DUALFILE2 + ".INIT",
                                        grid=grd,
                                        name="PORO",
                                        fracture=True)

    tsetup.assert_almostequal(poro.values[0, 0, 0], 0.25, 0.001)
    tsetup.assert_almostequal(poro.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(poro.values[4, 2, 0], 0.39, 0.001)
    assert poro.name == "POROF"
    poro.describe()

    perm = xtgeo.gridproperty_from_file(DUALFILE2 + ".INIT",
                                        grid=grd,
                                        name="PERMX")

    tsetup.assert_almostequal(perm.values[0, 0, 0], 100.0, 0.001)
    tsetup.assert_almostequal(perm.values[3, 0, 0], 100.0, 0.001)
    tsetup.assert_almostequal(perm.values[0, 1, 0], 0.0, 0.001)
    tsetup.assert_almostequal(perm.values[4, 2, 0], 100, 0.001)
    assert perm.name == "PERMXM"
    perm.to_file(os.path.join(TMPDIR, "dual2_permxm.roff"))

    perm = xtgeo.gridproperty_from_file(DUALFILE2 + ".INIT",
                                        grid=grd,
                                        name="PERMX",
                                        fracture=True)

    tsetup.assert_almostequal(perm.values[0, 0, 0], 100.0, 0.001)
    tsetup.assert_almostequal(perm.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(perm.values[0, 1, 0], 100.0, 0.001)
    tsetup.assert_almostequal(perm.values[4, 2, 0], 100, 0.001)
    assert perm.name == "PERMXF"
    perm.to_file(os.path.join(TMPDIR, "dual2_permxf.roff"))

    swat = xtgeo.gridproperty_from_file(DUALFILE2 + ".UNRST",
                                        grid=grd,
                                        name="SWAT",
                                        date=20170121,
                                        fracture=False)
    tsetup.assert_almostequal(swat.values[3, 0, 0], 0.55475, 0.001)

    soil = xtgeo.gridproperty_from_file(DUALFILE2 + ".UNRST",
                                        grid=grd,
                                        name="SOIL",
                                        date=20170121,
                                        fracture=False)
    print(soil.values)
    tsetup.assert_almostequal(soil.values[3, 0, 0], 0.44525, 0.001)
    tsetup.assert_almostequal(soil.values[0, 1, 0], 0.0, 0.001)
    assert np.ma.is_masked(soil.values[1, 2, 0])
    tsetup.assert_almostequal(soil.values[3, 2, 0], 0.0, 0.001)
    tsetup.assert_almostequal(soil.values[4, 2, 0], 0.41271, 0.001)

    swat = xtgeo.gridproperty_from_file(DUALFILE2 + ".UNRST",
                                        grid=grd,
                                        name="SWAT",
                                        date=20170121,
                                        fracture=True)
    swat.describe()
    assert "SWATF" in swat.name

    tsetup.assert_almostequal(swat.values[3, 0, 0], 0.0, 0.001)
    swat.to_file("TMP/swat.roff")
예제 #17
0
 def get_property_from_init(self, name, **kwargs):
     return xtgeo.gridproperty_from_file(self.path + ".INIT",
                                         grid=self.grid,
                                         name=name,
                                         **kwargs)
예제 #18
0
def test_import_dualperm_grid_sgas():
    """Test grid with flag for dual perm/poro setup gas/water"""

    grd = xtgeo.grid_from_file(DUALFILE3 + ".EGRID")

    sgas = xtgeo.gridproperty_from_file(DUALFILE3 + ".UNRST",
                                        grid=grd,
                                        name="SGAS",
                                        date=20170121,
                                        fracture=False)
    sgas.describe()
    tsetup.assert_almostequal(sgas.values[3, 0, 0], 0.06639, 0.001)
    tsetup.assert_almostequal(sgas.values[0, 1, 0], 0.0, 0.001)
    tsetup.assert_almostequal(sgas.values[4, 2, 0], 0.10696, 0.001)
    assert "SGASM in sgas.name"

    swat = xtgeo.gridproperty_from_file(DUALFILE3 + ".UNRST",
                                        grid=grd,
                                        name="SWAT",
                                        date=20170121,
                                        fracture=False)
    swat.describe()
    tsetup.assert_almostequal(swat.values[3, 0, 0], 0.93361, 0.001)
    tsetup.assert_almostequal(swat.values[0, 1, 0], 0.0, 0.001)
    tsetup.assert_almostequal(swat.values[4, 2, 0], 0.89304, 0.001)
    assert "SWATM in swat.name"

    # shall be not soil actually
    soil = xtgeo.gridproperty_from_file(DUALFILE3 + ".UNRST",
                                        grid=grd,
                                        name="SOIL",
                                        date=20170121,
                                        fracture=False)
    soil.describe()
    tsetup.assert_almostequal(soil.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(soil.values[0, 1, 0], 0.0, 0.001)
    assert "SOILM" in soil.name

    # fractures

    sgas = xtgeo.gridproperty_from_file(DUALFILE3 + ".UNRST",
                                        grid=grd,
                                        name="SGAS",
                                        date=20170121,
                                        fracture=True)
    sgas.describe()
    tsetup.assert_almostequal(sgas.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(sgas.values[0, 1, 0], 0.0018198, 0.001)
    tsetup.assert_almostequal(sgas.values[4, 2, 0], 0.17841, 0.001)
    assert "SGASF" in sgas.name

    swat = xtgeo.gridproperty_from_file(DUALFILE3 + ".UNRST",
                                        grid=grd,
                                        name="SWAT",
                                        date=20170121,
                                        fracture=True)
    swat.describe()
    tsetup.assert_almostequal(swat.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(swat.values[0, 1, 0], 0.99818, 0.001)
    tsetup.assert_almostequal(swat.values[4, 2, 0], 0.82159, 0.001)
    assert "SWATF" in swat.name

    # shall be not soil actually
    soil = xtgeo.gridproperty_from_file(DUALFILE3 + ".UNRST",
                                        grid=grd,
                                        name="SOIL",
                                        date=20170121,
                                        fracture=True)
    soil.describe()
    tsetup.assert_almostequal(soil.values[3, 0, 0], 0.0, 0.001)
    tsetup.assert_almostequal(soil.values[0, 1, 0], 0.0, 0.001)
    assert "SOILF" in soil.name
예제 #19
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
예제 #20
0
def test_get_cell_volume():
    """Test hexahedron (cell) bulk volume valculation"""

    # box
    grd = xtgeo.Grid(TESTGRID3)

    vol1 = grd.get_cell_volume((1, 1, 1))
    assert vol1 == pytest.approx(3821600, rel=0.01)

    # banal6
    grd = xtgeo.Grid(TESTGRID2)

    vol1 = grd.get_cell_volume((1, 1, 1))
    vol2 = grd.get_cell_volume((4, 1, 1))
    vol3 = grd.get_cell_volume((1, 2, 1))
    vol4 = grd.get_cell_volume((3, 1, 2))

    assert vol1 == pytest.approx(1679.7, rel=0.01)
    assert vol2 == pytest.approx(2070.3, rel=0.01)
    assert vol3 == pytest.approx(1289.1, rel=0.01)
    assert vol4 == pytest.approx(593.75, rel=0.01)

    # gridqc1
    grd = xtgeo.Grid(TESTGRID)
    tbulk_rms = xtgeo.gridproperty_from_file(TESTGRID_TBULK)

    rmean = []
    for prec in [1, 2, 4]:
        ntot = 0
        nfail = 0
        ratioarr = []
        for icol in range(grd.ncol):
            for jrow in range(grd.nrow):
                for klay in range(grd.nlay):
                    vol1a = grd.get_cell_volume(
                        (icol, jrow, klay), zerobased=True, precision=prec
                    )
                    if vol1a is not None:
                        vol1b = tbulk_rms.values[icol, jrow, klay]
                        ratio = vol1a / vol1b
                        ratioarr.append(ratio)
                        ntot += 1
                        if ratio < 0.98 or ratio > 1.02:
                            nfail += 1
                            logger.info("%s %s %s:  %s", icol, jrow, klay, ratio)
                            logger.info("XTGeo vs RMS %s %s", vol1a, vol1b)
                        if prec > 1:
                            assert vol1a == pytest.approx(vol1b, 0.0001)

        rarr = np.array(ratioarr)
        rmean.append(rarr.mean())
        logger.info(
            "Prec: %s, Fails of total %s vs %s, mean/min/max: %s %s %s",
            prec,
            nfail,
            ntot,
            rarr.mean(),
            rarr.min(),
            rarr.max(),
        )
        if prec > 1:
            assert rarr == pytest.approx(1.0, 0.0001)
            assert nfail == 0

    # ensure that mean difference get closer to 1 with increasing precision?
    for ravg in rmean:
        diff = abs(1.0 - ravg)
        logger.info("Diff from 1: %s", diff)
예제 #21
0
def load_grid_parameter(grid: Optional[xtgeo.Grid],
                        gridparameterpath: str) -> xtgeo.GridProperty:
    return xtgeo.gridproperty_from_file(gridparameterpath, grid=grid)
예제 #22
0
def load_grid_parameter(grid, gridparameterpath):
    return xtgeo.gridproperty_from_file(gridparameterpath, grid=grid)