Exemplo n.º 1
0
def lowess_homemade_kern(x, y, w, a1, kernel='Exp'):
    """
    #inspired by: https://xavierbourretsicotte.github.io/loess.html
    homebaked lowess with variogram kernel + heteroscedasticity of observations with error

    :param x:x
    :param y:y
    :param w: heteroscedastic weights (inverse of variance)
    :param a1: range of the kernel (in variogram terms)
    :param kernel: kernel function
    :return:
    """

    n = len(x)
    yest = np.zeros(n)
    err_yest = np.zeros(n)

    if kernel == 'Gau':
        kernel_fun = kernel_gaussian
    elif kernel == 'Exp':
        kernel_fun = kernel_exp
    elif kernel == 'Exc':
        kernel_fun = kernel_exclass
    else:
        print('Kernel not recognized.')
        sys.exit()

    W = np.array([kernel_fun(x, x[i], a1) * w for i in range(n)]).T
    X = np.array([x for i in range(n)]).T
    Y = np.array([y for i in range(n)]).T

    beta1, beta0, _, Yl, Yu = ft.wls_matrix(X, Y, W, conf_interv=0.68)

    for i in range(n):
        yest[i] = beta1[i] * x[i] + beta0[i]
        err_yest[i] = (Yu[i, i] - Yl[i, i]) / 2

    return yest, err_yest
#     new_err_vals[i] = np.nanmean(err_vals[ind])
# data_vals = new_data_vals
# time_vals = new_time_vals
# err_vals = new_err_vals
# good_vals = np.isfinite(data_vals)

# here we need to change the 0 for the x axis, in case we are using a linear kernel

ax = fig.add_subplot(grid[6:12,5:])

ax.text(0.025, 0.95, 'd', transform=ax.transAxes,
        fontsize=16, fontweight='bold', va='top', ha='left')

while (n_out > 0 or final_fit==0) and num_finite >= 2:

    beta1, beta0, incert_slope, _, _ = ft.wls_matrix(time_vals[good_vals], data_vals[good_vals],
                                                     1. / err_vals[good_vals], conf_slope=0.99)

    # standardized dispersion from linearity
    res_stdized = np.sqrt(np.mean(
        (data_vals[good_vals] - (beta0 + beta1 * time_vals[good_vals])) ** 2 / err_vals[good_vals]))
    res = np.sqrt(np.mean((data_vals[good_vals] - (beta0 + beta1 * time_vals[good_vals])) ** 2))
    if perc_nonlin[min(niter, len(perc_nonlin) - 1)] == 0:
        opt_var = 0
    else:
        opt_var = (res / res_stdized ** 2) ** 2 * 100. / (5 * perc_nonlin[min(niter, len(perc_nonlin) - 1)])

    k1 = PairwiseKernel(1, metric='linear') + PairwiseKernel(1, metric='linear') * C(opt_var) * RQ(10, 3)  # linear kernel
    k2 = C(30) * ESS(length_scale=1, periodicity=1)  # periodic kernel
    k3 = C(50) * RBF(0.75)
    kernel = k1 + k2 + k3
def bin_valid_df_by_vals(df,
                         bins,
                         bins_val,
                         list_var=['dh', 'zsc'],
                         ls_dvardt=True,
                         weight_ib=1. / 40,
                         return_ls=False):

    mid_bin, med, std, dvardt, dvardt_2std, ns_ics, ns_ib = ([]
                                                             for i in range(7))
    for i in range(len(bins) - 1):
        ind = np.logical_and(bins_val >= bins[i], bins_val < bins[i + 1])
        df_ind = df[ind]
        nics = np.count_nonzero(df_ind.sensor == 'ICS')
        nib = np.count_nonzero(df_ind.sensor == 'IB')
        ns_ics.append(nics)
        ns_ib.append(nib)
        mid_bin.append(bins[i] + 0.5 * (bins[i + 1] - bins[i]))

        sub_med = []
        sub_std = []
        sub_dvardt = []
        sub_dvardt_2std = []
        sub_mu = []
        sub_w = []
        sub_t = []
        for var in list_var:
            if weight_ib is not None:
                if nics != 0 or nib != 0:
                    sub_med.append(
                        np.nansum(
                            (np.nanmedian(
                                df_ind[df_ind.sensor == 'ICS'][var]) * nics,
                             np.nanmedian(df_ind[df_ind.sensor == 'IB'][var]) *
                             nib * weight_ib)) / (nics + nib * weight_ib))
                    sub_std.append(
                        np.nansum(
                            (nmad(df_ind[df_ind.sensor == 'ICS'][var]) * nics,
                             nmad(df_ind[df_ind.sensor == 'IB'][var]) * nib *
                             weight_ib)) / (nics + nib * weight_ib))
                else:
                    sub_med.append(np.nan)
                    sub_std.append(np.nan)
            else:
                sub_med.append(np.nanmedian(df_ind[var]))
                sub_std.append(nmad(df_ind[var].values))

            if ls_dvardt:
                list_t = sorted(list(set(list(df_ind.t.values))))
                ftime_delta = np.array([
                    (np.datetime64(t) -
                     np.datetime64('{}-01-01'.format(int(2000)))).astype(int) /
                    365.2422 for t in list_t
                ])
                mu = []
                w = []
                for val_t in list_t:
                    ind_t = df_ind.t.values == val_t
                    df_ind_t = df_ind[ind_t]
                    nics_t = np.count_nonzero(df_ind_t.sensor == 'ICS')
                    nib_t = np.count_nonzero(df_ind_t.sensor == 'IB')
                    if np.count_nonzero(ind_t) > 20:
                        med_t = np.nansum(
                            (np.nanmedian(
                                df_ind_t[df_ind_t.sensor == 'ICS'][var]) *
                             nics_t,
                             np.nanmedian(
                                 df_ind_t[df_ind_t.sensor == 'IB'][var]) *
                             nib_t * weight_ib)) / (nics_t + nib_t * weight_ib)
                        mu.append(med_t)
                        std_t = np.nansum(
                            (nmad(df_ind_t[df_ind_t.sensor == 'ICS'][var]) *
                             nics_t,
                             nmad(df_ind_t[df_ind_t.sensor == 'IB'][var]) *
                             nib_t * weight_ib)) / (nics_t + nib_t * weight_ib)
                        w.append(std_t / np.sqrt(nics_t + nib_t * weight_ib))
                    else:
                        mu.append(np.nan)
                        w.append(np.nan)
                mu = np.array(mu)
                w = np.array(w)
                if np.count_nonzero(~np.isnan(mu)) > 5:
                    # reg = LinearRegression().fit(ftime_delta[~np.isnan(mu)].reshape(-1, 1),
                    #                              mu[~np.isnan(mu)].reshape(-1, 1))

                    beta1, _, incert_slope, _, _ = ft.wls_matrix(
                        ftime_delta[~np.isnan(mu)],
                        mu[~np.isnan(mu)],
                        1. / w[~np.isnan(mu)]**2,
                        conf_slope=0.95)
                    # fig = plt.figure()
                    # plt.scatter(ftime_delta,mu_dh,color='red')
                    # plt.plot(np.arange(0,10,0.1),reg.predict(np.arange(0,10,0.1).reshape(-1,1)),color='black',label=reg)
                    # plt.ylim([-20,20])
                    # plt.text(5,0,str(reg.coef_[0]))
                    # plt.legend()
                    # coef = reg.coef_[0][0]
                    coef = beta1
                    sub_dvardt.append(coef)
                    sub_dvardt_2std.append(incert_slope)
                else:
                    sub_dvardt.append(np.nan)
                    sub_dvardt_2std.append(np.nan)

                sub_mu.append(mu)
                sub_w.append(w)
                sub_t.append(ftime_delta)
        med.append(sub_med)
        std.append(sub_std)
        dvardt.append(sub_dvardt)
        dvardt_2std.append(sub_dvardt_2std)

    df_out = pd.DataFrame()
    df_out = df_out.assign(mid_bin=mid_bin, ns_ics=ns_ics, ns_ib=ns_ib)
    for var in list_var:
        df_out['med_' + var] = list(zip(*med))[list_var.index(var)]
        df_out['nmad_' + var] = list(zip(*std))[list_var.index(var)]
        if ls_dvardt:
            df_out['d' + var + '_dt'] = list(zip(*dvardt))[list_var.index(var)]
            df_out['d' + var + '_dt_2std'] = list(
                zip(*dvardt_2std))[list_var.index(var)]

    if return_ls and ls_dvardt:
        df_ls = pd.DataFrame()
        for var in list_var:
            # print(len(sub_mu))
            df_ls['mu_' + var] = sub_mu[list_var.index(var)]
            df_ls['w_' + var] = sub_w[list_var.index(var)]
            df_ls['t_' + var] = sub_t[list_var.index(var)]
        return df_out, df_ls
    else:
        return df_out
                               '2000-01-01_2020-01-01'].err_dmdt.values[0]) +
      ' Gt yr-1')

print('Glacier mass loss totalled ' + '{:.3f}'.format(glac_trend) + ' ± ' +
      '{:.3f}'.format(2 * glac_trend_err) + ' mm of sea-level rise')

contr_trend = -glac_trend / gmsl_trend * 100
contr_trend_err = -glac_trend / gmsl_trend * np.sqrt(
    (gmsl_trend_err / gmsl_trend)**2 + (glac_trend_err / glac_trend)**2) * 100
print('Glacier contribution to SLR is ' + '{:.2f}'.format(contr_trend) +
      ' % ± ' + '{:.2f}'.format(2 * contr_trend_err) + ' %')

#GLACIER ACCELERATION

beta1_t, beta0, incert_slope, _, _ = ft.wls_matrix(
    x=np.arange(0, 16, 5),
    y=df_g.dhdt.values[:-1],
    w=1 / df_g.err_dhdt.values[:-1]**2)
print('Global thinning acceleration is ' + '{:.5f}'.format(beta1_t) + ' ± ' +
      '{:.5f}'.format(2 * incert_slope) + ' m yr-2')
beta1, beta0, incert_slope, _, _ = ft.wls_matrix(x=np.array([0, 5, 10, 15]),
                                                 y=df_np.dhdt.values[:-1],
                                                 w=1 /
                                                 df_np.err_dhdt.values[:-1]**2)
print('Global excl. GRL and ANT thinning acceleration is ' +
      '{:.5f}'.format(beta1) + ' ± ' + '{:.5f}'.format(2 * incert_slope) +
      ' m yr-2')

beta1_g, beta0, incert_slope_g, _, _ = ft.wls_matrix(
    x=np.arange(0, 16, 5),
    y=df_g.dmdt.values[:-1],
    w=1 / df_g.err_dmdt.values[:-1]**2)