Exemplo n.º 1
0
    def test_filters(self, data_grid):
        """Test filters as argument"""
        data_grid["filters"] = {
            "reek_sim_facies2.roff": {
                "include": ["FINESAND", "COARSESAND"],
            }
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert ["FINESAND", "COARSESAND"] == list(pdf.dataframe["FACIES"].unique())
        assert pdf.dataframe["PORO"].mean() == pytest.approx(0.2374, abs=0.001)

        data_grid["filters"] = {
            "reek_sim_facies2.roff": {
                "exclude": "FINESAND",
            }
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert "FINESAND" not in list(pdf.dataframe["FACIES"].unique())

        data_grid["filters"] = {
            "reek_sim_poro.roff": {
                "range": [0.15, 0.25],
            }
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())
        assert pdf.dataframe["PORO"].mean() == pytest.approx(0.2027, abs=0.001)
        assert pdf.dataframe["PORO"].min() > 0.15
        assert pdf.dataframe["PORO"].max() < 0.25
Exemplo n.º 2
0
    def run(self, data, reuse=False, project=None):
        """Main routine for evaluating grid quality and stop/warn if too bad

        The routine depends on existing XTGeo functions for this purpose.

        Args:
            data (dict or str): The input data either as a Python dictionary or
                a path to a YAML file
            reuse (bool or list): Reusing some "timeconsuming to read" data in the
                instance. If True, then grid and gridprops will be reused as default.
                Alternatively it can be a list for more fine grained control, e.g.
                ["grid", "gridprops", "wells"]
            project (Union[object, str]): For usage inside RMS, None if running files

        """
        self._data = self.handle_data(data, project)
        self._validate_input(self._data, project)

        QCC.verbosity = self._data.get("verbosity", 0)

        # parse data that are special for this check
        QCC.print_info("Parsing additional data...")
        self.ldata = _LocalData()
        self.ldata.parse_data(data)

        if isinstance(self.gdata, QCData):
            self.gdata.parse(data=data, reuse=reuse, project=project)
        else:
            self.gdata = QCData()
            self.gdata.parse(data)

        dfr = self.check_gridquality()
        QCC.print_debug(f"Results: \n{dfr}")

        self.evaluate_qcreport(dfr, "grid quality")
Exemplo n.º 3
0
 def test_gridprops(self, data_grid):
     """Test creating property dataframe from grid properties"""
     pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())
     assert pdf.dataframe["PORO"].mean() == pytest.approx(0.1677, abs=0.001)
     assert pdf.dataframe["PORO"].max() == pytest.approx(0.3613, abs=0.001)
     assert set(pdf.dataframe.columns) == set(
         ["PORO", "PERM", "ZONE", "FACIES"])
Exemplo n.º 4
0
    def test_codenames(self, data_grid):
        """Test modifying codenames on selectors"""

        data_grid["selectors"] = {
            "ZONE": {
                "name": "reek_sim_zone.roff",
                "codes": {
                    1: "TOP",
                    2: "MID"
                }
            },
            "FACIES": {
                "name": "reek_sim_facies2.roff",
                "codes": {
                    1: "SAND",
                    2: "SAND"
                },
            },
        }

        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert set(["TOP", "MID", "Below_Low_reek"]) == {
            x
            for x in list(pdf.dataframe["ZONE"].unique()) if x is not None
        }

        assert set(["SAND", "SHALE"]) == {
            x
            for x in list(pdf.dataframe["FACIES"].unique()) if x is not None
        }
Exemplo n.º 5
0
 def test_wells(self, data_wells):
     """Test creating property dataframe from wells"""
     pdf = WellLogs2df(data=data_wells, project=None, xtgdata=QCData())
     assert pdf.dataframe["PORO"].mean() == pytest.approx(0.1539, abs=0.001)
     assert pdf.dataframe["PORO"].max() == pytest.approx(0.3661, abs=0.001)
     assert set(pdf.dataframe.columns) == set(
         ["PORO", "PERM", "ZONE", "FACIES"])
Exemplo n.º 6
0
 def __init__(self):
     self._method = None
     self._data = None  # input data dictionary
     self._path = "."
     self._gdata = QCData()  # QCData instance, stores XTGeo data
     self._ldata = None  # special data instance, for local data parsed per method
     self._reports = [
     ]  # List of all report, used to determin write/append mode
Exemplo n.º 7
0
    def __init__(self):

        self._propstats = []  # list of PropStat() instances
        self._dataframe = pd.DataFrame(
        )  # merged dataframe with continous stats
        self._dataframe_disc = pd.DataFrame(
        )  # merged dataframe with discrete stats
        self._xtgdata = QCData()  # QCData instance, general XTGeo data
Exemplo n.º 8
0
 def test_blockedwells(self, data_bwells):
     """Test creating property dataframe from blocked wells"""
     pdf = WellLogs2df(
         data=data_bwells, project=None, xtgdata=QCData(), blockedwells=True
     )
     assert pdf.dataframe["PORO"].mean() == pytest.approx(0.1709, abs=0.001)
     assert pdf.dataframe["PORO"].max() == pytest.approx(0.3640, abs=0.001)
     assert set(pdf.dataframe.columns) == set(["PORO", "FACIES"])
Exemplo n.º 9
0
    def __init__(self):

        self._xtgdata = QCData()  # QCData instance, general XTGeo data
        self._dfs = []  # list of dataframes with aggregated statistics
        self._selectors_all = []
        self._proptypes_all = []
        self._ids = []
        self._dataframe = pd.DataFrame()  # merged dataframe with statistics
Exemplo n.º 10
0
    def test_selector_filters(self, data_grid):
        """Test filters on selector"""
        data_grid["selectors"] = {
            "FACIES": {"name": "reek_sim_facies2.roff", "include": "FINESAND"},
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert ["FINESAND"] == list(pdf.dataframe["FACIES"].unique())

        # test exclude values using list
        data_grid["selectors"] = {
            "FACIES": {
                "name": "reek_sim_facies2.roff",
                "exclude": ["FINESAND", "SHALE"],
            },
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert "FINESAND" not in list(pdf.dataframe["FACIES"].unique())
        assert "SHALE" not in list(pdf.dataframe["FACIES"].unique())
Exemplo n.º 11
0
    def test_filters_and_selector_filters(self, data_grid):
        """
        Test filters on both selector and as separate argument
        Wanted behaviour is to ignore the filter on the selector
        """
        data_grid["selectors"] = {
            "FACIES": {"name": "reek_sim_facies2.roff", "exclude": "FINESAND"},
        }
        data_grid["filters"] = {
            "reek_sim_facies2.roff": {
                "include": ["FINESAND", "COARSESAND"],
            }
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert ["FINESAND", "COARSESAND"] == list(pdf.dataframe["FACIES"].unique())
        assert pdf.dataframe["PORO"].mean() == pytest.approx(0.2374, abs=0.001)
Exemplo n.º 12
0
    def test_filters_and_property_filters(self, data_grid):
        """
        Test filters on both properties and as separate argument.
        Wanted behaviour is to ignore the filter on the property
        """
        data_grid["properties"] = {
            "PORO": {"name": "reek_sim_poro.roff", "range": [0.2, 0.4]},
        }
        data_grid["filters"] = {
            "reek_sim_poro.roff": {
                "range": [0.15, 0.25],
            }
        }
        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())

        assert pdf.dataframe["PORO"].mean() == pytest.approx(0.2027, abs=0.001)
        assert pdf.dataframe["PORO"].min() > 0.15
        assert pdf.dataframe["PORO"].max() < 0.25
Exemplo n.º 13
0
    def test_props_and_selectors_as_list(self, data_grid):
        """Test"""
        data_grid["properties"] = ["reek_sim_poro.roff", "reek_sim_permx.roff"]
        data_grid["selectors"] = [
            "reek_sim_zone.roff", "reek_sim_facies2.roff"
        ]

        pdf = GridProps2df(data=data_grid, project=None, xtgdata=QCData())
        assert pdf.dataframe["reek_sim_poro.roff"].mean() == pytest.approx(
            0.1677, abs=0.001)
        assert pdf.dataframe["reek_sim_poro.roff"].max() == pytest.approx(
            0.3613, abs=0.001)
        assert set(pdf.dataframe.columns) == set([
            "reek_sim_poro.roff",
            "reek_sim_permx.roff",
            "reek_sim_zone.roff",
            "reek_sim_facies2.roff",
        ])
Exemplo n.º 14
0
def test_qcdata():
    """Testing getting data with _QCForwardData class"""

    qcdata = QCData()
    qcdata.parse(data=DATA1)

    assert isinstance(qcdata, QCData)
    assert isinstance(qcdata.grid, xtgeo.Grid)
    assert isinstance(qcdata.gridprops, xtgeo.GridProperties)
    assert isinstance(qcdata.wells, xtgeo.Wells)

    assert qcdata._project is None
    assert qcdata.grid.ncol == 40

    zone = qcdata.gridprops.get_prop_by_name(ZONENAME)
    assert isinstance(zone, xtgeo.GridProperty)
    assert zone.name == ZONENAME
    assert zone.values.mean() == pytest.approx(1.92773, abs=0.01)
    assert zone.ncol == 40

    op1 = qcdata.wells.get_well("OP_1")

    assert ZONELOGNAME in op1.dataframe.columns
Exemplo n.º 15
0
    def run(
        self,
        data: Union[dict, str],
        reuse: Optional[bool] = False,
        project: Optional[Any] = None,
    ):
        """Main routine for evaluating blockedwells vs gridproperties

        The routine depends on existing XTGeo functions for this purpose.

        Args:
            data (dict or str): The input data either as a Python dictionary or
                a path to a YAML file
            reuse (bool or list): Reusing some "timeconsuming to read" data in the
                instance. If True, then grid and gridprops will be reused as default.
                Alternatively it can be a list for more fine grained control, e.g.
                ["grid", "gridprops", "bwells"]
            project (Union[object, str]): For usage inside RMS, None if running files

        """
        self._data = self.handle_data(data, project)
        self._validate_input(self._data, project)

        QCC.verbosity = self._data.get("verbosity", 0)

        # parse data that are special for this check
        QCC.print_info("Parsing additional data...")
        self.ldata = _LocalData()
        self.ldata.parse_data(self._data)

        # now need to retrieve blocked properties and grid properties from the "compare"
        # dictionary:
        wsettings = {"lognames": list(self.ldata.compare.keys())}

        if project:
            # inside RMS, get gridprops implicitly from compare values
            self._data["gridprops"] = list(self.ldata.compare.values())

        if not isinstance(self.gdata, QCData):
            self.gdata = QCData()

        self.gdata.parse(data=self._data,
                         reuse=reuse,
                         project=project,
                         wells_settings=wsettings)

        dfr, comb = self.compare_bw_props()

        QCC.print_debug(f"Results: \n{dfr}")
        status = self.evaluate_qcreport(dfr,
                                        "blocked wells vs grid props",
                                        stopaction=False)

        # make it possible to print the underlying dataframe, either some wells (.e.g
        # the failing) or all wells. If 'fail' it will only show those lines that
        # contains FAIL
        show = self.ldata.show_data
        if show is None or show is False:
            pass
        elif isinstance(show, dict):
            if "lines" not in show or "wellstatus" not in show:
                raise ValueError(
                    f"The 'showdata' entry is in an invalid form or format: {show}"
                )

            lines = show["lines"].upper()
            wstatus = show["wellstatus"].upper()

            print(
                f"\n** Key 'show_data' is active, here showing lines with {lines} "
                f"for wells classified as {wstatus} **")
            # filter out all line with word FAIL or WARN or ... , h/t HAVB
            fcomb = comb[comb.astype(str).agg("".join,
                                              axis=1).str.contains(lines)]
            if len(fcomb) > 0:
                mask = dfr["STATUS"] == wstatus
                wells = [
                    well for well in dfr[mask]["WELL"].unique()
                    if well != "all"
                ]
                if wells:
                    print(f"Wells within {wstatus} criteria are: {wells}:\n")
                    print(fcomb[fcomb["WELLNAME"].isin(wells)].to_string())
                else:
                    print(f"No wells within {wstatus} criteria")
            else:
                print(f"No lines are matching {lines}. Wrong input?:\n")

        else:

            print("Show all well cells for all wells:")
            if len(comb) > 0:
                print(comb.to_string())

        if status == "STOP":
            QCC.force_stop("STOP criteria is found!")