Beispiel #1
0
    def getTime(self,timeinfo):
        """
        Get the particle time step info
        """
        self.dt = timeinfo[2]

        self.time_track = othertime.TimeVector(timeinfo[0],timeinfo[1],timeinfo[2],timeformat ='%Y%m%d.%H%M%S')

        self.time_track_sec = othertime.SecondsSince(self.time_track)
        self.time_sec = othertime.SecondsSince(self.time)

        self.time_index = -9999
Beispiel #2
0
def tide_pred(modfile, lon, lat, time, z=None, conlist=None):
    """
    Performs a tidal prediction at all points in [lon,lat] at times in vector [time]

    """

    # Read and interpolate the constituents
    u_re, u_im, v_re, v_im, h_re, h_im, omega, conlist = extract_HC(
        modfile, lon, lat, z=z, conlist=conlist)

    # Initialise the output arrays
    sz = lon.shape
    nx = np.prod(sz)
    nt = time.shape[0]
    ncon = omega.shape[0]

    h_re = h_re.reshape((ncon, nx))
    h_im = h_im.reshape((ncon, nx))
    u_re = u_re.reshape((ncon, nx))
    u_im = u_im.reshape((ncon, nx))
    v_re = v_re.reshape((ncon, nx))
    v_im = v_im.reshape((ncon, nx))

    # Calculate nodal correction to amps and phases
    #baseyear = time[0].year
    #t1992 = othertime.SecondsSince(datetime(baseyear,1,1),basetime=datetime(1992,1,1))/86400.0
    t1992 = othertime.SecondsSince(time[0], basetime=datetime(1992, 1,
                                                              1)) / 86400.0

    pu, pf, v0u = nodal(t1992 + 48622.0, conlist)

    # Calculate the time series
    tsec = othertime.SecondsSince(time, basetime=datetime(
        1992, 1, 1))  # Needs to be referenced to 1992

    h = np.zeros((nt, nx))
    u = np.zeros((nt, nx))
    v = np.zeros((nt, nx))
    for nn, om in enumerate(omega):
        for ii in range(0, nx):
            h[:,ii] += pf[nn]*h_re[nn,ii] * np.cos(om*tsec + v0u[nn] + pu[nn]) - \
                pf[nn]*h_im[nn,ii] * np.sin(om*tsec + v0u[nn] + pu[nn])

            u[:,ii] += pf[nn]*u_re[nn,ii] * np.cos(om*tsec + v0u[nn] + pu[nn]) - \
                pf[nn]*u_im[nn,ii] * np.sin(om*tsec + v0u[nn] + pu[nn])

            v[:,ii] += pf[nn]*v_re[nn,ii] * np.cos(om*tsec + v0u[nn] + pu[nn]) - \
                pf[nn]*v_im[nn,ii] * np.sin(om*tsec + v0u[nn] + pu[nn])

    szo = (nt, ) + sz
    return h.reshape(szo), u.reshape(szo), v.reshape(szo)
Beispiel #3
0
def extract_phsamp(tidemod, lon, lat, basetime, conlist):
    """
    Extract the phase and amplitude
    """
    u_re, u_im, v_re, v_im, h_re, h_im, omega, conlist =\
        extract_HC(tidemod, X, Y, conlist = conlist)

    t1992 = othertime.SecondsSince(basetime, basetime=datetime(1992, 1,
                                                               1)) / 86400.0

    pu, pf, v0u = nodal(t1992 + 48622.0, conlist)

    u_amp = np.abs(u_re + 1j * u_im)
    v_amp = np.abs(v_re + 1j * v_im)
    h_amp = np.abs(h_re + 1j * h_im)

    u_phs = np.angle(u_re + 1j * u_im)
    v_phs = np.angle(v_re + 1j * v_im)
    h_phs = np.angle(h_re + 1j * h_im)

    # Apply the corrections
    for ii, cc in enumerate(omega):
        u_amp *= pf[ii]
        v_amp *= pf[ii]
        h_amp *= pf[ii]

        u_phs += (v0u[ii] + pu[ii])
        v_phs += (v0u[ii] + pu[ii])
        h_phs += (v0u[ii] + pu[ii])

    return u_amp, u_phs,\
        v_amp, v_phs,\
        h_amp, h_phs, omega
Beispiel #4
0
def tide_pred_old(modfile, lon, lat, time, z=None, conlist=None):
    """

        ### UNUSED ###
    Performs a tidal prediction at all points in [lon,lat] at times in vector [time]

    """

    # Read and interpolate the constituents
    u_re, u_im, v_re, v_im, h_re, h_im, omega, conlist = extract_HC(
        modfile, lon, lat, z=z, conlist=conlist)

    # Initialise the output arrays
    sz = lon.shape
    nx = np.prod(sz)
    nt = time.shape[0]
    ncon = omega.shape[0]

    h_re = h_re.reshape((ncon, nx))
    h_im = h_im.reshape((ncon, nx))
    u_re = u_re.reshape((ncon, nx))
    u_im = u_im.reshape((ncon, nx))
    v_re = v_re.reshape((ncon, nx))
    v_im = v_im.reshape((ncon, nx))

    # Nodal correction to amps and phases here...
    baseyear = time[0].year
    amp, phase = cart2pol(h_re, h_im)
    amp, phase = nodal_correction(baseyear, conlist, amp, phase)
    h_re, h_im = pol2cart(amp, phase)

    amp, phase = cart2pol(u_re, u_im)
    amp, phase = nodal_correction(baseyear, conlist, amp, phase)
    u_re, u_im = pol2cart(amp, phase)

    amp, phase = cart2pol(v_re, v_im)
    amp, phase = nodal_correction(baseyear, conlist, amp, phase)
    v_re, v_im = pol2cart(amp, phase)

    # Calculate the time series
    tsec = othertime.SecondsSince(time, basetime=datetime(baseyear, 1, 1))
    h = np.zeros((nt, nx))
    u = np.zeros((nt, nx))
    v = np.zeros((nt, nx))
    for nn, om in enumerate(omega):
        for ii in range(0, nx):
            h[:, ii] += h_re[nn, ii] * np.cos(
                om * tsec) + h_im[nn, ii] * np.sin(om * tsec)
            u[:, ii] += u_re[nn, ii] * np.cos(
                om * tsec) + u_im[nn, ii] * np.sin(om * tsec)
            v[:, ii] += v_re[nn, ii] * np.cos(
                om * tsec) + v_im[nn, ii] * np.sin(om * tsec)

    szo = (nt, ) + sz
    return h.reshape(szo), u.reshape(szo), v.reshape(szo)
Beispiel #5
0
    def __call__(self,tstart,tend,varnames=['eta','uc','vc']):
        """
        Actually does the harmonic calculation for the model time steps in tsteps
        (or at least calls the class that does the calculation)

        Set tstart = -1 to do all steps
        """
        if tstart == -1:
            self.tstep=np.arange(0,self.Nt,1)
        else:
            self.tstep=self.getTstep(tstart,tend)

        time = othertime.SecondsSince(self.time[self.tstep])

        self.varnames=varnames
        self._prepDict(varnames)


        for vv in varnames:
            if vv in ['ubar','vbar']:
                ndim=2
                if vv=='ubar': self.variable='uc'
                if vv=='vbar': self.variable='vc'
            else:
                ndim = self._returnDim(vv)
                self.variable=vv

            if ndim  == 2 or self.Nkmax==1:
                print('Loading data from %s...'%vv)
                if vv in ['ubar','vbar']:
                    data=self.loadDataBar()
                else:
                    data=self.loadData()
                print('Performing harmonic fit on variable, %s...'%(self.variable))
                self.Amp[vv], self.Phs[vv], self.Mean[vv] =\
                        harmonic_fit(time, data, self.frq, \
                        phsbase=self.reftime,\
                        #phsbase=None,\
                        )

            elif ndim == 3:
                for k in range(self.Nkmax):
                    self.klayer=[k]
                    print('Loading data...')
                    data = self.loadData()
                    print('Performing harmonic fit on variable, %s, layer = %d of %d...'%(self.variable,self.klayer[0],self.Nkmax))
                    self.Amp[vv][:,k,:], self.Phs[vv][:,k,:], self.Mean[vv][k,:] =\
                        harmonic_fit(time, data, self.frq, \
                        phsbase=self.reftime,\
                        #phsbase=None,
                        )
Beispiel #6
0
    def __init__(self, x, y, z, timeinfo, tformat='%Y%m%d.%H%M%S', **kwargs):

        metfile.__init__(self, mode='create', **kwargs)

        self.x = x
        self.y = y
        self.z = z
        self.time =\
            otime.TimeVector(timeinfo[0],timeinfo[1],timeinfo[2],timeformat=tformat)
        self.nctime = otime.SecondsSince(self.time)

        #self.varnames = ['Uwind','Vwind','Tair','Pair','RH','rain','cloud']

        # Update all of the metdata objects
        for vv in self.varnames:
            self.updateMetData(self[vv])
Beispiel #7
0
def calc_agebin(binfile, ncfile, polyfile, ntout):
    """
    Calculate the from a binary file and save to netcdf
    """
    # Load the polygon from a shapefile
    xypoly, field = readShpPoly(polyfile)

    # Load the binary file object
    PTM = PtmBin(binfile)

    # Count the number of particles from the first time step
    time, pdata = PTM.read_timestep()
    N = pdata.shape[0]
    tsec = othertime.SecondsSince(PTM.time)
    dt = tsec[1] - tsec[0]

    # Initialize the age particle object
    Age = ParticleAge(xypoly[0], N)

    # Loop through
    outctr = ntout
    ncctr = 0
    for tt in range(PTM.nt - 1):
        # Read the current time step
        time, pdata = PTM.read_timestep(ts=tt)

        # Update the age variable
        Age.update_age(pdata['x'][:, 0], pdata['x'][:, 1], pdata['x'][:, 2],
                       dt)

        # Write to netcdf
        if outctr == ntout:
            Age.write_nc(time, ncctr, ncfile=ncfile)
            ncctr += 1
            outctr = 0
        outctr += 1

    print('Done.')
Beispiel #8
0
def tide_pred_correc(modfile,
                     lon,
                     lat,
                     time,
                     dbfile,
                     ID,
                     z=None,
                     conlist=None):
    """
    Performs a tidal prediction at all points in [lon,lat] at times in vector [time]

    Applies an amplitude and phase correction based on a time series
    """
    from timeseries import timeseries, loadDBstation

    print('Calculating tidal correction factors from time series...')
    # Load using the timeseries module
    t0 = datetime.strftime(time[0], '%Y%m%d.%H%M%S')
    t1 = datetime.strftime(time[-1], '%Y%m%d.%H%M%S')
    dt = time[1] - time[0]

    print(t0, t1, dt.total_seconds())
    timeinfo = (t0, t1, dt.total_seconds())
    TS, meta = loadDBstation(dbfile,
                             ID,
                             'waterlevel',
                             timeinfo=timeinfo,
                             filttype='low',
                             cutoff=2 * 3600,
                             output_meta=True)
    lonpt = meta['longitude']
    latpt = meta['latitude']
    print(lonpt, latpt)

    # Extract the OTIS tide prediction
    u_re, u_im, v_re, v_im, h_re, h_im, omega, conlist = extract_HC(
        modfile, lonpt, latpt)
    h_amp = np.abs(h_re + 1j * h_im)[:, 0]
    h_phs = np.angle(h_re + 1j * h_im)[:, 0]

    # Harmonic analysis of observation time series
    amp, phs, frq, frqnames, htide = TS.tidefit(frqnames=conlist)
    TS_harm = timeseries(time, htide)
    residual = TS.y - htide

    # Calculate the amp and phase corrections
    dphs = phs - h_phs + np.pi
    damp = amp / h_amp

    # Extract the data along the specified points
    u_re, u_im, v_re, v_im, h_re, h_im, omega, conlist = extract_HC(
        modfile, lon, lat, z=z, conlist=conlist)

    h_amp = np.abs(h_re + 1j * h_im)
    h_phs = np.angle(h_re + 1j * h_im)
    u_amp = np.abs(u_re + 1j * u_im)
    u_phs = np.angle(u_re + 1j * u_im)
    v_amp = np.abs(v_re + 1j * v_im)
    v_phs = np.angle(v_re + 1j * v_im)

    # Initialise the output arrays
    sz = lon.shape
    nx = np.prod(sz)
    nt = time.shape[0]

    h = np.zeros((nt, nx))
    u = np.zeros((nt, nx))
    v = np.zeros((nt, nx))

    # Rebuild the time series
    #tsec=TS_harm.tsec - TS_harm.tsec[0]
    tsec = othertime.SecondsSince(time, basetime=time[0])
    print(tsec[0])
    for nn, om in enumerate(omega):
        for ii in range(0, nx):
            h[:,
              ii] += damp[nn] * h_amp[nn,
                                      ii] * np.cos(om * tsec -
                                                   (h_phs[nn, ii] + dphs[nn]))
            u[:,
              ii] += damp[nn] * u_amp[nn,
                                      ii] * np.cos(om * tsec -
                                                   (u_phs[nn, ii] + dphs[nn]))
            v[:,
              ii] += damp[nn] * v_amp[nn,
                                      ii] * np.cos(om * tsec -
                                                   (v_phs[nn, ii] + dphs[nn]))

    szo = (nt, ) + sz
    return h.reshape(szo), u.reshape(szo), v.reshape(szo), residual
Beispiel #9
0
def ProfilePlot(t,y,z,scale=86400,\
        axis=0,color=[0.5,0.5,0.5],xlim=None,units='m/s',scalebar=1.0):
    """
    Plot a series of vertical profiles as a time series

    scale - Sets 1 unit = scale (seconds)

    See this page on formatting:
        http://matplotlib.org/examples/pylab_examples/date_index_formatter.html
    """
    class MyFormatter(Formatter):
        def __init__(self, dates, fmt='%b %d %Y'):
            self.fmt = fmt
            self.dates = dates

        def __call__(self, x, pos=0):
            'Return the label for time x s'
            return datetime.strftime(
                datetime(1990, 1, 1) + timedelta(seconds=x), self.fmt)

    tsec = othertime.SecondsSince(t)
    formatter = MyFormatter(tsec)

    y = np.swapaxes(y, 0, axis)

    lines = []
    line2 = []
    for ii, tt in enumerate(tsec):
        #xplot = set_scale(y[:,ii],tt)
        xplot = tt + y[:, ii] * scale
        lines.append(np.array((xplot, z)).T)
        line2.append(np.array([[tt, tt], [z[0], z[-1]]]).T)

    LC1 = collections.LineCollection(lines, colors=color, linewidths=1.5)
    LC2 = collections.LineCollection(line2, colors='k',
                                     linestyles='dashed')  # Zero axis

    ax = plt.gca()
    ax.add_collection(LC1)
    ax.add_collection(LC2)
    ax.set_ylim((z.min(), z.max()))
    ax.xaxis.set_major_formatter(formatter)
    if xlim == None:
        xlim = (tsec[0] - scale / 2, tsec[-1] + scale / 2)
    else:
        xlim = othertime.SecondsSince(xlim)
    ax.set_xlim(xlim)
    plt.xticks(rotation=17)

    ###
    # Add a scale bar
    ###

    # Compute the scale bar size in dimensionless units
    if not scalebar == None:
        xscale = scalebar * scale / (xlim[-1] - xlim[0])
        x0 = 0.1
        y0 = 0.8
        dy = 0.02
        ax.add_line(
            Line2D([x0, x0 + xscale], [y0, y0],
                   linewidth=0.5,
                   color='k',
                   transform=ax.transAxes))
        #Little caps
        ax.add_line(
            Line2D([x0, x0], [y0 - dy, y0 + dy],
                   linewidth=0.5,
                   color='k',
                   transform=ax.transAxes))
        ax.add_line(
            Line2D([x0 + xscale, x0 + xscale], [y0 - dy, y0 + dy],
                   linewidth=0.5,
                   color='k',
                   transform=ax.transAxes))
        plt.text(x0,y0+0.05,'Scale %3.1f %s'%(scalebar,units),\
            transform=ax.transAxes)

    return ax