def test_exponential_variance_of_stokes_synthetic(): """ Produces a synthetic Stokes measurement with a known noise distribution. Check if same variance is obtained. Returns ------- """ yvar = 5. nx = 50 x = np.linspace(0., 20., nx) nt = 200 beta = np.linspace(3000, 4000, nt)[None] y = beta * np.exp(-0.001 * x[:, None]) y += stats.norm.rvs(size=y.size, scale=yvar**0.5).reshape(y.shape) ds = DataStore( { 'ST': (['x', 'time'], y), 'probe1Temperature': (['time'], range(nt)), 'userAcquisitionTimeFW': (['time'], np.ones(nt)), }, coords={ 'x': x, 'time': range(nt) }, attrs={'isDoubleEnded': '0'}) sections = { 'probe1Temperature': [ slice(0., 20.), ] } test_ST_var, _ = ds.variance_stokes_exponential(st_label='ST', sections=sections) np.testing.assert_almost_equal(test_ST_var, yvar, decimal=1)
def test_single_ended_exponential_variance_estimate_synthetic(): import dask.array as da from dtscalibration import DataStore import numpy as np from scipy import stats np.random.seed(0) state = da.random.RandomState(0) stokes_m_var = 40. astokes_m_var = 60. cable_len = 100. nt = 50 time = np.arange(nt) x = np.linspace(0., cable_len, 500) ts_cold = np.ones(nt) * 4. ts_warm = np.ones(nt) * 20. C_p = 15246 C_m = 2400. dalpha_r = 0.0005284 dalpha_m = 0.0004961 dalpha_p = 0.0005607 gamma = 482.6 cold_mask = x < 0.5 * cable_len warm_mask = np.invert(cold_mask) # == False temp_real = np.ones((len(x), nt)) temp_real[cold_mask] *= ts_cold + 273.15 temp_real[warm_mask] *= ts_warm + 273.15 st = C_p * np.exp(-dalpha_r * x[:, None]) * np.exp( -dalpha_p * x[:, None]) * np.exp( -gamma / temp_real) / (1 - np.exp(-gamma / temp_real)) ast = C_m * np.exp(-dalpha_r * x[:, None]) * np.exp( -dalpha_m * x[:, None]) / (1 - np.exp(-gamma / temp_real)) st_m = st + stats.norm.rvs(size=st.shape, scale=stokes_m_var**0.5) ast_m = ast + stats.norm.rvs(size=ast.shape, scale=astokes_m_var**0.5) print('alphaint', cable_len * (dalpha_p - dalpha_m)) print('alpha', dalpha_p - dalpha_m) print('C', np.log(C_p / C_m)) print('x0', x.max()) ds = DataStore( { 'st': (['x', 'time'], st), 'ast': (['x', 'time'], ast), 'mst': (['x', 'time'], st_m), 'mast': (['x', 'time'], ast_m), 'userAcquisitionTimeFW': (['time'], np.ones(nt)), 'cold': (['time'], ts_cold), 'warm': (['time'], ts_warm) }, coords={ 'x': x, 'time': time }, attrs={'isDoubleEnded': '0'}) sections = { 'cold': [slice(0., 0.5 * cable_len)], 'warm': [slice(0.5 * cable_len, cable_len)] } st_label = 'mst' ast_label = 'mast' mst_var, _ = ds.variance_stokes_exponential(st_label=st_label, sections=sections) mast_var, _ = ds.variance_stokes_exponential(st_label=ast_label, sections=sections) # MC variqnce ds.calibration_single_ended(sections=sections, st_label=st_label, ast_label=ast_label, st_var=mst_var, ast_var=mast_var, method='wls', solver='sparse') ds.conf_int_single_ended(p_val='p_val', p_cov='p_cov', st_label=st_label, ast_label=ast_label, st_var=mst_var, ast_var=mast_var, store_tmpf='TMPF', store_tempvar='_var', conf_ints=[2.5, 50., 97.5], mc_sample_size=500, ci_avg_time_flag=False, da_random_state=state) # Calibrated variance stdsf1 = ds.ufunc_per_section(label='TMPF', func=np.std, temp_err=True, calc_per='stretch', ddof=1) # Use a single timestep to better check if the parameter uncertainties propagate ds1 = ds.isel(time=1) # Estimated VAR stdsf2 = ds1.ufunc_per_section(label='TMPF_MC_var', func=np.mean, temp_err=False, calc_per='stretch') for (_, v1), (_, v2) in zip(stdsf1.items(), stdsf2.items()): for v1i, v2i in zip(v1, v2): print('Real VAR: ', v1i**2, 'Estimated VAR: ', v2i) np.testing.assert_almost_equal(v1i**2, v2i, decimal=2) pass