Ejemplo n.º 1
0
def test_climatology_interpolate_leapday():
    ts = pd.Series(np.arange(365),
                   index=pd.date_range('2001-01-01', freq='D', periods=365))
    # remove a part of the time series
    clim = anomaly.calc_climatology(ts,
                                    wraparound=True,
                                    respect_leap_years=False,
                                    fill=-1)
    assert clim[60] == -1
    clim = anomaly.calc_climatology(ts,
                                    wraparound=True,
                                    respect_leap_years=True,
                                    fill=-1)
    assert clim[366] == -1
    clim = anomaly.calc_climatology(ts,
                                    wraparound=True,
                                    respect_leap_years=False,
                                    fill=-1,
                                    interpolate_leapday=True)
    assert clim[60] == np.mean((clim[59], clim[61]))
    clim = anomaly.calc_climatology(ts,
                                    wraparound=True,
                                    respect_leap_years=True,
                                    fill=-1,
                                    interpolate_leapday=True)
    assert clim[366] == np.mean((clim[365], clim[1]))
Ejemplo n.º 2
0
def test_climatology_interpolate_leapday():
    ts = pd.Series(np.arange(365), index=pd.date_range(
        '2001-01-01', freq='D', periods=365))
    # remove a part of the time series
    clim = anomaly.calc_climatology(ts, wraparound=True, respect_leap_years=False, fill=-1)
    assert clim[60] == -1
    clim = anomaly.calc_climatology(ts, wraparound=True, respect_leap_years=True, fill=-1)
    assert clim[366] == -1
    clim = anomaly.calc_climatology(ts, wraparound=True, respect_leap_years=False, fill=-1, interpolate_leapday=True)
    assert clim[60] == np.mean((clim[59], clim[61]))
    clim = anomaly.calc_climatology(ts, wraparound=True, respect_leap_years=True, fill=-1, interpolate_leapday=True)
    assert clim[366] == np.mean((clim[365], clim[1]))
Ejemplo n.º 3
0
def test_monthly_climatology_always_12():
    ts = pd.Series(np.sin(np.arange(366) / 366. * 2 * np.pi),
                   index=pd.date_range('2000-01-01', freq='D', periods=366))
    # remove a part of the time series
    ts['2000-02-01':'2000-02-28'] = np.nan
    ts = ts.dropna()
    clim = anomaly.calc_climatology(ts, unit="month")
    assert clim.size == 12

    # this should also be the case if interpolate_leapday is set
    ts = pd.Series(np.sin(np.arange(10)),
                   index=pd.date_range('2000-01-01', freq='D', periods=10))
    clim = anomaly.calc_climatology(ts, unit="month")
    assert clim.size == 12
Ejemplo n.º 4
0
Archivo: app.py Proyecto: TUW-GEO/poets
def calc_anom(df, variable=None):
    """
    Calculates anomaly based on climatology for time series.

    Parameters
    ----------
    df : pandas DataFrame
        Dataframe containing time series.
    variable : str
        Variable to select from DataFrame

    Returns
    -------
    df : pandas DataFrame
        Anomaly of time series.
    """

    climatology = calc_climatology(df)
    if variable is None:
        variable = df.keys()[0]
    anom = calc_anomaly(df[variable], climatology=climatology)

    df[variable] = anom
    columns = []
    for cols in df.columns:
        columns.append(cols + '_anomaly')
    df.columns = columns

    return df
Ejemplo n.º 5
0
def calc_anom(df, variable=None):
    """
    Calculates anomaly based on climatology for time series.

    Parameters
    ----------
    df : pandas DataFrame
        Dataframe containing time series.
    variable : str
        Variable to select from DataFrame

    Returns
    -------
    df : pandas DataFrame
        Anomaly of time series.
    """

    climatology = calc_climatology(df)
    if variable is None:
        variable = df.keys()[0]
    anom = calc_anomaly(df[variable], climatology=climatology)

    df[variable] = anom
    columns = []
    for cols in df.columns:
        columns.append(cols + '_anomaly')
    df.columns = columns

    return df
Ejemplo n.º 6
0
def test_climatology_always_366():
    ts = pd.Series(np.sin(np.arange(366) / 366. * 2 * np.pi),
                   index=pd.date_range('2000-01-01', freq='D', periods=366))
    # remove a part of the time series
    ts['2000-02-01':'2000-02-28'] = np.nan
    ts = ts.dropna()
    clim = anomaly.calc_climatology(ts)
    assert clim.size == 366
Ejemplo n.º 7
0
def test_climatology_always_366():
    ts = pd.Series(np.sin(np.arange(366) / 366. * 2 * np.pi), index=pd.date_range(
        '2000-01-01', freq='D', periods=366))
    # remove a part of the time series
    ts['2000-02-01': '2000-02-28'] = np.nan
    ts = ts.dropna()
    clim = anomaly.calc_climatology(ts)
    assert clim.size == 366
Ejemplo n.º 8
0
 def calc_anom(self, data):
     if self.columns is None:
         ite = data
     else:
         ite = self.columns
     for column in ite:
         clim = calc_climatology(data[column], **self.kwargs)
         data[column] = calc_anomaly(data[column], climatology=clim)
     return data
Ejemplo n.º 9
0
 def calc_anom(self, data):
     if self.columns is None:
         ite = data
     else:
         ite = self.columns
     for column in ite:
         clim = calc_climatology(data[column], **self.kwargs)
         data[column] = calc_anomaly(data[column], climatology=clim)
     return data
Ejemplo n.º 10
0
def test_climatology_closed():
    ts = pd.Series(np.arange(366),
                   index=pd.date_range('2000-01-01', freq='D', periods=366))
    # remove a part of the time series
    ts['2000-02-01':'2000-02-28'] = np.nan
    ts = ts.dropna()
    clim = anomaly.calc_climatology(ts, wraparound=True)
    assert clim.size == 366
    # test that the arange was closed during the second moving average
    assert clim.iloc[365] - 187.90 < 0.01
Ejemplo n.º 11
0
def test_climatology_closed():
    ts = pd.Series(np.arange(366), index=pd.date_range(
        '2000-01-01', freq='D', periods=366))
    # remove a part of the time series
    ts['2000-02-01': '2000-02-28'] = np.nan
    ts = ts.dropna()
    clim = anomaly.calc_climatology(ts, wraparound=True)
    assert clim.size == 366
    # test that the arange was closed during the second moving average
    assert clim.iloc[365] - 187.90 < 0.01
Ejemplo n.º 12
0
def calc_anom(Ser,
              mode='climatological',
              window_size=35,
              return_clim=False,
              return_clim366=False):
    '''
    :param Ser:             pandas.Series; index must be a datetime index
    :param mode:            string; one of:
                                "climatological": calculate anomalies from the mean seasonal cycle
                                "longterm": inter-annual variabilities only (climatological anomalies minus short-term anomalies)
                                "shortterm": residuals from the seasonality (i.e., moving average) of each individual year
    :param window_size:     integer; window size for calculating the climatology and/or seasonality
    :param return_clim:     boolean; If true, the climatology value is returned for each timestep of the input Series
                                     This overrules the "mode" keyword!
    :param return_clim366:  boolean; If true, the actual climatology is returned (366 values)
                                     This overrules both the "mode" and "return_clim" keywords!
    '''

    if mode not in ['climatological', 'longterm', 'shortterm']:
        logging.error('calc_anom: unknown anomaly type')
        return None

    # Calculate the climatology
    if (mode != 'shortterm') | return_clim | return_clim366:
        clim = calc_climatology(Ser,
                                respect_leap_years=True,
                                wraparound=True,
                                moving_avg_clim=window_size,
                                fillna=False)
    else:
        clim = None

    # Return the actual climatology (366 values)
    if return_clim366:
        return clim

    # Calculate either climatological or short-term anomalies
    res = calc_anom_pytesmo(Ser,
                            climatology=clim,
                            window_size=window_size,
                            return_clim=return_clim)

    # Derive long-term anomalies by subtracting short-term anomalies from climatological anomalies
    if (mode == 'longterm') and not return_clim:
        res -= calc_anom_pytesmo(Ser,
                                 climatology=None,
                                 window_size=window_size)

    # Return climatology values for each time step of the input Series
    if return_clim:
        res = res['climatology']

    res.name = Ser.name

    return res
Ejemplo n.º 13
0
    def _adapt(self, data):
        data = super()._adapt(data)
        if self.columns is None:
            ite = data
        else:
            ite = self.columns
        for column in ite:
            clim = calc_climatology(data[column], **self.kwargs)
            data[column] = calc_anomaly(data[column], climatology=clim)

        return data
Ejemplo n.º 14
0
def getEVIanom(lon,lat):

    # load datasetes
    modis = ee.ImageCollection("MODIS/006/MOD13Q1")
    roi = ee.Geometry.Polygon([[[11.51092529296875, 46.626963598343174],
                                     [11.429901123046875, 46.47207397310214],
                                     [11.605682373046875, 46.41529659311316],
                                     [11.734771728515625, 46.442746381846845],
                                     [11.786956787109375, 46.55996197966659]]])

    poi = ee.Geometry.Point([lon, lat]).buffer(250)

    # mask modis
    modis = modis.map(lambda image: image.updateMask(image.select('SummaryQA').lt(2))) \
                 .filterBounds(roi)

    # get time-series
    def getSeries(image):

        out_feature = image.reduceRegion(ee.Reducer.mean(), poi, 250)

        return ee.Feature(None, {'result': out_feature})

    # get the EVI time-series
    evi_series = modis.map(getSeries).getInfo()

    EVI = np.array([x['properties']['result']['EVI'] for x in evi_series['features']], dtype=np.float)

    ge_dates = np.array([datetime.strptime(x['id'], '%Y_%m_%d') for x in evi_series['features']])

    valid = np.where(np.isfinite(EVI))

    # cut out invalid values
    EVI = EVI[valid] / 10000
    ge_dates = ge_dates[valid]

    # insert into pandas series
    EVI = pd.Series(EVI, index=ge_dates)

    # calculate climatology
    EVI_filled = EVI.reindex(index=pd.date_range(start=datetime(year=2000,month=1,day=1),end=datetime(year=2017,month=12,day=31)), copy=True) \
                    .interpolate()
    evi_clim = calc_climatology(EVI_filled, moving_avg_orig=30, moving_avg_clim=0)

    evi_clim_dates = [evi_clim.values[x.dayofyear-1] for x in EVI.index]
    evi_clim_dates = pd.Series(evi_clim_dates, index=EVI.index)
    evi_clim_dates_f = [evi_clim.values[x.dayofyear - 1] for x in EVI_filled.index]
    evi_clim_dates_f = pd.Series(evi_clim_dates_f, index=EVI_filled.index)

    evi_anomalies = evi_clim_dates - EVI

    return (EVI, evi_clim_dates, evi_anomalies, evi_clim_dates_f, evi_clim)
Ejemplo n.º 15
0
def plot_freq_components(dir_out):

    ds = GEOSldas_io('ObsFcstAna',
                     exp='NLv4_M36_US_DA_SMAP_Pcorr_LTST').timeseries

    ts = ds['obs_fcst'][:, 0, 50, 120].to_pandas().dropna()

    clim = calc_climatology(ts)

    anom_lt = calc_anom(ts, mode='longterm')
    anom_st = calc_anom(ts, mode='shortterm')
    clim = calc_anom(ts, return_clim=True)

    anom_lst = anom_lt + anom_st
    anom_lst.name = 'Anomalies (HF + LF)'

    f, axes = plt.subplots(figsize=(18, 6), nrows=3, ncols=1, sharex=True)

    fontsize = 11
    df = pd.concat((ts, clim), axis=1)
    df.columns = ['$T_b$ signal', 'Climatology']
    df.plot(ax=axes[0],
            color=['darkorange', 'blue'],
            linewidth=1.7,
            fontsize=fontsize).legend(loc='upper right', fontsize=fontsize)

    df = pd.DataFrame(anom_lst)
    df.plot(ax=axes[1],
            color='crimson',
            ylim=[-18, 18],
            linewidth=1.7,
            fontsize=fontsize).legend(loc='upper right', fontsize=fontsize)
    axes[1].axhline(color='black', linestyle='--', linewidth=0.8)

    df = pd.concat((anom_st, anom_lt), axis=1)
    df.columns = ['HF signal', 'LF signal']
    df.plot(ax=axes[2],
            color=['goldenrod', 'teal'],
            ylim=[-15, 15],
            linewidth=1.7,
            fontsize=fontsize).legend(loc='upper right', fontsize=fontsize)
    axes[2].axhline(color='black', linestyle='--', linewidth=0.8)

    plt.xlabel('')
    plt.minorticks_off()
    plt.xlim('2015-04', '2021,04')
    plt.xticks(fontsize=fontsize)

    f.savefig(dir_out / f'frequency_components.png',
              dpi=300,
              bbox_inches='tight')
    plt.close()
Ejemplo n.º 16
0
def plot_innov_ts_example():

    lat, lon = 41.70991616028507, -92.39133686043398

    io_smap = LDAS_io('ObsFcstAna', exp='US_M36_SMOS40_DA_cal_scaled')
    # io_smap = LDAS_io('ObsFcstAna', exp='US_M36_SMOS_DA_cal_scaled_yearly')

    idx_lon, idx_lat = io_smap.grid.lonlat2colrow(lon, lat, domain=True)
    print(idx_lon, idx_lat)

    ts = io_smap.timeseries.isel(lat=idx_lat, lon=idx_lon, species=0).to_dataframe()[['obs_fcst', 'obs_obs']].dropna()

    plt.figure(figsize=(21, 8))

    ax = plt.subplot(2, 1, 1)
    sns.lineplot(data=ts, dashes=False, ax=ax)
    plt.title(f'{lat:.2f} N, {lon:.2f} W')
    plt.xlabel('')
    plt.ylabel('Tb')

    # ---- cliamtology ----
    ts['obs_fcst_clim'] = calc_anomaly(ts['obs_fcst'], return_clim=True, climatology=calc_climatology(ts['obs_fcst']))[
        'climatology']
    ts['obs_obs_clim'] = calc_anomaly(ts['obs_obs'], return_clim=True, climatology=calc_climatology(ts['obs_obs']))[
        'climatology']

    ts['obs_fcst_seas'] = ts['obs_fcst'] - calc_anomaly(ts['obs_fcst'])
    ts['obs_obs_seas'] = ts['obs_obs'] - calc_anomaly(ts['obs_obs'])

    ax = plt.subplot(2, 1, 2)
    ts['climatology_scaled'] = ts['obs_obs'] - ts['obs_obs_clim'] + ts['obs_fcst_clim'] - ts['obs_fcst']
    ts['seasonality_scaled'] = ts['obs_obs'] - ts['obs_obs_seas'] + ts['obs_fcst_seas'] - ts['obs_fcst']
    sns.lineplot(data=ts[['climatology_scaled', 'seasonality_scaled']], dashes=False, ax=ax)
    plt.axhline(color='black', linewidth=1, linestyle='--')
    plt.xlabel('')
    plt.ylabel('O-F')

    plt.tight_layout()
    plt.show()
Ejemplo n.º 17
0
def plot_clim_anom(df, clim=None, axes=None, markersize=0.75,
                   mfc='0.3', mec='0.3', clim_color='0.0',
                   clim_linewidth=0.5, clim_linestyle='-',
                   pos_anom_color='#799ADA', neg_anom_color='#FD8086',
                   anom_linewidth=0.2, add_titles=True):
    """
    Takes a pandas DataFrame and calculates the climatology and anomaly
    and plots them in a nice way for each column

    Parameters
    ----------
    df : pandas.DataFrame
    clim : pandas.DataFrame, optional
        if given these climatologies will be used
        if not given then climatologies will be calculated
        this DataFrame must have the same number of columns as df
        and also the column names.
        each climatology must have doy as index.
    axes : list of matplotlib.Axes, optional
           list of axes on which each column should be plotted
           if not given a standard layout is generated
    markersize : float, optional
        size of the markers for the datapoints
    mfc : matplotlib color, optional
        markerfacecolor, color of the marker face
    mec : matplotlib color, optional
        markeredgecolor
    clim_color : matplotlib color, optional
        color of the climatology
    clim_linewidth : float, optional
        linewidth of the climatology
    clim_linestyle : string, optional
        linestyle of the climatology
    pos_anom_color : matplotlib color, optional
        color of the positive anomaly
    neg_anom_color : matplotlib color, optional
        color of the negative anomaly
    anom_linewidth : float, optional
        linewidth of the anomaly lines
    add_titles : boolean, optional
        if set each subplot will have it's column name as title
        Default : True

    Returns
    -------
    Figure : matplotlib.Figure
        if no axes were given
    axes : list of matploblib.Axes
        if no axes were given
    """

    if type(df) == pd.Series:
        df = pd.DataFrame(df)

    nr_columns = len(df.columns)

    # make own axis if necessary
    if axes is None:
        own_axis = True
        gs = gridspec.GridSpec(nr_columns, 1, right=0.8)

        fig = plt.figure(num=None, figsize=(6, 2 * nr_columns),
                         dpi=150, facecolor='w', edgecolor='k')

        last_axis = fig.add_subplot(gs[nr_columns - 1])
        axes = []
        for i, grid in enumerate(gs):
            if i < nr_columns - 1:
                ax = fig.add_subplot(grid, sharex=last_axis)
                axes.append(ax)
                ax.xaxis.set_visible(False)
        axes.append(last_axis)

    else:
        own_axis = False

    for i, column in enumerate(df):
        Ser = df[column]
        ax = axes[i]

        if clim is None:
            clima = anom.calc_climatology(Ser)
        else:
            clima = pd.Series(clim[column])
        anomaly = anom.calc_anomaly(Ser, climatology=clima, return_clim=True)

        anomaly[Ser.name] = Ser
        anomaly = anomaly.dropna()

        pos_anom = anomaly[Ser.name].values > anomaly['climatology'].values
        neg_anom = anomaly[Ser.name].values < anomaly['climatology'].values

        ax.plot(anomaly.index, anomaly[Ser.name].values, 'o',
                markersize=markersize, mfc=mfc, mec=mec)

        ax.plot(anomaly.index, anomaly['climatology'].values,
                linestyle=clim_linestyle,
                color=clim_color,
                linewidth=clim_linewidth)

        ax.fill_between(anomaly.index,
                        anomaly[Ser.name].values,
                        anomaly['climatology'].values, interpolate=True,
                        where=pos_anom, color=pos_anom_color,
                        linewidth=anom_linewidth)
        ax.fill_between(anomaly.index,
                        anomaly[Ser.name].values,
                        anomaly['climatology'].values, interpolate=True,
                        where=neg_anom, color=neg_anom_color,
                        linewidth=anom_linewidth)
        if add_titles:
            ax.set_title(column)

    if own_axis:
        return fig, axes
    else:
        return None, None
Ejemplo n.º 18
0
def compare_data(ismn_data, validation_data, scaling='linreg', anomaly=None):
    """
    Compare data from an ISMN station to the defined validation datasets.

    Parameters
    ----------
    ismn_data: pandas.Dataframe
        Data from the ISMN used as a reference
    validation_data: dict
        Dictionary of pandas.DataFrames, One for each dataset to
        compare against
    scaling: string, optional
        Scaling method to use.
    anomaly: string
        If set then the validation is done for anomalies.
    """
    insitu_label = 'soil moisture'

    if anomaly != None:

        if anomaly == 'climatology':
            ascat_clim = anomaly_calc.calc_climatology(
                ascat_masked[ascat_label])
            insitu_clim = anomaly_calc.calc_climatology(
                ismn_data['soil moisture'])

            ascat_anom = anomaly_calc.calc_anomaly(ascat_masked[ascat_label],
                                                   climatology=ascat_clim)
            ascat_masked[ascat_label] = ascat_anom.values

            insitu_anom = anomaly_calc.calc_anomaly(ISMN_data['insitu'],
                                                    climatology=insitu_clim)
            ISMN_data['insitu'] = insitu_anom.values

        if anomaly == 'average':
            ascat_anom = anomaly_calc.calc_anomaly(ascat_masked[ascat_label])
            ascat_masked[ascat_label] = ascat_anom.values

            insitu_anom = anomaly_calc.calc_anomaly(ISMN_data['insitu'])
            ISMN_data['insitu'] = insitu_anom.values

        ascat_masked = ascat_masked.dropna()
        ISMN_data = ISMN_data.dropna()

    for dname in validation_data:
        vdata = validation_data[dname]
        vdata_label = 'cci_sm'

        matched_data = temp_match.matching(ismn_data, vdata, window=1)

        if scaling != 'noscale' and scaling != 'porosity':

            scaled_data = scale.add_scaled(matched_data,
                                           label_in=vdata_label,
                                           label_scale=insitu_label,
                                           method=scaling)

            scaled_label = vdata_label + '_scaled_' + scaling

            scaled_data = scaled_data[[insitu_label, scaled_label]]

        elif scaling == 'noscale':
            scaled_data = matched_data[[insitu_label, vdata_label]]
            scaled_label = vdata_label

    # scaled_data.rename(columns={'insitu': ISMN_ts_name}, inplace=True)

    labels, values = scaled_data.to_dygraph_format()

    ascat_insitu = {'labels': labels, 'data': values}

    x, y = scaled_data[insitu_label].values, scaled_data[scaled_label].values

    kendall, p_kendall = sc_stats.kendalltau(x.tolist(), y.tolist())
    spearman, p_spearman = sc_stats.spearmanr(x, y)
    pearson, p_pearson = sc_stats.pearsonr(x, y)
    rmsd = metrics.rmsd(x, y)
    bias = metrics.bias(y, x)
    mse, mse_corr, mse_bias, mse_var = metrics.mse(x, y)
    statistics = {
        'kendall': {
            'v': '%.2f' % kendall,
            'p': '%.4f' % p_kendall
        },
        'spearman': {
            'v': '%.2f' % spearman,
            'p': '%.4f' % p_spearman
        },
        'pearson': {
            'v': '%.2f' % pearson,
            'p': '%.4f' % p_pearson
        },
        'bias': '%.4f' % bias,
        'rmsd': {
            'rmsd': '%.4f' % np.sqrt(mse),
            'rmsd_corr': '%.4f' % np.sqrt(mse_corr),
            'rmsd_bias': '%.4f' % np.sqrt(mse_bias),
            'rmsd_var': '%.4f' % np.sqrt(mse_var)
        },
        'mse': {
            'mse': '%.4f' % mse,
            'mse_corr': '%.4f' % mse_corr,
            'mse_bias': '%.4f' % mse_bias,
            'mse_var': '%.4f' % mse_var
        }
    }

    scaling_options = {
        'noscale': 'No scaling',
        'porosity': 'Scale using porosity',
        'linreg': 'Linear Regression',
        'mean_std': 'Mean - standard deviation',
        'min_max': 'Minimum,maximum',
        'lin_cdf_match': 'Piecewise <br> linear CDF matching',
        'cdf_match': 'CDF matching'
    }

    settings = {
        'scaling': scaling_options[scaling],
        # 'snow_depth': mask['snow_depth'],
        # 'surface_temp': mask['st_l1'],
        # 'air_temp': mask['air_temp']
    }

    era_data = {'labels': [], 'data': []}
    output_data = {
        'validation_data': ascat_insitu,
        'masking_data': era_data,
        'statistics': statistics,
        'settings': settings
    }

    return output_data, 1
Ejemplo n.º 19
0
                           marker='o',
                           color='#00bfff',
                           label='SSM')
    ts_ascat_sm['swi_t10'].plot(ax=ax, lw=2, label='SWI T=10')
    ts_ascat_sm['swi_t50'].plot(ax=ax, lw=2, label='SWI T=50')
    plt.legend()

    # Calculate anomaly based on moving +- 17 day window
    anomaly_ascat = anomaly.calc_anomaly(ts_ascat['sm'], window_size=35)
    fig2, ax = plt.subplots(1, 1, figsize=(15, 5))
    anomaly_ascat.plot(ax=ax, lw=2, label='ASCAT SM Anomaly')
    plt.legend()

    # Calculate climatology
    ts_ascat_clim = ts_ascat.dropna()
    climatology_ascat = anomaly.calc_climatology(ts_ascat_clim['sm'])
    fig3, ax = plt.subplots(1, 1, figsize=(15, 5))
    climatology_ascat.plot(ax=ax, lw=2, label='ASCAT SM Climatology')
    plt.legend()

    # Calculate anomaly based on climatology
    ts_ascat_clim = ts_ascat.dropna()
    anomaly_clim_ascat = anomaly.calc_anomaly(ts_ascat_clim['sm'],
                                              climatology=climatology_ascat)
    fig4, ax = plt.subplots(1, 1, figsize=(15, 5))
    anomaly_clim_ascat.plot(ax=ax,
                            lw=2,
                            label='ASCAT SM Anomaly vs Climatology')
    plt.legend()

    print('ciao')
Ejemplo n.º 20
0
def ismn_validation_run(bsize=500,
                        name='500m',
                        fvect1=None,
                        fvect2=None,
                        fvect1desc=None,
                        fvect2desc=None):
    s1path = 117

    #bsize=250

    basepath = '//projectdata.eurac.edu/projects/ESA_TIGER/S1_SMC_DEV/Processing/S1ALPS/ISMN/S1AB_' + name + '_reprocess_lt_05/'

    # outpath
    outpath = basepath + 'w_GLDAS_asc_desc/'

    # Calculate prediction standar deviations
    calcstd = False

    # use descending orbits
    desc = False

    # calculate anomalies?
    calc_anomalies = False

    # initialise available ISMN data
    ismn = ismn_interface.ISMN_Interface(
        'T:/ECOPOTENTIAL/reference_data/ISMN/')

    # get list of networks
    networks = ismn.list_networks()

    # initialise S1 SM retrieval
    # mlmodel = pickle.load(open('/mnt/SAT/Workspaces/GrF/Processing/S1ALPS/ASCAT/gee/mlmodel0.p', 'rb'))
    mlmodel_avg = "//projectdata.eurac.edu/projects/ESA_TIGER/S1_SMC_DEV/Processing/S1ALPS/ISMN/S1AB_1km_reprocess_lt_05/no_GLDAS_RFmlmodelNoneSVR_2step.p"
    mlmodel = basepath + "w_GLDAS_RFmlmodelNoneSVR_2step.p"
    mlmodel_desc = "//projectdata.eurac.edu/projects/ESA_TIGER/S1_SMC_DEV/Processing/S1ALPS/ISMN/S1AB_50m_reprocess_lt_05_descending/w_GLDAS_RFmlmodelNoneSVR_2step.p"

    # initialse text report
    txtrep = open(outpath + '2_report.txt', 'w')
    txtrep.write(
        'Accuracy report for Soil Moisture validation based on ISMN stations\n\n'
    )
    txtrep.write('Model used: ' + mlmodel + '\n')
    txtrep.write(
        '------------------------------------------------------------------------\n\n'
    )
    txtrep.write('Name, R, RMSE\n')

    xyplot = pd.DataFrame()
    cntr = 1

    #used_stations = np.load('X:/Workspaces/GrF/Processing/S1ALPS/ISMN/gee_global_all_no_deep/ValidStaions.npy')
    used_stations = pickle.load(open(basepath + "testset_meta.p", 'rb'))
    #invalid_col = pickle.load(open('/mnt/SAT/Workspaces/GrF/Processing/S1ALPS/ISMN/gee_global005_highdbtollerance/invalid_col.p', 'rb'))
    #used_stations = [invalid_col['ntwkname'][i] + ', ' + invalid_col['stname'][i] for i in range(len(invalid_col['ntwkname']))]

    #for ntwk in networks:
    #for vstation in used_stations:
    s1_ts_list = list()
    station_ts_list = list()
    station_name_list = list()
    gldas_ts_list = list()
    s1_failed_list = list()
    s1_ub_list = list()
    for st_i in range(len(used_stations[0])):
        #for st_i in [0]:

        #ntwk, st_name = [x.strip() for x in vstation.split(',')]
        ntwk = used_stations[1][st_i]
        st_name = used_stations[0][st_i]
        # if st_name != 'ROSASCYN':# and st_name != 'Salem-10-W':
        #     continue

        # get list of available stations
        available_stations = ismn.list_stations(ntwk)

        # iterate through all available ISMN stations
        #for st_name in available_stations:
        try:

            station = ismn.get_station(st_name, ntwk)
            station_vars = station.get_variables()
            # if st_name != '2.10':
            #     continue

            # if (st_name != 'Boulder-14-W'):
            #    continue
            #if st_name not in ['ANTIMONYFL', 'CALIVALLEY', 'Bethlehem']:
            # if st_name not in ['CALIVALLEY']:
            #     continue

            if 'soil moisture' not in station_vars:
                continue

            station_depths = station.get_depths('soil moisture')

            # if 0.0 in station_depths[0]:
            #     sm_sensors = station.get_sensors('soil moisture', depth_from=0, depth_to=0.24)
            #     station_ts = station.read_variable('soil moisture', depth_from=0, depth_to=0.24, sensor=sm_sensors[0])
            # else:
            #     continue

            if 0.0 in station_depths[0]:
                did = np.where(station_depths[0] == 0.0)
                dto = station_depths[1][did]
                sm_sensors = station.get_sensors('soil moisture',
                                                 depth_from=0,
                                                 depth_to=dto[0])
                print(sm_sensors[0])
                station_ts = station.read_variable('soil moisture',
                                                   depth_from=0,
                                                   depth_to=dto[0],
                                                   sensor=sm_sensors[0])
            elif 0.05 in station_depths[0]:
                sm_sensors = station.get_sensors('soil moisture',
                                                 depth_from=0.05,
                                                 depth_to=0.05)
                station_ts = station.read_variable('soil moisture',
                                                   depth_from=0.05,
                                                   depth_to=0.05,
                                                   sensor=sm_sensors[0])
            else:
                continue

            print(st_name)

            plotpath = outpath + st_name + '.png'

            # if os.path.exists(plotpath):
            #     continue

            # get station ts
            station_ts = station_ts.data['soil moisture']

            # get S1 time series
            s1_ts, s1_ts_std, outliers, s1_failed = extract_time_series_gee(
                mlmodel,
                mlmodel_avg,
                '/mnt/SAT4/DATA/S1_EODC/',
                outpath,
                station.latitude,
                station.longitude,
                name=st_name,
                footprint=bsize,
                calcstd=calcstd,
                desc=desc,
                target=station_ts,
                feature_vect1=fvect1,
                feature_vect2=fvect2)  #,
            #s1path=s1path)

            s1_ts2, s1_ts_std2, outliers2, s1_failed2 = extract_time_series_gee(
                mlmodel_desc,
                mlmodel_avg,
                '/mnt/SAT4/DATA/S1_EODC/',
                outpath,
                station.latitude,
                station.longitude,
                name=st_name,
                footprint=bsize,
                calcstd=calcstd,
                desc=True,
                target=station_ts,
                feature_vect1=fvect1desc,
                feature_vect2=fvect2desc)  # ,

            if (s1_ts is not None) and (s1_ts2 is not None):
                # correct the mean offset between time-series from ascending and descending orbits
                meandiff = s1_ts.mean() - s1_ts2.mean()
                s1_ts2 = s1_ts2 + meandiff
                meandiff_failed = s1_failed.median() - s1_failed2.median()
                s1_failed2 = s1_failed2 + meandiff_failed
                s1_ts = pd.concat([s1_ts, s1_ts2])
                s1_failed = pd.concat([s1_failed, s1_failed2])
            elif (s1_ts is None) and (s1_ts2 is not None):
                s1_ts = s1_ts2
                s1_failed = s1_failed2

            s1_ts.sort_index(inplace=True)
            s1_failed.sort_index(inplace=True)

            if s1_ts is None:
                continue

            if len(s1_ts) < 5:
                continue

            #evi_ts = extr_MODIS_MOD13Q1_ts_GEE(station.longitude, station.latitude, bufferSize=150)
            #evi_ts = pd.Series(evi_ts[1]['EVI'], index=evi_ts[0])

            gldas_ts = extr_GLDAS_ts_GEE(
                station.longitude,
                station.latitude,
                bufferSize=150,
                yearlist=[2014, 2015, 2016, 2017, 2018, 2019])
            gldas_ts = gldas_ts / 100.

            start = np.array([s1_ts.index[0], station_ts.index[0]]).max()
            end = np.array([s1_ts.index[-1], station_ts.index[-1]]).min()
            if start > end:
                continue
            station_ts = station_ts[start:end]
            s1_ts = s1_ts[start:end]
            s1_failed = s1_failed[start:end]
            #outliers = outliers[start:end]
            #evi_ts = evi_ts[start:end]
            gldas_ts = gldas_ts[start:end]
            if calcstd == True:
                s1_ts_std = s1_ts_std[start:end]
            if len(s1_ts) < 1:
                continue
            #station_ts = station_ts.iloc[np.where(station_ts > 0.1)]

            #s1_ts = s1_ts[np.where(error_ts == error_ts.min())[0]]

            s1_ts_res = s1_ts.resample('D').mean().rename('s1')
            station_ts_res = station_ts.resample('D').mean().rename('ismn')
            gldas_ts_res = gldas_ts.resample('D').mean().rename('gldas')

            if calc_anomalies == True:
                from pytesmo.time_series import anomaly as pyan
                s1_clim = pyan.calc_climatology(s1_ts_res.interpolate())
                station_clim = pyan.calc_climatology(
                    station_ts_res.interpolate())

                s1_ts = pyan.calc_anomaly(s1_ts, climatology=s1_clim)
                s1_ts_res = pyan.calc_anomaly(s1_ts_res, climatology=s1_clim)
                station_ts = pyan.calc_anomaly(station_ts,
                                               climatology=station_clim)
                station_ts_res = pyan.calc_anomaly(station_ts_res,
                                                   climatology=station_clim)

            # calculate error metrics
            ts_bias = s1_ts_res.subtract(station_ts_res).mean()

            # cdf matching
            tobemerged = [
                s1_ts_res.dropna(),
                gldas_ts_res.dropna(),
                station_ts_res.dropna()
            ]
            s1_and_station = pd.concat(tobemerged, axis=1, join='inner')
            statmask = (s1_and_station['ismn'] > 0) & (
                s1_and_station['ismn'] < 1) & (s1_and_station['s1'] >
                                               0) & (s1_and_station['s1'] < 1)
            p2 = s1_and_station['ismn'][statmask].std(
            ) / s1_and_station['s1'][statmask].std()
            p1 = s1_and_station['ismn'][statmask].mean() - (
                p2 * s1_and_station['s1'][statmask].mean())
            s1_ts_ub = p1 + (p2 * s1_ts)
            s1_and_station['s1ub'] = p1 + (p2 * s1_and_station['s1'])
            ts_bias = s1_and_station['s1ub'].subtract(
                s1_and_station['ismn']).median()
            s1_failed = p1 + (p2 * s1_failed)

            xytmp = pd.concat(
                {
                    'y': s1_and_station['s1ub'],
                    'x': s1_and_station['ismn']
                },
                join='inner',
                axis=1)
            if cntr == 1:
                xyplot = xytmp
            else:
                xyplot = pd.concat([xyplot, xytmp], axis=0)

            cntr = cntr + 1

            ts_cor = s1_and_station['s1ub'].corr(s1_and_station['ismn'])
            ts_rmse = np.sqrt(
                np.nanmean(
                    np.square(s1_and_station['s1ub'].subtract(
                        s1_and_station['ismn']))))
            #ts_ubrmse = np.sqrt(np.sum(np.square(s1_ts_res.subtract(s1_ts_res.mean()).subtract(station_ts_res.subtract(station_ts_res.mean())))))
            ts_ubrmse = np.sqrt(
                np.sum(
                    np.square((s1_and_station['s1ub'] -
                               s1_and_station['s1ub'].mean()) -
                              (s1_and_station['ismn'] -
                               s1_and_station['ismn'].mean()))) /
                len(s1_and_station['s1ub']))
            print('R: ' + str(ts_cor))
            print('RMSE: ' + str(ts_rmse))
            print('Bias: ' + str(ts_bias))
            txtrep.write(st_name + ', ' + str(ts_cor) + ', ' + str(ts_rmse) +
                         '\n')

            s1_ts_list.append(s1_ts)
            station_ts_list.append(station_ts)
            station_name_list.append(st_name)
            gldas_ts_list.append(gldas_ts)
            s1_failed_list.append(s1_failed)
            s1_ub_list.append(s1_ts_ub)
            # plot
            # plt.figure(figsize=(18, 6))
            fig, ax1 = plt.subplots(figsize=(7.16, 1.4), dpi=300)
            line1, = ax1.plot(s1_ts_ub.index,
                              s1_ts_ub,
                              color='b',
                              linestyle='',
                              marker='+',
                              label='Sentinel-1',
                              linewidth=0.2)
            line8, = ax1.plot(s1_failed.index,
                              s1_failed,
                              color='r',
                              linestyle='',
                              marker='+',
                              label='fail',
                              linewidth=0.2)
            line2, = ax1.plot(station_ts.index,
                              station_ts,
                              label='In-Situ',
                              linewidth=0.4)
            if np.any(outliers) and outliers is not None:
                line6, = ax1.plot(s1_ts.index[outliers],
                                  s1_ts.iloc[outliers],
                                  color='r',
                                  linestyle='',
                                  marker='o')
            #line3, = ax1.plot(outliers.index, outliers, color='r', linestyle='', marker='*', label='Outliers')
            if calcstd == True:
                line4, = ax1.plot(s1_ts.index,
                                  s1_ts - np.sqrt(s1_ts_std),
                                  color='k',
                                  linestyle='--',
                                  linewidth=0.2)
                line5, = ax1.plot(s1_ts.index,
                                  s1_ts + np.sqrt(s1_ts_std),
                                  color='k',
                                  linestyle='--',
                                  linewidth=0.2)

            #ax3 = ax1.twinx()
            line6, = ax1.plot(gldas_ts.index,
                              gldas_ts,
                              color='g',
                              linestyle='--',
                              label='GLDAS',
                              linewidth=0.2)
            #line3, = ax3.plot(evi_ts.index, evi_ts, linewidth=0.4, color='r', linestyle='--', label='MOD13Q1:EVI')
            # ax3.axes.tick_params(axis='y', direction='in', labelcolor='r', right='off', labelright='off')

            ax1.set_ylabel('Soil Moisture [m3m-3]', size=8)
            smc_max = np.max([s1_ts.max(), station_ts.max()])
            if smc_max <= 0.5:
                smc_max = 0.5
            ax1.set_ylim((0, smc_max))
            ax1.text(
                0.85,
                0.4,
                'R=' + '{:03.2f}'.format(ts_cor) +
                #'\nRMSE=' + '{:03.2f}'.format(ts_rmse) +
                '\nBias=' + '{:03.2f}'.format(ts_bias) + '\nRMSE=' +
                '{:03.2f}'.format(ts_rmse),
                transform=ax1.transAxes,
                fontsize=8)
            # ax2.set_ylabel('In-Situ [m3/m3]')
            #ax3.set_ylabel('EVI')

            #fig.tight_layout()
            #plt.legend(handles=[line1, line2], loc='upper left', fontsize=8)#, line3, line6])
            plt.title(st_name, fontsize=8)
            #plt.show()
            plt.tight_layout()
            plt.savefig(plotpath, dpi=300)
            plt.close()
        except:
            print('No data for: ' + st_name)

    pickle.dump(
        (s1_ts_list, s1_ub_list, s1_failed, station_ts_list, gldas_ts_list,
         station_name_list),
        open(
            'C:/Users/FGreifeneder/OneDrive - Scientific Network South Tyrol/1_THESIS/pub3/images_submission2/w_GLDAS_validation_tss_'
            + name + '.p', 'wb'))
    scatter_valid = np.where(((xyplot['x'] > 0) & (xyplot['x'] < 1))
                             & ((xyplot['y'] > 0) & (xyplot['y'] < 1)))
    xyplot = xyplot.iloc[scatter_valid]
    urmse_scatter = np.sqrt(
        np.sum(
            np.square((xyplot['y'] - xyplot['y'].mean()) -
                      (xyplot['x'] - xyplot['x'].mean()))) / len(xyplot['y']))
    rmse_scatter = np.sqrt(
        np.nanmean(np.square(xyplot['x'].subtract(xyplot['y']))))
    r_scatter = xyplot['x'].corr(xyplot['y'])
    #plt.figure(figsize=(3.5, 3), dpi=600)
    xyplot.plot.scatter(x='x',
                        y='y',
                        color='k',
                        xlim=(0, 1),
                        ylim=(0, 1),
                        figsize=(3.5, 3),
                        s=1,
                        marker='*')
    plt.xlim(0, 1)
    plt.ylim(0, 1)
    plt.xlabel("$SMC_{Tot}$ [m$^3$m$^{-3}$]", size=8)
    plt.ylabel("$SMC^*_{Tot}$ [m$^3$m$^{-3}$]", size=8)
    plt.plot([0, 1], [0, 1], 'k--', linewidth=0.8)
    plt.text(0.1,
             0.5,
             'R=' + '{:03.2f}'.format(r_scatter) + '\nRMSE=' +
             '{:03.2f}'.format(rmse_scatter),
             fontsize=8)  # +
    #'\nRMSE=' + '{:03.2f}'.format(rmse_scatter), fontsize=8)
    plt.tick_params(labelsize=8)
    plt.title('True vs. estimated SMC', size=8)
    plt.axes().set_aspect('equal', 'box')
    plt.tight_layout()
    plt.savefig(outpath + '1_scatterplot.png', dpi=600)
    plt.close()

    txtrep.write(
        '------------------------------------------------------------------------\n\n'
    )
    txtrep.write('Overall performance:\n')
    txtrep.write('R = ' + str(xyplot['x'].corr(xyplot['y'])) + '\n')
    txtrep.write(
        'RMSE = ' +
        str(np.sqrt(np.nanmean(np.square(xyplot['x'].subtract(xyplot['y']))))))
    txtrep.write('ubRMSE = ' + str(
        np.sqrt(
            np.sum(
                np.square((xyplot['y'] - xyplot['y'].mean()) -
                          (xyplot['x'] - xyplot['x'].mean()))) /
            len(xyplot['y']))))
    txtrep.close()
Ejemplo n.º 21
0
sm_time = cci['time']
#sm_time = np.array([datetime.datetime.fromtimestamp(i*24*60*60) for i in sm_time])
timediff = datetime.datetime(
    year=1979, month=1, day=1, hour=0, minute=0,
    second=0) - datetime.datetime.fromtimestamp(0)
sm_time = np.array([
    datetime.datetime.fromtimestamp(i * 24 * 60 * 60) + timediff
    for i in sm_time
])
sm = np.nanmean(sm, axis=(1, 2))

sm_pd = pd.Series(sm, index=sm_time)
sm_pd = sm_pd.dropna()
sm_df = pd.DataFrame({'Soil Moisture': sm_pd.values}, index=sm_pd.index)

sm_climatology = calc_climatology(sm_pd)
sm_climatology = pd.DataFrame({'Soil Moisture': sm_climatology.values},
                              index=sm_climatology.index)

fig, axs = plt.subplots(figsize=(25, 10))

plot_clim_anom(sm_df,
               clim=sm_climatology,
               axes=[axs],
               clim_color='r',
               clim_linewidth='0.9')
#sm_anomalies_monthly.plot(ax=axs, linestyle='-', linewidth=0.5)
plt.savefig('/mnt/SAT/Workspaces/GrF/model_kassel_sm_1980_2015.png')
plt.close()
cci.close()
Ejemplo n.º 22
0
def plot_clim_anom(df,
                   clim=None,
                   axes=None,
                   markersize=0.75,
                   mfc='0.3',
                   mec='0.3',
                   clim_color='0.0',
                   clim_linewidth=0.5,
                   clim_linestyle='-',
                   pos_anom_color='#799ADA',
                   neg_anom_color='#FD8086',
                   anom_linewidth=0.2,
                   add_titles=True):
    """
    Takes a pandas DataFrame and calculates the climatology and anomaly
    and plots them in a nice way for each column

    Parameters
    ----------
    df : pandas.DataFrame
    clim : pandas.DataFrame, optional
        if given these climatologies will be used
        if not given then climatologies will be calculated
        this DataFrame must have the same number of columns as df
        and also the column names.
        each climatology must have doy as index.
    axes : list of matplotlib.Axes, optional
           list of axes on which each column should be plotted
           if not given a standard layout is generated
    markersize : float, optional
        size of the markers for the datapoints
    mfc : matplotlib color, optional
        markerfacecolor, color of the marker face
    mec : matplotlib color, optional
        markeredgecolor
    clim_color : matplotlib color, optional
        color of the climatology
    clim_linewidth : float, optional
        linewidth of the climatology
    clim_linestyle : string, optional
        linestyle of the climatology
    pos_anom_color : matplotlib color, optional
        color of the positive anomaly
    neg_anom_color : matplotlib color, optional
        color of the negative anomaly
    anom_linewidth : float, optional
        linewidth of the anomaly lines
    add_titles : boolean, optional
        if set each subplot will have it's column name as title
        Default : True

    Returns
    -------
    Figure : matplotlib.Figure
        if no axes were given
    axes : list of matploblib.Axes
        if no axes were given
    """

    if type(df) == pd.Series:
        df = pd.DataFrame(df)

    nr_columns = len(df.columns)

    # make own axis if necessary
    if axes is None:
        own_axis = True
        gs = gridspec.GridSpec(nr_columns, 1, right=0.8)

        fig = plt.figure(num=None,
                         figsize=(6, 2 * nr_columns),
                         dpi=150,
                         facecolor='w',
                         edgecolor='k')

        last_axis = fig.add_subplot(gs[nr_columns - 1])
        axes = []
        for i, grid in enumerate(gs):
            if i < nr_columns - 1:
                ax = fig.add_subplot(grid, sharex=last_axis)
                axes.append(ax)
                ax.xaxis.set_visible(False)
        axes.append(last_axis)

    else:
        own_axis = False

    for i, column in enumerate(df):
        Ser = df[column]
        ax = axes[i]

        if clim is None:
            clima = anom.calc_climatology(Ser)
        else:
            clima = pd.Series(clim[column])
        anomaly = anom.calc_anomaly(Ser, climatology=clima, return_clim=True)

        anomaly[Ser.name] = Ser
        anomaly = anomaly.dropna()

        pos_anom = anomaly[Ser.name].values > anomaly['climatology'].values
        neg_anom = anomaly[Ser.name].values < anomaly['climatology'].values

        ax.plot(anomaly.index,
                anomaly[Ser.name].values,
                'o',
                markersize=markersize,
                mfc=mfc,
                mec=mec)

        ax.plot(anomaly.index,
                anomaly['climatology'].values,
                linestyle=clim_linestyle,
                color=clim_color,
                linewidth=clim_linewidth)

        ax.fill_between(anomaly.index,
                        anomaly[Ser.name].values,
                        anomaly['climatology'].values,
                        interpolate=True,
                        where=pos_anom,
                        color=pos_anom_color,
                        linewidth=anom_linewidth)
        ax.fill_between(anomaly.index,
                        anomaly[Ser.name].values,
                        anomaly['climatology'].values,
                        interpolate=True,
                        where=neg_anom,
                        color=neg_anom_color,
                        linewidth=anom_linewidth)
        if add_titles:
            ax.set_title(column)

    if own_axis:
        return fig, axes
    else:
        return None, None
import matplotlib.pyplot as plt
import os

if __name__ == '__main__':
    cur_path = os.path.abspath(os.path.curdir)

    input_dataidx_file = os.path.join(cur_path, 'data/ssmi/0673')

    gpi = 720360

    dat_obj = datasets.DatasetTs(input_dataidx_file)

    print dat_obj.dat_data.dtype
    print type(dat_obj.dat_data), dat_obj.dat_data.shape

    gpi_data = dat_obj.read_ts(gpi)
    print gpi_data.dtype, gpi_data.shape
    Ser = pd.Series(gpi_data['sm'], index=gpi_data['jd'])
    # Adjust the parameters
    climatology = anomaly.calc_climatology(Ser)
    print climatology
    climatology.plot()
    plt.show()

    anom = anomaly.calc_anomaly(Ser, climatology=climatology)

    anom.plot()
    plt.show()
    print anom
Ejemplo n.º 24
0
#bcksct_min = -14.8
#bcksct_max = -8.12
bcksct_rng = bcksct_max - bcksct_min

s1pd_scaled = (s1pd - bcksct_min) / bcksct_rng
s1pd_scaled = (s1pd_scaled * 35.) + 5.
# s1pd_scaled = (s1pd - bcksct_min) / bcksct_rng
# s1pd_scaled = (s1pd_scaled * 15.) + 3.
s1pd_scaled = s1pd_scaled.resample('D').mean()
s1pd_scaled.interpolate(inplace=True)

# anomalies
#bcksct_mean = s1pd_scaled.mean()
#s1pd_anom = (s1pd_scaled / bcksct_mean) - 1
climatology = anomaly.calc_climatology(s1pd_scaled,
                                       moving_avg_orig=5,
                                       moving_avg_clim=30)
s1pd_anom = anomaly.calc_anomaly(s1pd_scaled, climatology=climatology)

plt.figure(figsize=(6.3, 3.7))
s1pd_scaled.plot()
plt.xlabel('Date', fontsize=10)
plt.ylabel('SMC [m3/m-3]')
plt.ylim((0, 50))
plt.show()
plt.savefig('/mnt/SAT/Workspaces/GrF/02_Documents/ISRSE2017/s1ts.png', dpi=300)
plt.close()

plt.figure(figsize=(6.3, 3.7))
s1pd_anom.plot()
timex = pd.date_range('30/9/2014', '30/4/2017', freq='D')
Ejemplo n.º 25
0
            if start > end:
                continue
            station_ts = station_ts[start:end]
            s1_ts = s1_ts[start:end]
            if calcstd == True:
                s1_ts_std = s1_ts_std[start:end]
            if len(s1_ts) < 1:
                continue

            s1_ts_res = s1_ts.resample('D').mean()
            station_ts_res = station_ts.resample('D').mean()

            if calc_anomalies == True:
                from pytesmo.time_series import anomaly as pyan

                s1_clim = pyan.calc_climatology(s1_ts_res.interpolate())
                station_clim = pyan.calc_climatology(
                    station_ts_res.interpolate())

                s1_ts = pyan.calc_anomaly(s1_ts, climatology=s1_clim)
                s1_ts_res = pyan.calc_anomaly(s1_ts_res, climatology=s1_clim)
                station_ts = pyan.calc_anomaly(station_ts,
                                               climatology=station_clim)
                station_ts_res = pyan.calc_anomaly(station_ts_res,
                                                   climatology=station_clim)

            # calculate error metrics
            ts_bias = s1_ts_res.subtract(station_ts_res).mean()

            tobemerged = [s1_ts_res.dropna(), station_ts_res.dropna()]
            s1_and_station = pd.concat(tobemerged, axis=1, join='inner')
Ejemplo n.º 26
0
# <codecell>

# Read data for location in northern Italy
ascat_ts = ascat_SSM_reader.read(11, 45)
#plot soil moisture
ascat_ts.data['sm'].plot(title='SSM data')
plt.show()

# <codecell>

#calculate anomaly based on moving +- 17 day window
anom = ts_anomaly.calc_anomaly(ascat_ts.data['sm'], window_size=35)
anom.plot(title='Anomaly (35-day window)')
plt.show()

# <codecell>

#calculate climatology
climatology = ts_anomaly.calc_climatology(ascat_ts.data['sm'])
climatology.plot(title='Climatology')
plt.show()

# <codecell>

#calculate anomaly based on climatology
anomaly_clim = ts_anomaly.calc_anomaly(ascat_ts.data['sm'], climatology=climatology)
anomaly_clim.plot(title='Anomaly (climatology)')
plt.show()

# <codecell>
Ejemplo n.º 27
0
def mazia_vaildation_run(bsize=500, name='500m', fvect1=None, fvect2=None):

    # outpath
    outpath = '//projectdata.eurac.edu/projects/ESA_TIGER/S1_SMC_DEV/Processing/S1ALPS/ISMN/S1AB_' + name + '_reprocess_lt_05/w_GLDAS_station_validation/'

    # Calculate prediction standar deviations
    calcstd = False

    # use descending orbits
    desc = False

    calc_anomalies = False

    # initialise S1 SM retrieval
    # mlmodel = pickle.load(open('/mnt/SAT/Workspaces/GrF/Processing/S1ALPS/ASCAT/gee/mlmodel0.p', 'rb'))
    mlmodel = "//projectdata.eurac.edu/projects/ESA_TIGER/S1_SMC_DEV/Processing/S1ALPS/ISMN/S1AB_" + name + "_reprocess_lt_05/w_GLDAS_RFmlmodelNoneSVR_2step.p"

    # initialse text report
    txtrep = open(outpath + '2_Mazia_report.txt', 'w')
    txtrep.write(
        'Accuracy report for Soil Moisture validation based on ISMN stations\n\n'
    )
    txtrep.write('Model used: ' + mlmodel + '\n')
    txtrep.write(
        '------------------------------------------------------------------------\n\n'
    )
    txtrep.write('Name, R, RMSE\n')

    xyplot = pd.DataFrame()
    cntr = 1

    # define mazia station locations
    m_stations = {
        'I1': [10.57978, 46.68706],
        'I3': [10.58359, 46.68197],
        'P1': [10.58295, 46.68586],
        'P2': [10.58525, 46.68433],
        'P3': [10.58562, 46.68511]
    }

    m_station_paths = '//projectdata.eurac.edu/projects/ESA_TIGER/S1_SMC_DEV/01_Data/InSitu/MaziaValley_SWC_2015_16/'

    s1_ts_list = list()
    station_ts_list = list()
    station_name_list = list()
    gldas_ts_list = list()

    for vstation in m_stations:

        st_name = vstation
        st_coordinates = m_stations[vstation]

        try:

            # get in situ data
            full_path2015 = m_station_paths + st_name + '_YEAR_2015.csv'

            insitu2015 = pd.read_csv(full_path2015,
                                     header=0,
                                     skiprows=[0, 2, 3],
                                     index_col=0,
                                     parse_dates=True,
                                     sep=',')

            full_path2016 = m_station_paths + st_name + '_YEAR_2016.csv'

            insitu2016 = pd.read_csv(full_path2016,
                                     header=0,
                                     skiprows=[0, 2, 3],
                                     index_col=0,
                                     parse_dates=True,
                                     sep=',')

            insitu = insitu2015.append(insitu2016)

            # get station ts
            station_ts = pd.Series(
                insitu[['SWC_02_A_Avg', 'SWC_02_B_Avg',
                        'SWC_02_C_Avg']].mean(axis=1))
            plotpath = outpath + st_name + '.png'

            s1_ts, s1_ts_std, outliers = extract_time_series_gee(
                mlmodel,
                mlmodel,
                '/mnt/SAT4/DATA/S1_EODC/',
                outpath,
                st_coordinates[1],
                st_coordinates[0],
                name=st_name,
                footprint=bsize,
                calcstd=calcstd,
                desc=desc,
                target=station_ts,
                feature_vect1=fvect1,
                feature_vect2=fvect2)  # ,

            if s1_ts is None:
                continue

            if len(s1_ts) < 5:
                continue

            gldas_ts = extr_GLDAS_ts_GEE(st_coordinates[1],
                                         st_coordinates[0],
                                         bufferSize=150,
                                         yearlist=[2015, 2016])
            gldas_ts = gldas_ts / 100.

            start = np.array([s1_ts.index[0], station_ts.index[0]]).max()
            end = np.array([s1_ts.index[-1], station_ts.index[-1]]).min()
            if start > end:
                continue
            station_ts = station_ts[start:end]
            s1_ts = s1_ts[start:end]
            gldas_ts = gldas_ts[start:end]
            if calcstd == True:
                s1_ts_std = s1_ts_std[start:end]
            if len(s1_ts) < 1:
                continue

            s1_ts_res = s1_ts.resample('D').mean()
            station_ts_res = station_ts.resample('D').mean()

            if calc_anomalies == True:
                from pytesmo.time_series import anomaly as pyan

                s1_clim = pyan.calc_climatology(s1_ts_res.interpolate())
                station_clim = pyan.calc_climatology(
                    station_ts_res.interpolate())

                s1_ts = pyan.calc_anomaly(s1_ts, climatology=s1_clim)
                s1_ts_res = pyan.calc_anomaly(s1_ts_res, climatology=s1_clim)
                station_ts = pyan.calc_anomaly(station_ts,
                                               climatology=station_clim)
                station_ts_res = pyan.calc_anomaly(station_ts_res,
                                                   climatology=station_clim)

            # calculate error metrics
            ts_bias = s1_ts_res.subtract(station_ts_res).mean()

            tobemerged = [s1_ts_res.dropna(), station_ts_res.dropna()]
            s1_and_station = pd.concat(tobemerged, axis=1, join='inner')
            ts_bias = s1_and_station[0].subtract(s1_and_station[1]).median()

            xytmp = pd.concat(
                {
                    'y': s1_and_station[0] - ts_bias,
                    'x': s1_and_station[1]
                },
                join='inner',
                axis=1)
            if cntr == 1:
                xyplot = xytmp
            else:
                xyplot = pd.concat([xyplot, xytmp], axis=0)

            cntr = cntr + 1

            ts_cor = s1_and_station[0].corr(s1_and_station[1])
            ts_rmse = np.sqrt(
                np.nanmean(
                    np.square(s1_and_station[0].subtract(s1_and_station[1]))))
            ts_ubrmse = np.sqrt(
                np.sum(
                    np.square((s1_and_station[0] - s1_and_station[0].mean()) -
                              (s1_and_station[1] - s1_and_station[1].mean())))
                / len(s1_and_station[0]))
            print('R: ' + str(ts_cor))
            print('RMSE: ' + str(ts_rmse))
            print('Bias: ' + str(ts_bias))
            txtrep.write(st_name + ', ' + str(ts_cor) + ', ' + str(ts_rmse) +
                         '\n')

            s1_ts_list.append(s1_ts)
            station_ts_list.append(station_ts)
            station_name_list.append(st_name)
            gldas_ts_list.append(gldas_ts)
            # plot
            fig, ax1 = plt.subplots(figsize=(7.16, 1.4), dpi=300)
            line1, = ax1.plot(s1_ts.index,
                              s1_ts,
                              color='b',
                              linestyle='-',
                              marker='+',
                              label='Sentinel-1',
                              linewidth=0.2)
            line2, = ax1.plot(station_ts.index,
                              station_ts,
                              label='In-Situ',
                              linewidth=0.4)
            if np.any(outliers) and outliers is not None:
                line6, = ax1.plot(s1_ts.index[outliers],
                                  s1_ts.iloc[outliers],
                                  color='r',
                                  linestyle='',
                                  marker='o')
            if calcstd == True:
                line4, = ax1.plot(s1_ts.index,
                                  s1_ts - np.sqrt(s1_ts_std),
                                  color='k',
                                  linestyle='--',
                                  linewidth=0.2)
                line5, = ax1.plot(s1_ts.index,
                                  s1_ts + np.sqrt(s1_ts_std),
                                  color='k',
                                  linestyle='--',
                                  linewidth=0.2)
            line6, = ax1.plot(gldas_ts.index,
                              gldas_ts,
                              color='g',
                              linestyle='--',
                              label='GLDAS',
                              linewidth=0.2)

            ax1.set_ylabel('Soil Moisture [m3m-3]', size=8)
            smc_max = np.max([s1_ts.max(), station_ts.max()])
            if smc_max <= 0.5:
                smc_max = 0.5
            ax1.set_ylim((0, smc_max))
            ax1.text(
                0.85,
                0.4,
                'R=' + '{:03.2f}'.format(ts_cor) +
                # '\nRMSE=' + '{:03.2f}'.format(ts_rmse) +
                '\nBias=' + '{:03.2f}'.format(ts_bias) + '\nubRMSE=' +
                '{:03.2f}'.format(ts_ubrmse),
                transform=ax1.transAxes,
                fontsize=8)
            plt.title(st_name, fontsize=8)
            plt.tight_layout()
            plt.savefig(plotpath, dpi=300)
            plt.close()
        except:
            print('No data for: ' + st_name)

    pickle.dump(
        (s1_ts_list, station_ts_list, gldas_ts_list, station_name_list),
        open(
            'C:/Users/FGreifeneder/OneDrive - Scientific Network South Tyrol/1_THESIS/pub3/images_submission2/w_GLDAS_validation_tss_mazia'
            + name + '.p', 'wb'))
    urmse_scatter = np.sqrt(
        np.sum(
            np.square((xyplot['y'] - xyplot['y'].mean()) -
                      (xyplot['x'] - xyplot['x'].mean()))) / len(xyplot['y']))
    rmse_scatter = np.sqrt(
        np.nanmean(np.square(xyplot['x'].subtract(xyplot['y']))))
    r_scatter = xyplot['x'].corr(xyplot['y'])
    # plt.figure(figsize=(3.5, 3), dpi=600)
    xyplot.plot.scatter(x='x',
                        y='y',
                        color='k',
                        xlim=(0, 1),
                        ylim=(0, 1),
                        figsize=(3.5, 3),
                        s=1,
                        marker='.')
    plt.xlim(0, 0.7)
    plt.ylim(0, 0.7)
    plt.xlabel("$SMC_{Tot}$ [m$^3$m$^{-3}$]", size=8)
    plt.ylabel("$SMC^*_{Tot}$ [m$^3$m$^{-3}$]", size=8)
    plt.plot([0, 0.7], [0, 0.7], 'k--')
    plt.text(0.1,
             0.5,
             'R=' + '{:03.2f}'.format(r_scatter) + '\nRMSE=' +
             '{:03.2f}'.format(rmse_scatter),
             fontsize=8)  # +
    # '\nRMSE=' + '{:03.2f}'.format(rmse_scatter), fontsize=8)
    plt.tick_params(labelsize=8)
    plt.title('True vs. estimated SMC', size=8)
    plt.axes().set_aspect('equal', 'box')
    plt.tight_layout()
    plt.savefig(outpath + '1_Mazia_scatterplot.png', dpi=600)
    plt.close()

    txtrep.write(
        '------------------------------------------------------------------------\n\n'
    )
    txtrep.write('Overall performance:\n')
    txtrep.write('R = ' + str(xyplot['x'].corr(xyplot['y'])) + '\n')
    txtrep.write(
        'RMSE = ' +
        str(np.sqrt(np.nanmean(np.square(xyplot['x'].subtract(xyplot['y']))))))
    txtrep.write('ubRMSE = ' + str(
        np.sqrt(
            np.sum(
                np.square((xyplot['y'] - xyplot['y'].mean()) -
                          (xyplot['x'] - xyplot['x'].mean()))) /
            len(xyplot['y']))))

    txtrep.close()