def test_mon_U(self, mon_series, series, mon_triangular, kind, name): """ Train on hist: U ref: U + monthly cycle Predict on hist to get ref """ u = np.random.rand(10000) # Define distributions xd = uniform(loc=2, scale=0.1) yd = uniform(loc=4, scale=0.1) noise = uniform(loc=0, scale=1e-7) # Generate random numbers x = xd.ppf(u) y = yd.ppf(u) + noise.ppf(u) # Test train hist = sim = series(x, name) ref = mon_series(y, name) QM = EmpiricalQuantileMapping(kind=kind, group="time.month", nquantiles=5) QM.train(ref, hist) p = QM.adjust(sim) mqm = QM.ds.af.mean(dim="quantiles") expected = apply_correction(mon_triangular, 2, kind) np.testing.assert_array_almost_equal(mqm, expected, 1) # Test predict np.testing.assert_array_almost_equal(p, ref, 2)
def test_simple(self, c_thresh, q_thresh, frac, power): n = 45 * 365 def gen_testdata(c, s): base = np.clip(norm.rvs(loc=0, scale=s, size=(n, )), 0, None) qv = np.quantile(base[base > 1], q_thresh) base[base > qv] = genpareto.rvs(c, loc=qv, scale=s, size=base[base > qv].shape) return xr.DataArray( base, dims=("time", ), coords={ "time": xr.cftime_range("1990-01-01", periods=n, calendar="noleap") }, attrs={ "units": "mm/day", "thresh": qv }, ) ref = jitter_under_thresh(gen_testdata(-0.1, 2), 1e-3) hist = jitter_under_thresh(gen_testdata(-0.1, 2), 1e-3) sim = gen_testdata(-0.15, 2.5) EQM = EmpiricalQuantileMapping(group="time.dayofyear", nquantiles=15, kind="*") EQM.train(ref, hist) scen = EQM.adjust(sim) EX = ExtremeValues(c_thresh, q_thresh=q_thresh) EX.train(ref, hist) qv = (ref.thresh + hist.thresh) / 2 np.testing.assert_allclose(EX.ds.fit_params, [-0.1, qv, 2], atol=0.5, rtol=0.1) np.testing.assert_allclose(EX.ds.thresh, qv, atol=0.15, rtol=0.01) scen2 = EX.adjust(scen, sim, frac=frac, power=power) # What to test??? # Test if extreme values of sim are still extreme exval = sim > EX.ds.thresh assert (scen2.where(exval) > EX.ds.thresh).sum() > (scen.where(exval) > EX.ds.thresh).sum() # ONLY extreme values have been touched (but some might not have been modified) assert (((scen != scen2) | exval) == exval).all()
def test_quantiles(self, series, kind, name): """Train on hist: U ref: Normal Predict on hist to get ref """ u = np.random.rand(10000) # Define distributions xd = uniform(loc=10, scale=1) yd = norm(loc=12, scale=1) # Generate random numbers with u so we get exact results for comparison x = xd.ppf(u) y = yd.ppf(u) # Test train hist = sim = series(x, name) ref = series(y, name) QM = EmpiricalQuantileMapping( kind=kind, group="time", nquantiles=50, ) QM.train(ref, hist) p = QM.adjust(sim, interp="linear") q = QM.ds.coords["quantiles"] expected = get_correction(xd.ppf(q), yd.ppf(q), kind) # Results are not so good at the endpoints np.testing.assert_array_almost_equal(QM.ds.af[2:-2], expected[2:-2], 1) # Test predict # Accept discrepancies near extremes middle = (x > 1e-2) * (x < 0.99) np.testing.assert_array_almost_equal(p[middle], ref[middle], 1)
def test_dask_julia(self): dsim = open_dataset("sdba/CanESM2_1950-2100.nc").chunk() dref = open_dataset("sdba/ahccd_1950-2013.nc").chunk() dexp = open_dataset("sdba/adjusted_external.nc") ref = convert_units_to(dref.sel(time=slice("1950", "2009")).pr, "mm/d") hist = convert_units_to( dsim.sel(time=slice("1950", "2009")).pr, "mm/d") quantiles = np.linspace(0.01, 0.99, num=50) EQM = EmpiricalQuantileMapping(group=Grouper("time.dayofyear", window=31), nquantiles=quantiles) with xr.set_options(keep_attrs=True): ref = ref + uniform_noise_like(ref, low=1e-6, high=1e-3) hist = hist + uniform_noise_like(hist, low=1e-6, high=1e-3) EQM.train(ref, hist) scen = EQM.adjust(hist, interp="linear", extrapolation="constant") EX = ExtremeValues(cluster_thresh="1 mm/day", q_thresh=0.97) EX.train(ref, hist) new_scen = EX.adjust(scen, hist, frac=0.000000001) new_scen.load() exp_scen = dexp.extreme_values_julia xr.testing.assert_allclose( new_scen.where(new_scen != scen).transpose("time", "location"), exp_scen.where(new_scen != scen).transpose("time", "location"), atol=0.005, rtol=2e-3, )