Beispiel #1
0
 def test_signchange(self):
     ts = pd.Series([-2., -1., 1., 2., 3], index=np.arange(5))
     sc = utils.signchange(ts)
     assert_array_equal(sc, [0, 0, 1, 0, 0])
     ts = pd.Series([-2., -1., 1., 2., 3][::-1], index=np.arange(5))
     sc = utils.signchange(ts)
     assert_array_equal(sc, [0, 0, 0, 1, 0])
Beispiel #2
0
 def test_signchange(self):
     ts = pd.Series([-2., -1., 1., 2., 3], index=np.arange(5))
     sc = utils.signchange(ts)
     assert_array_equal(sc, [0, 0, 1, 0, 0])
     ts = pd.Series([-2., -1., 1., 2., 3][::-1], index=np.arange(5))
     sc = utils.signchange(ts)
     assert_array_equal(sc, [0, 0, 0, 1, 0])
Beispiel #3
0
def t_star_from_refmb(gdir, mbdf):
    """Computes the t* for the glacier, given a series of MB measurements.

    Could be multiprocessed but its probably not necessary.

    Parameters
    ----------
    gdirs: the list of oggm.GlacierDirectory objects where to write the data.
    mbdf: a pd.Series containing the observed MB data indexed by year

    Returns
    -------
    A dict: {t_star:[], bias:[], bias_std:[], prcp_fac:float}
    """

    # Only divide 0, we believe the original RGI entities to be the ref...
    years, temp_yr_ts, prcp_yr_ts = mb_yearly_climate_on_glacier(gdir, 1.,
                                                                 div_id=0)

    # which years to look at
    selind = np.searchsorted(years, mbdf.index)
    temp_yr_ts = temp_yr_ts[selind]
    prcp_yr_ts = prcp_yr_ts[selind]
    temp_yr = np.mean(temp_yr_ts)
    prcp_yr = np.mean(prcp_yr_ts)

    # Average oberved mass-balance
    ref_mb = np.mean(mbdf)
    ref_mb_std = np.std(mbdf)

    # Average mass-balance per mu and fac
    mu_yr_clim_df = gdir.read_pickle('mu_candidates', div_id=0)

    odf = pd.DataFrame(index=mu_yr_clim_df.columns)
    out = dict()
    for prcp_fac in mu_yr_clim_df:

        mu_yr_clim = mu_yr_clim_df[prcp_fac]
        nmu = len(mu_yr_clim)
        mb_per_mu = prcp_yr * prcp_fac - mu_yr_clim * temp_yr
        mbts_per_mu = np.atleast_2d(prcp_yr_ts * prcp_fac).repeat(nmu, 0) - \
                      np.atleast_2d(mu_yr_clim).T * \
                      np.atleast_2d(temp_yr_ts).repeat(nmu, 0)
        std_per_mu = mb_per_mu*0 + np.std(mbts_per_mu, axis=1)

        # Diff to reference
        diff = (mb_per_mu - ref_mb).dropna()
        diff_std = (std_per_mu - ref_mb_std).dropna()
        signchange = utils.signchange(diff)

        # If sign changes save them
        # TODO: ideas to do this better:
        #  - apply a smooth (take noise into account)
        #  - take longer stable periods into account
        # these stuffs could be proven better (or not) with cross-val
        pchange = np.where(signchange == 1)[0]
        years = diff.index
        diff = diff.values
        diff_std = diff_std.values
        if len(pchange) > 0:
            t_stars = []
            bias = []
            std_bias = []
            for p in pchange:
                # Check the side with the smallest bias
                ide = p-1 if np.abs(diff[p-1]) < np.abs(diff[p]) else p
                if years[ide] not in t_stars:
                    t_stars.append(years[ide])
                    bias.append(diff[ide])
                    std_bias.append(diff_std[ide])
        else:
            amin = np.argmin(np.abs(diff))
            t_stars = [years[amin]]
            bias = [diff[amin]]
            std_bias = [diff_std[amin]]

        # (prcp_fac, t_stars, bias, std_bias)
        odf.loc[prcp_fac, 'avg_bias'] = np.mean(bias)
        odf.loc[prcp_fac, 'avg_std_bias'] = np.mean(std_bias)
        odf.loc[prcp_fac, 'n_tstar'] = len(std_bias)
        out[prcp_fac] = {'t_star': t_stars, 'bias': bias, 'std_bias': std_bias,
                         'prcp_fac': prcp_fac}

    # write
    gdir.write_pickle(odf, 'prcp_fac_optim')

    # we take the closest result and see later if it needs cleverer handling
    amin = np.argmin(np.abs(odf.avg_std_bias))  # this gives back an index!
    return out[amin]
Beispiel #4
0
def t_star_from_refmb(gdir, mbdf):
    """Computes the t* for the glacier, given a series of MB measurements.

    Could be multiprocessed but its probably not necessary.

    Parameters
    ----------
    gdirs: the list of oggm.GlacierDirectory objects where to write the data.
    mbdf: a pd.Series containing the observed MB data indexed by year

    Returns:
    --------
    (t_star, bias, prcp_fac): lists of t*, their associated bias and a prcp fac
    """

    # Only divide 0, we believe the original RGI entities to be the ref...
    years, temp_yr_ts, prcp_yr_ts = mb_yearly_climate_on_glacier(gdir, 1.,
                                                                 div_id=0)

    # which years to look at
    selind = np.searchsorted(years, mbdf.index)
    temp_yr_ts = temp_yr_ts[selind]
    prcp_yr_ts = prcp_yr_ts[selind]
    temp_yr = np.mean(temp_yr_ts)
    prcp_yr = np.mean(prcp_yr_ts)

    # Average oberved mass-balance
    ref_mb = np.mean(mbdf)
    ref_mb_std = np.std(mbdf)

    # Average mass-balance per mu and fac
    mu_yr_clim_df = gdir.read_pickle('mu_candidates', div_id=0)

    odf = pd.DataFrame(index=mu_yr_clim_df.columns)
    out = dict()
    for prcp_fac in mu_yr_clim_df:

        mu_yr_clim = mu_yr_clim_df[prcp_fac]
        nmu = len(mu_yr_clim)
        mb_per_mu = prcp_yr * prcp_fac - mu_yr_clim * temp_yr
        mbts_per_mu = np.atleast_2d(prcp_yr_ts * prcp_fac).repeat(nmu, 0) - \
                      np.atleast_2d(mu_yr_clim).T * \
                      np.atleast_2d(temp_yr_ts).repeat(nmu, 0)
        std_per_mu = mb_per_mu*0 + np.std(mbts_per_mu, axis=1)

        # Diff to reference
        diff = (mb_per_mu - ref_mb).dropna()
        diff_std = (std_per_mu - ref_mb_std).dropna()
        signchange = utils.signchange(diff)

        # If sign changes save them
        # TODO: ideas to do this better:
        #  - apply a smooth (take noise into account)
        #  - take longer stable periods into account
        # these stuffs could be proven better (or not) with cross-val
        pchange = np.where(signchange == 1)[0]
        years = diff.index
        diff = diff.values
        diff_std = diff_std.values
        if len(pchange) > 0:
            t_stars = []
            bias = []
            std_bias = []
            for p in pchange:
                # Check the side with the smallest bias
                ide = p-1 if np.abs(diff[p-1]) < np.abs(diff[p]) else p
                if years[ide] not in t_stars:
                    t_stars.append(years[ide])
                    bias.append(diff[ide])
                    std_bias.append(diff_std[ide])
        else:
            amin = np.argmin(np.abs(diff))
            t_stars = [years[amin]]
            bias = [diff[amin]]
            std_bias = [diff_std[amin]]

        # (prcp_fac, t_stars, bias, std_bias)
        odf.loc[prcp_fac, 'avg_bias'] = np.mean(bias)
        odf.loc[prcp_fac, 'avg_std_bias'] = np.mean(std_bias)
        odf.loc[prcp_fac, 'n_tstar'] = len(std_bias)
        out[prcp_fac] = t_stars, bias, prcp_fac

    # write
    gdir.write_pickle(odf, 'prcp_fac_optim')

    # we take the closest result and see later if it needs cleverer handling
    amin = np.argmin(np.abs(odf.avg_std_bias))  # this gives back an index!
    return out[amin]