Beispiel #1
0
def test_missing(tas_series):
    a = tas_series(np.ones(365, float), start="1/1/2000")

    # By default, missing is set to "from_context", and the default missing option is "any"
    # Cannot set missing_options with "from_context"
    with pytest.raises(ValueError, match="Cannot set `missing_options`"):
        uniClim.__class__(missing_options={"tolerance": 0.01})

    # Null value
    a[5] = np.nan

    m = uniIndTemp(a, freq="MS")
    assert m[0].isnull()

    with xclim.set_options(check_missing="pct",
                           missing_options={"pct": {
                               "tolerance": 0.05
                           }}):
        m = uniIndTemp(a, freq="MS")
        assert not m[0].isnull()

    with xclim.set_options(check_missing="wmo"):
        m = uniIndTemp(a, freq="YS")
        assert m[0].isnull()

    # With freq=None
    c = uniClim(a)
    assert c.isnull()

    # With indexer
    ci = uniClim(a, month=[2])
    assert not ci.isnull()

    out = uniClim(a, month=[1])
    assert out.isnull()
Beispiel #2
0
def test_register_missing_method():
    @register_missing_method("test")
    class MissingTest(MissingBase):
        def is_missing(self, null, count, a_param=2):
            return True

        @staticmethod
        def validate(a_param):
            return a_param < 3

    with pytest.raises(ValueError):
        set_options(missing_options={"test": {"a_param": 5}})

    with set_options(check_missing="test"):
        assert OPTIONS["check_missing"] == "test"
Beispiel #3
0
def test_renaming_variable(tas_series, tmp_path):
    tas = tas_series(np.ones(366), start="1/1/2000")
    input_file = tmp_path / "tas.nc"
    output_file = tmp_path / "out.nc"
    tas.name = "tas"
    tas.to_netcdf(input_file)
    with xclim.set_options(cf_compliance="warn"):
        runner = CliRunner()
        results = runner.invoke(
            cli,
            [
                "-i",
                str(input_file),
                "-o",
                str(output_file),
                "-v",
                "tn_mean",
                "--tasmin",
                "tas",
            ],
        )
        assert "Processing : tn_mean" in results.output
        assert "100% Completed" in results.output

    out = xr.open_dataset(output_file)
    assert out.tn_mean[0] == 1.0
Beispiel #4
0
def test_missing(tas_series):
    a = tas_series(np.ones(360, float), start="1/1/2000")

    # By default, missing is set to "from_context", and the default missing option is "any"
    ind = UniIndTemp()
    clim = UniClim()

    # Null value
    a[5] = np.nan

    m = ind(a, freq="MS")
    assert m[0].isnull()

    with xclim.set_options(check_missing="pct",
                           missing_options={"pct": {
                               "tolerance": 0.05
                           }}):
        m = ind(a, freq="MS")
        assert not m[0].isnull()

    # With freq=None
    c = clim(a)
    assert c.isnull()

    # With indexer
    ci = clim(a, month=[2])
    assert not ci.isnull()

    out = clim(a, month=[1])
    assert out.isnull()
Beispiel #5
0
def adjust_quantiledeltamapping_year(
    simulation, qdm, year, variable, halfyearwindow_n=10, include_quantiles=False
):
    """Apply QDM to adjust a year within a simulation.

    Parameters
    ----------
    simulation : xr.Dataset
        Daily simulation data to be adjusted. Must have sufficient observations
        around `year` to adjust. Target variable must have a units attribute.
    qdm : xr.Dataset or sdba.adjustment.QuantileDeltaMapping
        Trained ``xclim.sdba.adjustment.QuantileDeltaMapping``, or
        Dataset representation that will be instantiate
        ``xclim.sdba.adjustment.QuantileDeltaMapping``.
    year : int
        Target year to adjust, with rolling years and day grouping.
    variable : str
        Target variable in `simulation` to adjust. Adjusted output will share the
        same name.
    halfyearwindow_n : int, optional
        Half-length of the annual rolling window to extract along either
        side of `year`.
    include_quantiles : bool, optional
        Whether or not to output quantiles (sim_q) as a coordinate on
        the bias corrected data variable in output.

    Returns
    -------
    out : xr.Dataset
        QDM-adjusted values from `simulation`. May be a lazy-evaluated future, not
        yet computed.
    """
    year = int(year)
    variable = str(variable)
    halfyearwindow_n = int(halfyearwindow_n)

    if isinstance(qdm, xr.Dataset):
        qdm = sdba.adjustment.QuantileDeltaMapping.from_dataset(qdm)

    # Slice to get 15 days before and after our target year. This accounts
    # for the rolling 31 day rolling window.
    timeslice = slice(
        f"{year - halfyearwindow_n - 1}-12-17", f"{year + halfyearwindow_n + 1}-01-15"
    )
    simulation = simulation[variable].sel(
        time=timeslice
    )  # TODO: Need a check to ensure we have all the data in this slice!
    if include_quantiles:
        # include quantile information in output
        with set_options(sdba_extra_output=True):
            out = qdm.adjust(simulation, interp="nearest").sel(time=str(year))
            # make quantiles a coordinate of bias corrected output variable
            out = out["scen"].assign_coords(sim_q=out.sim_q)
    else:
        out = qdm.adjust(simulation, interp="nearest").sel(time=str(year))

    return out.to_dataset(name=variable)
Beispiel #6
0
def test_set_options_valid(option, value):
    old = OPTIONS[option]
    with set_options(**{option: value}):
        if option != "missing_options":
            assert OPTIONS[option] == value
        else:
            for k, opts in value.items():
                curr_opts = OPTIONS["missing_options"][k].copy()
                assert curr_opts == opts
    assert OPTIONS[option] == old
Beispiel #7
0
    def test_first_snowfall(self):
        with set_options(check_missing="skip"):
            fs = atmos.first_snowfall(prsn=self.get_snowfall(),
                                      thresh="0.5 mm/day")

        np.testing.assert_array_equal(
            fs[:, [0, 45, 82], [10, 105, 155]],
            np.array([
                [[1, 1, 1], [1, 1, 1], [11, np.nan, np.nan]],
                [[254, 256, 277], [274, 292, 275], [300, np.nan, np.nan]],
            ]),
        )
Beispiel #8
0
    def test_last_snowfall(self):
        with set_options(check_missing="skip"):
            ls = atmos.last_snowfall(prsn=self.get_snowfall(),
                                     thresh="0.5 mm/day")

        np.testing.assert_array_equal(
            ls[:, [0, 45, 82], [10, 105, 155]],
            np.array([
                [[155, 151, 129], [127, 157, 110], [106, np.nan, np.nan]],
                [[365, 363, 363], [365.0, 364, 364], [362, np.nan, np.nan]],
            ]),
        )
Beispiel #9
0
def test_cf_compliance_options(tas_series, caplog):
    tas = tas_series(np.ones(365))
    tas.attrs["standard_name"] = "not the right name"

    with caplog.at_level(logging.INFO):
        with set_options(cf_compliance="log"):
            cfchecks.check_valid_temperature(tas, "degK")

            assert all([rec.levelname == "INFO" for rec in caplog.records])
            assert ("Variable has a non-conforming standard_name"
                    in caplog.records[0].msg)
            assert "Variable has a non-conforming units" in caplog.records[
                1].msg

    with pytest.warns(UserWarning, match="Variable has a non-conforming"):
        with set_options(cf_compliance="warn"):
            cfchecks.check_valid_temperature(tas, "degK")

    with pytest.raises(ValidationError,
                       match="Variable has a non-conforming standard_name"):
        with set_options(cf_compliance="raise"):
            cfchecks.check_valid_temperature(tas, "degK")
Beispiel #10
0
def test_generated_cfchecks():
    with set_options(cf_compliance="raise"):
        tas = xr.DataArray(attrs=dict(standard_name="air_temperature",
                                      cell_methods="time: mean within days"))

        cfchecks.generate_cfcheck("tas")(tas)

        tas.attrs["standard_name"] = "air_feeling_of_heat"

        with pytest.raises(ValidationError):
            cfchecks.generate_cfcheck("tas")(tas)

        sfcwind = xr.DataArray(attrs=dict(
            standard_name="wind_speed", cell_methods="time: max within hours"))

        with pytest.raises(ValidationError):
            cfchecks.generate_cfcheck("sfcWind")(sfcwind)
Beispiel #11
0
    def test_basic(self):
        check_units("%", "[]")
        check_units("pct", "[]")
        check_units("mm/day", "[precipitation]")
        check_units("mm/s", "[precipitation]")
        check_units("kg/m2/s", "[precipitation]")
        check_units("kg/m2", "[length]")
        check_units("cms", "[discharge]")
        check_units("m3/s", "[discharge]")
        check_units("m/s", "[speed]")
        check_units("km/h", "[speed]")

        with set_options(data_validation="raise"):
            with pytest.raises(ValidationError):
                check_units("mm", "[precipitation]")

            with pytest.raises(ValidationError):
                check_units("m3", "[discharge]")
def test_input_dataset():
    ds = open_dataset("ERA5/daily_surface_cancities_1990-1993.nc")

    # Use defaults
    out = xclim.atmos.daily_temperature_range(freq="YS", ds=ds)

    # Use non-defaults (inverted on purpose)
    with xclim.set_options(cf_compliance="log"):
        out = xclim.atmos.daily_temperature_range("tasmax",
                                                  "tasmin",
                                                  freq="YS",
                                                  ds=ds)

    # Use a mix
    out = xclim.atmos.daily_temperature_range(tasmax=ds.tasmax,
                                              freq="YS",
                                              ds=ds)

    # Inexistent variable:
    dsx = ds.drop_vars("tasmin")
    with pytest.raises(MissingVariableError):
        out = xclim.atmos.daily_temperature_range(freq="YS", ds=dsx)  # noqa
Beispiel #13
0
def test_liquid_precip_ratio():
    ds = open_dataset("ERA5/daily_surface_cancities_1990-1993.nc")

    out = atmos.liquid_precip_ratio(pr=ds.pr,
                                    tas=ds.tas,
                                    thresh="0 degC",
                                    freq="YS")
    np.testing.assert_allclose(out[:, 0],
                               np.array([0.919, 0.805, 0.525, 0.740, 0.993]),
                               atol=1e3)

    with set_options(cf_compliance="raise"):
        # Test if tasmax is allowed
        out = atmos.liquid_precip_ratio(pr=ds.pr,
                                        tas=ds.tasmax,
                                        thresh="33 degF",
                                        freq="YS")
        np.testing.assert_allclose(out[:, 0],
                                   np.array(
                                       [0.975, 0.921, 0.547, 0.794, 0.999]),
                                   atol=1e3)
        assert "where temperature is above 33 degf." in out.description
def test_input_dataset():
    dsx = open_dataset("NRCANdaily/nrcan_canada_daily_tasmax_1990")
    dsn = open_dataset("NRCANdaily/nrcan_canada_daily_tasmin_1990")
    ds = xr.merge([dsx, dsn])

    # Use defaults
    out = xclim.atmos.daily_temperature_range(freq="YS", ds=ds)

    # Use non-defaults (inverted on purpose)
    with xclim.set_options(cf_compliance="log"):
        out = xclim.atmos.daily_temperature_range("tasmax",
                                                  "tasmin",
                                                  freq="YS",
                                                  ds=ds)

    # Use a mix
    out = xclim.atmos.daily_temperature_range(tasmax=ds.tasmax,
                                              freq="YS",
                                              ds=ds)

    # Inexistent variable:
    with pytest.raises(MissingVariableError):
        out = xclim.atmos.daily_temperature_range(freq="YS", ds=dsx)  # noqa
Beispiel #15
0
def test_set_options_invalid(option, value):
    old = OPTIONS[option]
    with pytest.raises(ValueError):
        set_options(**{option: value})
    assert old == OPTIONS[option]
Beispiel #16
0
def setup_module(module):
    set_options(cf_compliance="raise", data_validation="raise")
Beispiel #17
0
def teardown_module(module):
    set_options(cf_compliance="warn", data_validation="raise")
Beispiel #18
0
import numpy as np
import pandas as pd
import pytest
import xarray as xr

from xclim import set_options
from xclim.core import cfchecks
from xclim.core.utils import ValidationError
from xclim.indicators.atmos import tg_mean

K2C = 273.15

TESTS_HOME = Path(__file__).absolute().parent
TESTS_DATA = Path(TESTS_HOME, "testdata")
set_options(cf_compliance="raise", data_validation="raise")
TestObj = namedtuple("TestObj", ["test"])


@pytest.fixture(scope="module", params=[xr.cftime_range, pd.date_range])
def date_range(request):
    return request.param


@pytest.mark.parametrize("value,expected", [("a string", "a string"),
                                            ("a long string", "a * string")])
def test_check_valid_ok(value, expected):
    d = TestObj(value)
    cfchecks.check_valid(d, "test", expected)

Beispiel #19
0
 def test_options(self, q_series):
     q = q_series(np.random.rand(19))
     with set_options(missing_options={"at_least_n": {"n": 10}}):
         out = land.fit(q, dist="norm")
     np.testing.assert_array_equal(out.isnull(), False)