Beispiel #1
0
def test_pillars():
    """Test that we can build a dataframe of pillar statistics"""
    eclfiles = EclFiles(DATAFILE)
    pillars_df = pillars.df(eclfiles)
    assert "PILLAR" in pillars_df
    assert "VOLUME" in pillars_df
    assert "PORV" in pillars_df
    assert "PERMX" in pillars_df
    assert "X" in pillars_df
    assert "Y" in pillars_df
    assert "PORO" in pillars_df
    assert "OILVOL" not in pillars_df
    assert "FIPNUM" not in pillars_df
    assert "EQLNUM" not in pillars_df
    assert "OWC" not in pillars_df
    assert "GOC" not in pillars_df
    assert len(pillars_df) == 2560

    pillars_df = pillars.df(eclfiles, region="FIPNUM")
    assert "FIPNUM" in pillars_df
    assert len(pillars_df["FIPNUM"].unique()) == 6
    assert "OILVOL" not in pillars_df

    pillars_df = pillars.df(eclfiles, rstdates="first")
    firstdate = str(grid.dates2rstindices(eclfiles, "first")[1][0])
    assert "OILVOL@" + firstdate in pillars_df
    assert "GASVOL@" + firstdate in pillars_df
    assert "WATVOL@" + firstdate in pillars_df

    pillars_df = pillars.df(eclfiles, rstdates="last", soilcutoff=0.2, sgascutoff=0.2)
    lastdate = str(grid.dates2rstindices(eclfiles, "last")[1][0])
    assert "OWC@" + lastdate in pillars_df
    assert "GOC@" + lastdate not in pillars_df  # Because the dataset has no GAS...
Beispiel #2
0
def test_rstdates():
    eclfiles = EclFiles(DATAFILE)
    # rstfile = eclfiles.get_rstfile()

    alldates = grid.rstdates(eclfiles)
    assert len(alldates) == 4

    didx = grid.dates2rstindices(eclfiles, "all")
    assert len(didx[0]) == len(alldates)
    assert len(didx[1]) == len(alldates)
    assert isinstance(didx[0][0], int)
    assert isinstance(didx[1][0], datetime.date)
    assert didx[1][0] == alldates[0]
    assert didx[1][-1] == alldates[-1]

    first = grid.dates2rstindices(eclfiles, "first")
    assert first[1][0] == alldates[0]

    last = grid.dates2rstindices(eclfiles, "last")
    assert last[1][0] == alldates[-1]

    dates = grid.rstdates(eclfiles)
    assert isinstance(dates, list)

    # Test with missing RST file:
    eclfiles = EclFiles("BOGUS.DATA")
    with pytest.raises(IOError):
        eclfiles.get_rstfile()
Beispiel #3
0
def test_get_available_rst_dates():
    """Test the support of dates in restart files"""
    eclfiles = EclFiles(REEK)
    # rstfile = eclfiles.get_rstfile()

    alldates = grid.get_available_rst_dates(eclfiles)
    assert len(alldates) == 4

    didx = grid.dates2rstindices(eclfiles, "all")
    assert len(didx[0]) == len(alldates)
    assert len(didx[1]) == len(alldates)
    assert isinstance(didx[0][0], int)
    assert isinstance(didx[1][0], datetime.date)
    assert didx[1][0] == alldates[0]
    assert didx[1][-1] == alldates[-1]

    somedate = grid.dates2rstindices(eclfiles, "2000-07-01")
    assert somedate[1] == [alldates[1]]

    with pytest.raises(ValueError, match="date 1999-09-09 not found in UNRST file"):
        grid.dates2rstindices(eclfiles, "1999-09-09")

    with pytest.raises(ValueError, match="date 1999-0909 not understood"):
        grid.dates2rstindices(eclfiles, "1999-0909")

    expl_date = grid.dates2rstindices(eclfiles, datetime.date(2000, 7, 1))
    assert expl_date[1] == [alldates[1]]

    expl_datetime = grid.dates2rstindices(
        eclfiles, datetime.datetime(2000, 7, 1, 0, 0, 0)
    )
    assert expl_datetime[1] == [alldates[1]]

    expl_list_datetime = grid.dates2rstindices(eclfiles, [datetime.date(2000, 7, 1)])
    assert expl_list_datetime[1] == [alldates[1]]

    # For list input, only datetime.date objects are allowed:
    expl_list2_date = grid.dates2rstindices(
        eclfiles, [datetime.date(2000, 7, 1), datetime.date(2001, 2, 1)]
    )
    assert expl_list2_date[1] == [alldates[1], alldates[2]]

    with pytest.raises(ValueError, match="None of the requested dates were found"):
        grid.dates2rstindices(eclfiles, ["2000-07-01", "2001-02-01"])

    with pytest.raises(ValueError, match="None of the requested dates were found"):
        grid.dates2rstindices(
            eclfiles,
            [
                datetime.datetime(2000, 7, 1, 0, 0, 0),
                datetime.datetime(2001, 2, 1, 0, 0, 0),
            ],
        )

    with pytest.raises(ValueError, match="not understood"):
        grid.dates2rstindices(eclfiles, {"2000-07-01": "2001-02-01"})

    first = grid.dates2rstindices(eclfiles, "first")
    assert first[1][0] == alldates[0]

    last = grid.dates2rstindices(eclfiles, "last")
    assert last[1][0] == alldates[-1]

    dates = grid.get_available_rst_dates(eclfiles)
    assert isinstance(dates, list)

    # Test with missing RST file:
    eclfiles = EclFiles("BOGUS.DATA")
    with pytest.raises(IOError):
        eclfiles.get_rstfile()
Beispiel #4
0
def df(
    eclfiles: EclFiles,
    region: str = None,
    rstdates: Optional[Union[str, datetime.date, List[datetime.date]]] = None,
    soilcutoff: float = 0.2,
    sgascutoff: float = 0.7,
    swatcutoff: float = 0.7,
    stackdates: bool = False,
) -> pd.DataFrame:
    """Produce a dataframe with pillar information

    This is the "main" function for Python API users
    Produces a dataframe with data for each I-J combination
    (in the column PILLAR), and if a region parameter is
    supplied, also pr. region.

    PORV is the summed porevolume of the pillar (in the region),
    VOLUME is bulk volume, and PORO is porevolume weighted porosity
    PERM columns contain unweighted value averages, use with caution.

    If a restart date is picked, then SWAT and SGAS will
    be used to compute volumes pr. phase, WATVOL, OILVOL and GASVOL. The
    columns with dynamic data will include the date in the column headers
    like SWAT@2009-01-01

    Args:
        region: A parameter the pillars will be split
            on. Typically EQLNUM or FIPNUM. Set to empty string
            or None to avoid any region grouping.
        rstdates: Dates for which restart data
            is to be extracted. The string can
            be in ISO-format, or one of the mnenomics
            'first', 'last' or 'all'. It can also be a list
            of datetime.date.
        soilcutoff: If not None, an oil-water contact will
            be estimated pr. pillar, based on the deepest cell with
            SOIL above the given cutoff. Value is put in column OWC.
        sgascuttof: If not None, a gas contact will be
            estimated pr pillar, based on the deepest cell with
            SGAS above the given cutoff. Value is put in column GOC.
        swatcutoff: OWC or GWC is only computed for pillars
            where at least one cell is above this value.
        stackdates: If true, a column
            called DATE will be added and data for all restart
            dates will be added in a stacked manner.
    """
    # List of vectors we want, conservative in order to save memory and cputime:
    vectors = []
    if region:
        vectors.append(region)
    vectors.extend(["POR*", "PERM*", "SWAT", "SGAS", "1OVERBO", "1OVERBG"])
    grid_df = grid.df(eclfiles,
                      rstdates=rstdates,
                      vectors=vectors,
                      dateinheaders=True)

    rstdates_iso = grid.dates2rstindices(eclfiles, rstdates)[2]

    grid_df["PILLAR"] = grid_df["I"].astype(str) + "-" + grid_df["J"].astype(
        str)
    logger.info("Computing pillar statistics")
    groupbies = ["PILLAR"]
    if region:
        if region not in grid_df:
            logger.warning("Region parameter %s not found, ignored", region)
        else:
            groupbies.append(region)
            grid_df[region] = grid_df[region].astype(int)

    for datestr in rstdates_iso:
        logger.info("Dynamic volumes for %s", datestr)
        volumes = compute_volumes(grid_df, datestr=datestr)
        grid_df = pd.concat([grid_df, volumes], axis="columns", sort=False)

    aggregators = {
        key: AGGREGATORS[key.split("@")[0]]
        for key in grid_df if key.split("@")[0] in AGGREGATORS
    }

    # Group over PILLAR and possibly regions:
    grouped = (grid_df.groupby(groupbies).agg(aggregators)).reset_index()

    # Compute correct pillar averaged porosity (from bulk)
    if "PORV" in grouped and "VOLUME" in grouped:
        grouped["PORO"] = grouped["PORV"] / grouped["VOLUME"]

    # Compute contacts:
    for datestr in rstdates_iso:
        if "SWAT@" + datestr in grid_df and ("SOIL@" + datestr in grid_df
                                             or "SGAS@" + datestr in grid_df):
            contacts = compute_pillar_contacts(
                grid_df,
                region=region,
                soilcutoff=soilcutoff,
                sgascutoff=sgascutoff,
                swatcutoff=swatcutoff,
                datestr=datestr,
            )
            if not contacts.empty:
                grouped = pd.merge(grouped, contacts, how="left")

    if stackdates:
        return common.stack_on_colnames(grouped,
                                        sep="@",
                                        stackcolname="DATE",
                                        inplace=True)
    return grouped