Exemplo n.º 1
0
def metrics ( station, datespan, forecasts, doPlot=False ):    
    """
    Computes a full set of time series comparison metrics
    over a specified dateSpan
    for a given CO-OPS station 7-digit IDs (str)
    and the list of model forecasts.
    
    Returns mx and fx - lists of metrics and corresponding lead times (hrs)
    """
    
    mx = [] # metrics
    fx = [] # lead time, in hrs

    if doPlot:
        import matplotlib
        matplotlib.use('Agg',warn=False)
        import matplotlib.pyplot as plt
           
    data = coops.getData(station, datespan) 
    
    if len(data['values']):

        if doPlot:            
            plt.figure(figsize=(20,4.5))
            
        for model in forecasts:
            
        #model = getPointsWaterlevel (ncFile)
            fcst_time = model['time'][60]
            lead_time = 1./3600*(fcst_time-datespan[0]).total_seconds()
            fx.append(lead_time)
            counter = 0
            nst = np.nan
            for s in model['stations']:
                if station in s:
                    nst = counter
                    break
                counter += 1    
                    
            # Project
            pdates, pdata, pmodel = \
            interp.projectTimeSeries (data['dates'], data['values'], 
                                      model['time'], model['zeta'][:,nst], 
                                           refStepMinutes=6)
            
            #Run metrics
            metrics = valstat.metrics (pdata, pmodel, pdates)
            mx.append(metrics)

            #Plot data and model forecasts (optional)
            if doPlot:
                plt.plot(pdates, pdata, c='green')
                plt.plot(pdates, pmodel, c=np.random.rand(3,))
                plt.title('station ' + station)
                plt.savefig('ts-metrics-' + station + '.png')

    return mx, np.array(fx)
Exemplo n.º 2
0
def plot_estofs_timeseries(obs_dates,
                           obs_values,
                           mod_dates,
                           mod_values,
                           figFile=None,
                           stationName='',
                           htp_dates=None,
                           htp_vals=None,
                           daterange=None,
                           ylim=[-2.0, 2.0]):
    """
    Project obs and model onto the same timeline;
    Compute RMSD
    """
    #Sort by date
    obs_dates = np.array(obs_dates)
    obs_values = np.array(obs_values)
    ind = np.argsort(obs_dates)
    obs_dates = obs_dates[ind]
    obs_values = obs_values[ind]
    # Remove nans
    ind = np.logical_not(np.isnan(obs_values))
    obs_dates = obs_dates[ind]
    obs_values = obs_values[ind]

    #Sort by date
    mod_dates = np.array(mod_dates)
    mod_values = np.array(mod_values)
    ind = np.argsort(mod_dates)
    mod_dates = mod_dates[ind]
    mod_values = mod_values[ind]

    #Rid of mask
    if hasattr(mod_values, 'mask'):
        ind = ~mod_values.mask
        mod_dates = mod_dates[ind]
        mod_values = mod_values[ind]
    # Remove nans
    ind = np.logical_not(np.isnan(mod_values))
    mod_dates = mod_dates[ind]
    mod_values = mod_values[ind]

    refStepMinutes = 6
    refDates, obsValProj, modValProj = \
             interp.projectTimeSeries(obs_dates, obs_values,
                                      mod_dates, mod_values,
                                      refStepMinutes)

    rmsd = valstat.rms(obsValProj - modValProj)
    N = len(obsValProj)

    if figFile:
        print '[info]: creating a plot ', figFile
        plt.figure(figsize=(20, 4.5))
        if htp_dates is not None:
            plt.plot(htp_dates, htp_vals, color='c', label='ASTRON. TIDE')
        plt.plot(obs_dates, obs_values, '.', color='g', label='OBSERVED')
        plt.plot(mod_dates,
                 mod_values,
                 '.',
                 color='b',
                 label='STORM TIDE FCST')

        try:
            peak_val = np.nanmax(mod_values)
            peak_ft = 3.28 * peak_val
            peak_dat = mod_dates[np.argmax(mod_values)]
            plt.plot(peak_dat, peak_val, 'bo')
            plt.text(peak_dat,
                     1.05 * peak_val,
                     str(np.round(peak_val, 1)) + "m (" +
                     str(np.round(peak_ft, 1)) + "ft) MSL",
                     color='b')
            plt.plot([obs_dates[0], mod_dates[-1]], [peak_val, peak_val],
                     '--b')
            plt.plot([peak_dat, peak_dat], [ylim[0], ylim[1]], '--b')

            peak_str = str(peak_dat.hour).zfill(2) + ':' + str(
                peak_dat.minute).zfill(2)
            plt.text(peak_dat, ylim[0], peak_str, color='b')

            #Attempt to post-correct
            lastdata = np.where(mod_dates == valstat.nearest(
                mod_dates, obs_dates[-1])[0])[0][0]
            offset = obs_values[-1] - mod_values[lastdata]
            offset_ft = 3.28 * offset
            plt.plot(mod_dates[lastdata:],
                     offset + mod_values[lastdata:],
                     color='gray',
                     label='POST-CORRECTED')
            plt.plot(peak_dat, offset + peak_val, 'o', color='gray')
            plt.text(peak_dat, 1.05*(offset+peak_val), \
                     str(np.round(offset+peak_val,1)) + "m (" + str(np.round(peak_ft+offset_ft,1)) +"ft) MSL", color='gray')

        except:
            pass

        plt.ylim(ylim)
        if daterange is not None:
            plt.xlim([daterange[0], mod_dates[-1]])
        #if rmsd > 0:
        #plt.title(stationName+', RMSD=' +str(rmsd)+' meters')
        #else:
        plt.title(stationName)
        plt.legend(bbox_to_anchor=(0.9, 0.35))
        plt.grid()
        plt.xlabel('DATE UTC')
        plt.ylabel('WL, meters LMSL')
        plt.savefig(figFile)
        #plt.close()
    return {'rmsd': rmsd, 'N': N}