def test_verify_no_need_for_control(PM_da_initialized_1d, PM_da_control_1d): """Tests that no error is thrown when no control present when calling verify(reference=['uninitialized']).""" v = "tos" comparison = "m2e" pm = PerfectModelEnsemble(PM_da_initialized_1d).load() # verify needs to control skill = pm.verify(metric="mse", comparison=comparison, dim="init") assert not skill[v].isnull().any() # control not needed for normalized metrics as normalized # with verif which is the verification member in PM and # not the control simulation. assert (not pm.verify(metric="nmse", comparison=comparison, dim="init")[v].isnull().any()) with pytest.raises(DatasetError) as e: pm.verify(metric="mse", comparison=comparison, dim="init", reference=["persistence"]) assert "at least one control dataset" in str(e.value) # unlikely case that control gets deleted after generating uninitialized pm = pm.add_control(PM_da_control_1d).generate_uninitialized() pm._datasets["control"] = {} assert (not pm._compute_uninitialized( metric="mse", comparison=comparison, dim="init")[v].isnull().any()) assert (not pm.verify(metric="mse", comparison=comparison, dim="init", reference=["uninitialized"])[v].isnull().any())
def perfectModelEnsemble_initialized_control_1d_dm_cftime( PM_ds_initialized_1d_dm_cftime, PM_ds_control_1d_dm_cftime): """PerfectModelEnsemble with MPI Perfect-model-framework initialized and control timeseries daily mean with cftime coords.""" pm = PerfectModelEnsemble(PM_ds_initialized_1d_dm_cftime) pm = pm.add_control(PM_ds_control_1d_dm_cftime) return pm
def setup(self, *args, **kwargs): self.get_data() self.PredictionEnsemble = PerfectModelEnsemble( self.initialized).add_control(self.observations) self.PredictionEnsemble = self.PredictionEnsemble.generate_uninitialized( ) self.reference = None self.resample_dim = "member" self.iterations = ITERATIONS
def test_calendar_matching_control(PM_ds_initialized_1d, PM_ds_control_1d): """Tests that error is thrown if calendars mismatch when adding observations.""" pm = PerfectModelEnsemble(PM_ds_initialized_1d) PM_ds_control_1d["time"] = xr.cftime_range( start="1950", periods=PM_ds_control_1d.time.size, freq="MS", calendar="all_leap" ) with pytest.raises(ValueError) as excinfo: pm = pm.add_control(PM_ds_control_1d) assert "does not match" in str(excinfo.value)
def test_PerfectModelEnsemble_plot(PM_ds_initialized_1d, PM_ds_control_1d, variable, show_members, cmap): """Test PredictionEnsemble.plot().""" pm = PerfectModelEnsemble(PM_ds_initialized_1d) kws = {"cmap": cmap, "show_members": show_members, "variable": variable} pm.plot(**kws) pm = pm.add_control(PM_ds_control_1d) pm.plot(**kws) pm = pm.generate_uninitialized() pm.plot(**kws)
def test_HindcastEnsemble_as_PerfectModelEnsemble(hindcast_recon_1d_mm): """Test that initialized dataset for HindcastEnsemble can also be used for PerfectModelEnsemble.""" v = "SST" alignment = "maximize" hindcast = hindcast_recon_1d_mm assert (not hindcast.verify( metric="acc", comparison="e2o", dim="init", alignment=alignment)[v].isnull().any()) # try PerfectModelEnsemble predictability init = hindcast.get_initialized() pm = PerfectModelEnsemble(init) assert (not pm.verify(metric="acc", comparison="m2e", dim=["member", "init"])[v].isnull().any()) pm = pm.add_control( init.isel(member=0, lead=0, drop=True).rename({ "init": "time" }).resample(time="1MS").interpolate("linear")) pm = pm.generate_uninitialized() assert (not pm.verify( metric="acc", comparison="m2e", dim=["member", "init"], reference=["uninitialized"], )[v].isnull().any()) pm.bootstrap(iterations=2, metric="acc", comparison="m2e", dim=["member", "init"])
def test_PerfectModelEnsemble_plus_defined(PM_ds_initialized_1d, PM_ds_control_1d, other, operator): """Test that PerfectModelEnsemble math operator (+-*/) other works correctly for allowed other types.""" he = PerfectModelEnsemble(PM_ds_initialized_1d) he = he.add_control(PM_ds_control_1d) operator = eval(operator) he2 = operator(he, other) for dataset in he._datasets: if he._datasets[dataset]: print("check", dataset) assert_equal(he2._datasets[dataset], operator(he._datasets[dataset], other)) # check same dims and data_vars as before check_dataset_dims_and_data_vars(he, he2, dataset)
def test_warn_if_chunked_along_init_member_time( hindcast_hist_obs_1d, perfectModelEnsemble_initialized_control): """Test that _warn_if_chunked_along_init_member_time warns.""" he = hindcast_hist_obs_1d with pytest.warns(UserWarning, match="is chunked along dimensions"): he_chunked = HindcastEnsemble(he.get_initialized().chunk( {"init": 10})).add_observations(he.get_observations()) with pytest.raises( ValueError, match="pass ``allow_rechunk=True`` in ``dask_gufunc_kwargs``"): he_chunked.verify(metric="rmse", dim="init", comparison="e2o", alignment="same_inits") with pytest.warns(UserWarning, match="is chunked along dimensions"): he_chunked = HindcastEnsemble(he.get_initialized()).add_observations( he.get_observations().chunk({"time": 10})) with pytest.raises( ValueError, match="pass ``allow_rechunk=True`` in ``dask_gufunc_kwargs``"): he_chunked.verify(metric="rmse", dim="init", comparison="e2o", alignment="same_inits") pm = perfectModelEnsemble_initialized_control with pytest.warns(UserWarning, match="is chunked along dimensions"): PerfectModelEnsemble(pm.get_initialized().chunk({"init": 10}))
def test_PredictionEnsemble_plot( hind_ds_initialized_1d, hist_ds_uninitialized_1d, reconstruction_ds_1d, observations_ds_1d, variable, show_members, x, ): """Test PredictionEnsemble.plot().""" he = HindcastEnsemble(hind_ds_initialized_1d) kws = {"show_members": show_members, "variable": variable, "x": x} he.plot(**kws) he = he.add_uninitialized(hist_ds_uninitialized_1d) he.plot(**kws) he = he.add_observations(reconstruction_ds_1d) he.plot(**kws) he = he.add_observations(observations_ds_1d) he.plot(**kws) if x == "time": pm = PerfectModelEnsemble(hind_ds_initialized_1d) pm.plot(**kws) pm = pm.add_control(hist_ds_uninitialized_1d.isel(member=0, drop=True)) pm.plot(**kws)
def test_PerfectModelEnsemble_area_weighted_mean(PM_ds_initialized_3d): """Test area weighted mean PerfectModelEnsemble.""" he = PerfectModelEnsemble(PM_ds_initialized_3d) # fake area area = np.cos(PM_ds_initialized_3d.lat) + 1 spatial_dims = [ d for d in PM_ds_initialized_3d.dims if d not in CLIMPRED_DIMS ] # PredictionEnsemble doesnt like other data_vars he_self_spatial_mean = (he * area).sum(spatial_dims) / area.sum() # weighted requires Dataset area = area.to_dataset(name="area") he_xr_spatial_mean = he.weighted(area).mean(spatial_dims) assert_PredictionEnsemble(he_self_spatial_mean, he_xr_spatial_mean, how="allclose", rtol=0.03, atol=0.05)
def test_PerfectModelEnsemble_plus_Dataset_different_name( PM_ds_initialized_1d, other, operator): """Test that PerfectModelEnsemble math operator (+-*/) other raises error for Dataset with other dims and/or variables.""" he = PerfectModelEnsemble(PM_ds_initialized_1d) error_str = gen_error_str(he, operator, other) operator = eval(operator) with pytest.raises(VariableError) as excinfo: operator(he, other) assert f"{error_str} with new `data_vars`" in str(excinfo.value)
def test_PerfectModelEnsemble_plus_broadcast(PM_ds_initialized_3d, operator): """Test that PerfectModelEnsemble math operator (+-*/) other also broadcasts correctly.""" he = PerfectModelEnsemble(PM_ds_initialized_3d) operator = eval(operator) # minimal adding an offset or like multiplying area he2 = operator( he, xr.ones_like(PM_ds_initialized_3d.isel(init=1, lead=1, drop=True))) he3 = operator(he, 1) assert_PredictionEnsemble(he2, he3)
def test_PerfectModelEnsemble_plus_not_defined(PM_ds_initialized_1d, other, operator): """Test that PerfectModelEnsemble math operator (+-*/) other raises error for non-defined others.""" he = PerfectModelEnsemble(PM_ds_initialized_1d) error_str = gen_error_str(he, operator, other) operator = eval(operator) with pytest.raises(TypeError) as excinfo: operator(he, other) assert f"{error_str} because type {type(other)} not supported" in str( excinfo.value)
class GeneratePerfectModelEnsembleSmall(GeneratePerfectModelEnsemble): """Generate single grid point `PerfectModelEnsemble`.""" def setup(self, *args, **kwargs): self.get_data(spatial_res=360) self.PredictionEnsemble = PerfectModelEnsemble( self.initialized).add_control(self.observations) self.PredictionEnsemble = self.PredictionEnsemble.generate_uninitialized( ) self.alignment = None self.reference = None self.resample_dim = "member" self.iterations = ITERATIONS
def test_HindcastEnsemble_as_PerfectModelEnsemble(hindcast_recon_1d_mm): """Test that initialized dataset for HindcastEnsemble can also be used for PerfectModelEnsemble.""" v = "SST" alignment = "maximize" hindcast = hindcast_recon_1d_mm.isel(lead=[0, 1]) assert ( not hindcast.verify( metric="acc", comparison="e2o", dim="init", alignment=alignment )[v] .isnull() .any() ) # try PerfectModelEnsemble predictability init = hindcast.get_initialized() pm = PerfectModelEnsemble(init) assert ( not pm.verify(metric="acc", comparison="m2e", dim=["member", "init"])[v] .isnull() .any() )
def test_PerfectModelEnsemble_time_resolution_verify( HindcastEnsemble_time_resolution): """Test that PerfectModelEnsemble.verify() in any lead time resolution works.""" pm = PerfectModelEnsemble( HindcastEnsemble_time_resolution.get_initialized()) assert pm.verify(**PerfectModelEnsemble_verify_kw).notnull().any()
def perfectModelEnsemble_initialized_control(PM_ds_initialized_1d, PM_ds_control_1d): """PerfectModelEnsemble initialized with `initialized` and `control` xr.Dataset.""" pm = PerfectModelEnsemble(PM_ds_initialized_1d) pm = pm.add_control(PM_ds_control_1d) return pm
def test_bootstrap(pm_ds_ds1d, pm_ds_control1d): """Test that perfect model ensemble object can be bootstrapped""" pm = PerfectModelEnsemble(pm_ds_ds1d) pm.add_control(pm_ds_control1d) pm.bootstrap(bootstrap=2)
def test_compute_persistence(pm_ds_ds1d, pm_ds_control1d): """Test that compute persistence can be run for perfect model ensemble""" pm = PerfectModelEnsemble(pm_ds_ds1d) pm.add_control(pm_ds_control1d) pm.compute_persistence()
def perfectModelEnsemble_3v_initialized_control_1d( PM_ds3v_initialized_1d, PM_ds3v_control_1d ): """PerfectModelEnsemble 1d initialized with `initialized` and `control` xr.Dataset with three variables.""" return PerfectModelEnsemble(PM_ds3v_initialized_1d).add_control(PM_ds3v_control_1d)
def test_inplace(PM_ds_initialized_1d, PM_ds_control_1d): """Tests that inplace operations do not work.""" pm = PerfectModelEnsemble(PM_ds_initialized_1d) # Adding a control. pm.add_control(PM_ds_control_1d) with_ctrl = pm.add_control(PM_ds_control_1d) assert pm != with_ctrl # Adding an uninitialized ensemble. pm = pm.add_control(PM_ds_control_1d) pm.generate_uninitialized() with_uninit = pm.generate_uninitialized() assert pm != with_uninit # Applying arbitrary func. pm.sum("init") summed = pm.sum("init") assert pm != summed
def test_add_control(pm_ds_ds1d, pm_ds_control1d): """Test to see if control can be added to PerfectModelEnsemble""" pm = PerfectModelEnsemble(pm_ds_ds1d) pm.add_control(pm_ds_control1d)
def test_PerfectModelEnsemble_plot_fails_3d(PM_ds_initialized_3d): """Test PredictionEnsemble.plot().""" pm = PerfectModelEnsemble(PM_ds_initialized_3d) with pytest.raises(DimensionError) as excinfo: pm.plot() assert "does not allow dimensions other" in str(excinfo.value)
def test_perfectModelEnsemble_init_da(PM_da_initialized_1d): """Test to see if perfect model ensemble can be initialized with da""" pm = PerfectModelEnsemble(PM_da_initialized_1d) assert pm
def test_generate_uninit(pm_ds_ds1d, pm_ds_control1d): """Test to see if uninitialized ensemble can be bootstrapped""" pm = PerfectModelEnsemble(pm_ds_ds1d) pm.add_control(pm_ds_control1d) pm.generate_uninitialized()
def test_compute_metric(pm_ds_ds1d, pm_ds_control1d): """Test that metric can be computed for perfect model ensemble""" pm = PerfectModelEnsemble(pm_ds_ds1d) pm.add_control(pm_ds_control1d) pm.compute_metric()
def test_get_initialized(PM_ds_initialized_1d): """Test whether get_initialized function works.""" pm = PerfectModelEnsemble(PM_ds_initialized_1d) init = pm.get_initialized() assert init == pm._datasets["initialized"]
def test_compute_uninitialized(pm_ds_ds1d, pm_ds_control1d): """Test that compute uninitialized can be run for perfect model ensemble""" pm = PerfectModelEnsemble(pm_ds_ds1d) pm.add_control(pm_ds_control1d) pm.generate_uninitialized() pm.compute_uninitialized()
def test_perfectModelEnsemble_init(PM_ds_initialized_1d): """Test to see if perfect model ensemble can be initialized""" pm = PerfectModelEnsemble(PM_ds_initialized_1d) print(PerfectModelEnsemble) assert pm
def perfectModelEnsemble_initialized_control_3d_North_Atlantic( PM_ds_initialized_3d, PM_ds_control_3d ): """PerfectModelEnsemble with `initialized` and `control` for the North Atlantic.""" return PerfectModelEnsemble(PM_ds_initialized_3d).add_control(PM_ds_control_3d)