"""Reproduce results from `bib.sakov2008deterministic`.""" import numpy as np import dapper.mods as modelling from dapper.mods.QG import LP_setup, model_config, sample_filename, shape from dapper.tools.localization import nd_Id_localization ############################ # Time series, model, initial condition ############################ model = model_config("sakov2008", {}) Dyn = { 'M': np.prod(shape), 'model': model.step, 'noise': 0, } # Considering that I have 8GB mem on the Mac, and the estimate: # ≈ (8 bytes/float)*(129² float/stat)*(7 stat/k) * K, # it should be possible to run experiments of length (K) < 8000. t = modelling.Chronology(dt=model.prms['dtout'], dko=1, T=1500, BurnIn=250) # In my opinion the burn in should be 400. # Sakov also used 10 repetitions. X0 = modelling.RV(M=Dyn['M'], file=sample_filename) ############################ # Observation settings
"""Reproduce experiments from 'Application of a hybrid EnKF-OI to ocean forecasting' by F. Counillon, P. Sakov, and L. Bertino (2009).""" import dapper as dpr from dapper.mods.QG import model_config from dapper.mods.QG.sakov2008 import HMM dt = 1.25 * 10 # 10 steps between obs (also requires dkObs=1) HMM.t = dpr.Chronology(dt=dt, dkObs=1, T=1000 * dt, BurnIn=10 * dt) HMM.Dyn.model = model_config("counillon2009_ens", { "dtout": dt, 'RKH2': 2.0e-11 }).step truth_model = model_config("counillon2009_truth", {"dtout": dt}).step #################### # Suggested tuning #################### # Reproduce Table 1 results. # - Note that Counillon et al: # - Report forecast rmse's (but they are pretty close to analysis rmse anyways). # - Use enkf-matlab which has a bug which cause them to report the # wrong localization radius (see mods/QG/sakov2008.py). # Eg. enkf-matlab radius 15 (resp 25) corresponds to # DAPPER radius 10.6 (resp 17.7). # R = 17.7 # equiv. to R=25 in enkf-matlab # from dapper.mods.QG.counillon2009 import HMM, truth_model # rmse.f: # xps += LETKF(mp=True, N=25,infl=1.15,taper='Gauss',loc_rad=R) # 1.11
x0 = KS.x0 dt = KS.dt N = KS.Nx Nx = len(x0) T = 1e3 eps = 0.0002 # n0 ≈ 140 if mod == "QG": from dapper.mods.QG import model_config, sample_filename, shape # NB: There may arise an ipython/multiprocessing bug/issue. # Ref https://stackoverflow.com/a/45720872 . If so, set mp=False, # or run outside of ipython. However, I did not encounter it lately. model = model_config("sakov2008", {}, mp=True) step = model.step Nx = np.prod(shape) ii = np.random.choice(np.arange(Nx), 100, False) T = 1000.0 dt = model.prms['dtout'] x0 = np.load(sample_filename)['sample'][-1] eps = 0.01 # ensemble rescaling N = 300 ######################## # Reference trajectory ######################## # NB: Arbitrary, coz models are autonom. But dont use nan coz QG doesn't like it. t0 = 0.0
# Main ########### # Load or generate time-series data of a simulated state and obs: fname = dpr.rc.dirs.data / "QG-ts-en.npz" np.random.seed(123) # ensemble size needs to be at least Ne=2 for plotting to be true plotting = True Ne = 2 try: with np.load(fname) as data: E1 = np.squeeze(data['ens'][:, 0, :]) E2 = np.squeeze(data['ens'][:, 1, :]) except FileNotFoundError: sample = gen_ensemble_sample(model_config("sample_generation", {}), 400, Ne, 10, 10) E1 = np.squeeze(sample[:, 0, :]) E2 = np.squeeze(sample[:, 1, :]) np.savez(fname, ens=sample) if plotting == True: # Create figure fig, (ax1, ax2) = plt.subplots(ncols=2, sharex=True, sharey=True, figsize=(12, 6)) for ax in (ax1, ax2): ax.set_aspect('equal', 'box') ax1.set_title(r'Ensemble member 1') ax2.set_title(r'Ensemble member 2')