Beispiel #1
0
def test_multiple_metrics_per_axis():
    # copied from test_derivatives.py - should refactor
    dx = 10.0
    ds = xr.Dataset(
        {
            "foo": (("XC", ), [1.0, 2.0, 4.0, 3.0]),
            "bar": (("XG", ), [10.0, 20.0, 30.0, 40.0]),
        },
        coords={
            "XC": (("XC", ), [0.5, 1.5, 2.5, 3.5]),
            "XG": (("XG", ), [0, 1.0, 2.0, 3.0]),
            "dXC": (("XC", ), [dx, dx, dx, dx]),
            "dXG": (("XG", ), [dx, dx, dx, dx]),
        },
    )

    grid = Grid(
        ds,
        coords={"X": {
            "center": "XC",
            "left": "XG"
        }},
        metrics={("X", ): ["dXC", "dXG"]},
        periodic=True,
    )

    assert grid.get_metric(ds.foo,
                           ("X", )).equals(ds.dXC.reset_coords(drop=True))
    assert grid.get_metric(ds.bar,
                           ("X", )).equals(ds.dXG.reset_coords(drop=True))
Beispiel #2
0
def test_get_metric(axes, data_var, drop_vars, metric_expected_list,
                    expected_error):
    ds_full = datasets()
    ds = ds_full["C"]
    metrics = ds_full["metrics"]
    # drop metrics according to drop_vars input, and remove from metrics input
    if drop_vars:
        print(drop_vars)
        ds = ds.drop(drop_vars)
        metrics = {
            k: [a for a in v if a not in drop_vars]
            for k, v in metrics.items()
        }

    grid = Grid(ds, coords=ds_full["coords"], metrics=metrics)
    if expected_error:
        with pytest.raises(expected_error):
            metric = grid.get_metric(ds[data_var], axes)
    else:
        metric = grid.get_metric(ds[data_var], axes)
        expected_metrics = [
            ds[me].reset_coords(drop=True) for me in metric_expected_list
        ]
        expected = functools.reduce(operator.mul, expected_metrics, 1)
        assert metric.equals(expected)
Beispiel #3
0
def test_interp_conservative(grid_type, variable, axis, metric_weighted):
    ds, coords, metrics = datasets_grid_metric(grid_type)
    grid = Grid(ds, coords=coords, metrics=metrics)

    metric = grid.get_metric(ds[variable], metric_weighted)
    expected_raw = grid.interp(ds[variable] * metric, axis)
    metric_new = grid.get_metric(expected_raw, metric_weighted)
    expected = expected_raw / metric_new
    new = grid.interp(ds[variable], axis, metric_weighted=metric_weighted)
    assert new.equals(expected)
Beispiel #4
0
    def test_weighted_metric(
        self, funcname, grid_type, variable, axis, metric_weighted, periodic, boundary
    ):
        """tests the correct execution of weighted ops along a single axis"""
        # metric_weighted allows the interpolation of e.g. a surface flux to be conservative
        # It multiplies the values with a metric like the area, then performs interpolation
        # and divides by the same metric (area) for the new grid position
        ds, coords, metrics = datasets_grid_metric(grid_type)
        grid = Grid(ds, coords=coords, metrics=metrics, periodic=periodic)
        func = getattr(grid, funcname)

        metric = grid.get_metric(ds[variable], metric_weighted)
        expected_raw = func(ds[variable] * metric, axis, boundary=boundary)
        metric_new = grid.get_metric(expected_raw, metric_weighted)
        expected = expected_raw / metric_new
        new = func(
            ds[variable], axis, metric_weighted=metric_weighted, boundary=boundary
        )
        assert new.equals(expected)

        @pytest.mark.parametrize(
            "multi_axis", ["X", ["X"], ("Y"), ["X", "Y"], ("Y", "X")]
        )
        def test_weighted_metric_multi_axis(
            self, funcname, grid_type, variable, multi_axis, metric_weighted, boundary
        ):
            """tests if the output for multiple axis is the same as when
            executing the single axis ops in serial"""
            ds, coords, metrics = datasets_grid_metric(grid_type)
            grid = Grid(ds, coords=coords, metrics=metrics)

            func = getattr(grid, funcname)
            expected = ds[variable]
            for ax in multi_axis:
                if isinstance(metric_weighted, dict):
                    metric_weighted_axis = metric_weighted[ax]
                else:
                    metric_weighted_axis = metric_weighted
                expected = func(
                    expected,
                    ax,
                    metric_weighted=metric_weighted_axis,
                    boundary=boundary,
                )

            new = func(
                ds[variable],
                multi_axis,
                metric_weighted=metric_weighted,
                boundary=boundary,
            )
            assert new.equals(expected)
Beispiel #5
0
def test_get_metric_with_conditions_01():
    # Condition 1: metric with matching axes and dimensions exist
    ds, coords, metrics = datasets_grid_metric("C")
    grid = Grid(ds, coords=coords, metrics=metrics)
    get_metric = grid.get_metric(ds.v, ("X", "Y"))

    expected_metric = ds["area_n"].reset_coords(drop=True)

    xr.testing.assert_allclose(get_metric, expected_metric)
Beispiel #6
0
    def test_weighted_metric(self, funcname, grid_type, variable, axis,
                             metric_weighted, periodic, boundary):
        """tests the correct execution of weighted ops along a single axis"""
        # metric_weighted allows the interpolation of e.g. a surface flux to be conservative
        # It multiplies the values with a metric like the area, then performs interpolation
        # and divides by the same metric (area) for the new grid position
        ds, coords, metrics = datasets_grid_metric(grid_type)
        grid = Grid(ds, coords=coords, metrics=metrics, periodic=periodic)
        func = getattr(grid, funcname)

        metric = grid.get_metric(ds[variable], metric_weighted)
        expected_raw = func(ds[variable] * metric, axis, boundary=boundary)
        metric_new = grid.get_metric(expected_raw, metric_weighted)
        expected = expected_raw / metric_new
        new = func(ds[variable],
                   axis,
                   metric_weighted=metric_weighted,
                   boundary=boundary)
        assert new.equals(expected)
Beispiel #7
0
def test_get_metric_with_conditions_02a(periodic):
    # Condition 2, case a: interpolate metric with matching axis to desired dimensions
    ds, coords, _ = datasets_grid_metric("C")
    grid = Grid(ds, coords=coords, periodic=periodic, boundary="extend")
    grid.set_metrics(("X", "Y"), "area_e")

    get_metric = grid.get_metric(ds.v, ("X", "Y"))

    expected_metric = grid.interp(ds["area_e"], ("X", "Y"))

    xr.testing.assert_allclose(get_metric, expected_metric)
Beispiel #8
0
def test_get_metric_orig(axes, data_var, drop_vars, metric_expected_list):
    ds, coords, metrics = datasets_grid_metric("C")
    # drop metrics according to drop_vars input, and remove from metrics input
    if drop_vars:
        ds = ds.drop_vars(drop_vars)
        metrics = {k: [a for a in v if a not in drop_vars] for k, v in metrics.items()}

    grid = Grid(ds, coords=coords, metrics=metrics)
    metric = grid.get_metric(ds[data_var], axes)
    expected_metrics = [ds[me].reset_coords(drop=True) for me in metric_expected_list]
    expected = functools.reduce(operator.mul, expected_metrics, 1)
    assert metric.equals(expected)
Beispiel #9
0
def test_metrics_2d_grid():
    # this is a uniform grid
    # a non-uniform grid would provide a more rigorous test
    dx = 10.0
    dy = 11.0
    area = 120.0
    ny, nx = 7, 9
    ds = xr.Dataset(
        {"foo": (("YC", "XC"), np.ones((ny, nx)))},
        coords={
            "XC": (("XC",), np.arange(nx)),
            "dX": (("XC",), np.full(nx, dx)),
            "YC": (("YC",), np.arange(ny)),
            "dY": (("YC",), np.full(ny, dy)),
            "area": (("YC", "XC"), np.full((ny, nx), area)),
        },
    )

    grid = Grid(
        ds,
        coords={"X": {"center": "XC"}, "Y": {"center": "YC"}},
        metrics={("X",): ["dX"], ("Y",): ["dY"], ("X", "Y"): ["area"]},
    )

    assert ds.dX.reset_coords(drop=True).equals(grid.get_metric(ds.foo, ("X",)))
    assert ds.dY.reset_coords(drop=True).equals(grid.get_metric(ds.foo, ("Y",)))
    assert ds.area.reset_coords(drop=True).equals(grid.get_metric(ds.foo, ("X", "Y")))
    assert ds.area.reset_coords(drop=True).equals(grid.get_metric(ds.foo, ("Y", "X")))

    # try with no area metric:
    grid = Grid(
        ds,
        coords={"X": {"center": "XC"}, "Y": {"center": "YC"}},
        metrics={("X",): ["dX"], ("Y",): ["dY"]},
    )

    dxdy = (ds.dX * ds.dY).reset_coords(drop=True).transpose("YC", "XC")
    actual = grid.get_metric(ds.foo, ("Y", "X")).transpose("YC", "XC")
    assert dxdy.equals(actual)
Beispiel #10
0
def test_get_metric_with_conditions_04a():
    # Condition 4, case a: 1 metric on the wrong position (must interpolate before multiplying)
    ds, coords, _ = datasets_grid_metric("C")
    grid = Grid(ds, coords=coords)
    grid.set_metrics(("X"), "dx_t")
    grid.set_metrics(("Y"), "dy_n")

    get_metric = grid.get_metric(ds.v, ("X", "Y"))

    interp_metric = grid.interp(ds.dx_t, "Y")
    expected_metric = (interp_metric * ds.dy_n).reset_coords(drop=True)

    xr.testing.assert_allclose(get_metric, expected_metric)
Beispiel #11
0
def test_get_metric_with_conditions_03b():
    # Condition 3: use provided metrics with matching dimensions to calculate for required metric
    ds, coords, metrics = datasets_grid_metric("C")
    grid = Grid(ds, coords=coords)
    grid.set_metrics(("X", "Y"), "area_t")
    grid.set_metrics(("Z"), "dz_t")

    get_metric = grid.get_metric(ds.tracer, ("X", "Y", "Z"))

    metric_var_1 = ds.area_t
    metric_var_2 = ds.dz_t
    expected_metric = (metric_var_1 * metric_var_2).reset_coords(drop=True)

    xr.testing.assert_allclose(get_metric, expected_metric)
Beispiel #12
0
def test_get_metric_with_conditions_02b():
    # Condition 2, case b: get_metric should select for the metric with matching axes and interpolate from there,
    # even if other metrics in the desired positions are available
    ds, coords, _ = datasets_grid_metric("C")
    grid = Grid(ds, coords=coords)
    grid.set_metrics(("X", "Y"), "area_e")
    grid.set_metrics(("X"), "dx_n")
    grid.set_metrics(("Y"), "dx_n")

    get_metric = grid.get_metric(ds.v, ("X", "Y"))

    expected_metric = grid.interp(ds["area_e"], ("X", "Y"))

    xr.testing.assert_allclose(get_metric, expected_metric)