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)
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, lon, lat, 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
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)
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])
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.')
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
def writeNC(self, outfile, dv=None): """ Export the results to a netcdf file """ from .suntans_ugrid import ugrid from netCDF4 import Dataset # Fill in the depths with zero #if not self.__dict__.has_key('dv'): if dv is None: self.dv = np.zeros((self.Nc, )) else: self.dv = dv if 'Nk' not in self.__dict__: self.Nk = self.Nkmax * np.ones((self.Nc, )) Grid.writeNC(self, outfile) # write the time variable t = othertime.SecondsSince(self.time) self.create_nc_var(outfile, 'time', ugrid['time']['dimensions'], ugrid['time']['attributes']) # Create the other variables self.create_nc_var( outfile, 'eta', ('time', 'Nc'), { 'long_name': 'Sea surface elevation', 'units': 'metres', 'coordinates': 'time yv xv' }) self.create_nc_var( outfile, 'uc', ('time', 'Nk', 'Nc'), { 'long_name': 'Eastward water velocity component', 'units': 'metre second-1', 'coordinates': 'time z_r yv xv' }) self.create_nc_var( outfile, 'vc', ('time', 'Nk', 'Nc'), { 'long_name': 'Northward water velocity component', 'units': 'metre second-1', 'coordinates': 'time z_r yv xv' }) self.create_nc_var( outfile, 'salt', ('time', 'Nk', 'Nc'), { 'long_name': 'Salinity', 'units': 'ppt', 'coordinates': 'time z_r yv xv' }) self.create_nc_var( outfile, 'temp', ('time', 'Nk', 'Nc'), { 'long_name': 'Water temperature', 'units': 'degrees C', 'coordinates': 'time z_r yv xv' }) self.create_nc_var(outfile, 'agec', ('time', 'Nk', 'Nc'), { 'long_name': 'Age concentration', 'units': '' }) self.create_nc_var( outfile, 'agealpha', ('time', 'Nk', 'Nc'), { 'long_name': 'Age alpha parameter', 'units': 'seconds', 'coordinates': 'time z_r yv xv' }) self.create_nc_var(outfile,'agesource',('Nk','Nc'),\ {'long_name':'Age source grid cell (>0 = source)',\ 'units':'','coordinates':'z_r yv xv'}) # now write the variables... nc = Dataset(outfile, 'a') nc.variables['time'][:] = t nc.variables['eta'][:] = self.h nc.variables['uc'][:] = self.uc nc.variables['vc'][:] = self.vc nc.variables['salt'][:] = self.S nc.variables['temp'][:] = self.T nc.variables['agec'][:] = self.agec nc.variables['agealpha'][:] = self.agealpha nc.variables['agesource'][:] = self.agesource nc.close() print('Initial condition file written to: %s' % outfile)
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