def cal_gam(pr, et):
    slope, intercept, r, p, std_err = ols(pr, et)
    if p < 0.01:
        gam = (r) * (np.nanstd(et) / np.nanstd(pr))
    else:
        gam = np.nan
    return (gam)
Exemple #2
0
 def __init__(self, x, y):
     x = np.array(x)
     y = np.array(y)
     self.b, self.a, *other = ols(x, y)
     self.T = len(x)
     n = self.T
     # sample property
     self.x_mean = x.mean()
     self.y_mean = y.mean()
     self.x_sigma = x.std(ddof=1)
     self.y_sigma = y.std(ddof=1)
     self.y_hat = self.b * x + self.a
     self.u_hat = y - self.y_hat
     # prediction check
     self.RSS = ((self.u_hat)**2).sum()
     self.TSS = ((y - self.y_mean)**2).sum()
     self.ESS = self.TSS - self.RSS
     self.R_2 = 1 - self.RSS / self.TSS
     self.R_2_adj = 1 - self.RSS / (self.T - 2) / (self.TSS / (self.T - 1))
     # estimator check
     self.u_sigma_hat = np.sqrt(self.RSS / (self.T - 2))
     self.b_sigma = self.u_sigma_hat / np.sqrt(x.std(ddof=0)**2 * n)
     self.a_sigma = self.b_sigma * np.sqrt(x.std(ddof=0)**2 + x.mean()**2)
     # ddof = T-2
     self.a_hat_tstat = self.a / self.a_sigma
     self.b_hat_tstat = self.b / self.b_sigma
def calculating_t_et(t_anom, et_anom, ols_out='r',
                     wet_bool=None, season=None, weighting=False,
                     corr_method='pearson'):

    # Define arrays to store data
    len_lat = t_anom.shape[-2]
    len_lon = t_anom.shape[-1]
    t_et = np.nan * np.empty((len_lat, len_lon))
    pval_array = np.nan * np.empty((len_lat, len_lon))

    for ny in range(len_lat):
        for nx in range(len_lon):

            # Extract data from one grid cell
            if wet_bool is not None:
                    if season == 'wet':
                        i, = np.where(wet_bool[:, ny, nx] == 1)
                        surf_temp = t_anom.data[i, ny, nx]
                        flux_temp = et_anom.data[i, ny, nx]

                    elif season == 'dry':
                        i, = np.where((wet_bool[:, ny, nx]) == 0)
                        surf_temp = t_anom.data[i, ny, nx]
                        flux_temp = et_anom.data[i, ny, nx]
            else:
                surf_temp = t_anom.data[:, ny, nx]
                flux_temp = et_anom.data[:, ny, nx]

            # 1. Find which months both surface and flux variables have data
            mask = ~np.isnan(surf_temp) & ~np.isnan(flux_temp)

            # Provided at least one month overlap proceed with calc
            if len(surf_temp[mask]) > 10:

                # Save t_et and p value
                if ols_out == 'slope':
                    slope, intercept, r, p, std_err = ols(surf_temp[mask],
                                                          flux_temp[mask])
                    t_et[ny, nx] = slope
                    pval_array[ny, nx] = p
                    
                elif ols_out == 'r':
                    
                    if corr_method == 'pearson':
                        r, p = pearsonr(surf_temp[mask], flux_temp[mask])
                        
                    if corr_method == 'spearman':
                        r, p = spearmanr(surf_temp[mask], flux_temp[mask])
                    
                    t_et[ny, nx] = r    
                    pval_array[ny, nx] = p

            # Weight by variability of denominator to emphasise 
            # places where actual impact is large
            if weighting is True:
                if (t_et[ny, nx] != -999.0):
                    t_et[ny, nx] = t_et[ny, nx] * np.std(surf_temp[mask])
    print(np.nanmin(t_et), np.nanmax(t_et))
    return(t_et, pval_array)
def cal_tci(s, e, ols_out='slope', weighting=True):
    slope, intercept, r, p, std_err = ols(s, e)
    # If significant then save value otherwise NaN
    if p < 0.01:
        if ols_out == 'slope':
            tc = slope
        elif ols_out == 'r':
            tc = r
    else:
        tc = -999.0
    # Weight by variability of denominator (see Dirmeyer et al., 2011). This emphasises places where actual impact is large
    if weighting is True:
        if (tc != -999.0):
            tci = tc * np.nanstd(s)
        else:
            tci = tc * np.nan
        return (tci)

    if weighting is False:
        if (tc != -999.0):
            tci = tc * 1
        else:
            tci = tc * np.nan
        return (tci)
Exemple #5
0
def calculating_legs(surf_var,
                     flux_var,
                     atm_var,
                     ols_out='slope',
                     wet_bool=None,
                     season=None,
                     weighting=True,
                     p_thresh=0.05,
                     corr_method='pearson'):

    len_lat = surf_var.shape[-2]
    len_lon = surf_var.shape[-1]

    # Define arrays to store data
    surf_leg = np.empty((len_lat, len_lon))
    surf_leg[:] = np.nan
    surf_pvals = np.empty((len_lat, len_lon))
    surf_pvals[:] = np.nan
    atm_leg = np.empty((len_lat, len_lon))
    atm_leg[:] = np.nan
    atm_pvals = np.empty((len_lat, len_lon))
    atm_pvals[:] = np.nan
    product = np.empty((len_lat, len_lon))
    product[:] = np.nan
    product_pvals = np.empty((len_lat, len_lon))
    product_pvals[:] = np.nan

    for ny in range(surf_var.shape[-2]):
        for nx in range(surf_var.shape[-1]):

            # Extract data from one grid cell
            if wet_bool is not None:
                if season == 'wet':
                    i, = np.where(wet_bool[:, ny, nx] == 1)
                    surf_temp = surf_var[i, ny, nx]
                    flux_temp = flux_var[i, ny, nx]
                    atm_temp = atm_var[i, ny, nx]
                elif season == 'dry':
                    i, = np.where((wet_bool[:, ny, nx]) == 0)
                    surf_temp = surf_var[i, ny, nx]
                    flux_temp = flux_var[i, ny, nx]
                    atm_temp = atm_var[i, ny, nx]
            else:
                surf_temp = surf_var[:, ny, nx]
                flux_temp = flux_var[:, ny, nx]
                atm_temp = atm_var[:, ny, nx]

            # First calculate surface leg of metric
            # 1. Find which months both surface and flux variables have data
            mask1 = ~np.isnan(surf_temp) & ~np.isnan(flux_temp)

            # Provided at least 10 months overlap proceed with calc
            if len(surf_temp[mask1]) > 10:

                # If significant then save value otherwise -999
                if ols_out == 'slope':
                    slope, intercept, r, p, std_err = ols(
                        surf_temp[mask1], flux_temp[mask1])
                    surf_leg[ny, nx] = slope
                    surf_pvals[ny, nx] = p

                elif ols_out == 'r':

                    if corr_method == 'pearson':
                        r, p = pearsonr(surf_temp[mask1], flux_temp[mask1])

                    if corr_method == 'spearman':
                        r, p = spearmanr(surf_temp[mask1], flux_temp[mask1])

                    surf_leg[ny, nx] = r
                    surf_pvals[ny, nx] = p

            # As above for atmospheric leg
            # Find which months both flux and atm variables have data
            mask2 = ~np.isnan(flux_temp) & ~np.isnan(atm_temp)
            if len(flux_temp[mask2]) > 10:

                if ols_out == 'slope':
                    slope, intercept, r, p, std_err = ols(
                        flux_temp[mask2], atm_temp[mask2])
                    atm_leg[ny, nx] = slope
                    atm_pvals[ny, nx] = p

                elif ols_out == 'r':
                    if corr_method == 'pearson':
                        r, p = pearsonr(flux_temp[mask2], atm_temp[mask2])

                    if corr_method == 'spearman':
                        r, p = spearmanr(flux_temp[mask2], atm_temp[mask2])

                    atm_leg[ny, nx] = r
                    atm_pvals[ny, nx] = p

            # Calculate response of atm var to surface var
            product[ny, nx] = surf_leg[ny, nx] * atm_leg[ny, nx]
            product_pvals[ny,
                          nx] = max([surf_pvals[ny, nx], atm_pvals[ny, nx]])

            # Weight by variability of denominator (see Dirmeyer et al., 2014)
            # this emphasises places where actual impact is large
            if weighting is True:
                #                if (surf_pvals[ny, nx] < p_thresh):
                surf_leg[ny, nx] = surf_leg[ny, nx] *\
                                   np.std(surf_temp[mask1])
                #                if (atm_pvals[ny, nx] < p_thresh):
                atm_leg[ny, nx] = atm_leg[ny, nx] *\
                                  np.std(flux_temp[mask2])
                #                if (product_pvals[ny, nx] < p_thresh):
                product[ny, nx] = product[ny, nx] *\
                                  np.std(surf_temp[mask1])

    print(np.nanmin(surf_leg), np.nanmax(surf_leg))
    print(np.nanmin(atm_leg), np.nanmax(atm_leg))
    print(np.nanmin(product), np.nanmax(product))
    #    assert False
    return (surf_leg, surf_pvals, atm_leg, atm_pvals, product, product_pvals)