def reconstr(self, time): if self.coef['aux']['opt']['twodim']: self.U, self.V = ut_reconstr(time, self.coef) self.QC.append('ut_reconstr done for velocity') else: self.ts_recon, _ = ut_reconstr(time, self.coef) self.QC.append('ut_reconstr done for elevation')
def Harmonic_reconstruction(self, harmo, elevation=True, velocity=False, time_ind=slice(None), debug=False, **kwarg): ''' Description: ---------- This function reconstructs the velocity components or the surface elevation from harmonic coefficients. Harmonic_reconstruction calls ut_reconstr. This function assumes harmonics (ut_solv) has already been executed. Inputs: ------ - Harmo = harmonic coefficient from harmo_analysis - elevation =True means that ut_reconstr will be done for elevation. - velocity =True means that ut_reconst will be done for velocity. - time_ind = time indices to process, list of integers Output: ------ - Reconstruct = reconstructed signal, dictionary Options: ------- Options are the same as for ut_reconstr, which are shown below with their default values: cnstit = [], minsnr = 2, minpe = 0 Notes: ----- For more detailed information about ut_reconstr, please see https://github.com/wesleybowman/UTide ''' debug = (debug or self._debug) time = self._var.matlabTime[time_ind] #TR_comments: Add debug flag in Utide: debug=self._debug Reconstruct = {} if velocity: U_recon, V_recon = ut_reconstr(time, harmo) Reconstruct['U'] = U_recon Reconstruct['V'] = V_recon if elevation: elev_recon, _ = ut_reconstr(time, harmo) Reconstruct['el'] = elev_recon return Reconstruct
def Harmonic_reconstruction( self, harmo, elevation=True, velocity=False, time_ind=slice(None), debug=False, **kwarg ): """ Description: ---------- This function reconstructs the velocity components or the surface elevation from harmonic coefficients. Harmonic_reconstruction calls ut_reconstr. This function assumes harmonics (ut_solv) has already been executed. Inputs: ------ - Harmo = harmonic coefficient from harmo_analysis - elevation =True means that ut_reconstr will be done for elevation. - velocity =True means that ut_reconst will be done for velocity. - time_ind = time indices to process, list of integers Output: ------ - Reconstruct = reconstructed signal, dictionary Options: ------- Options are the same as for ut_reconstr, which are shown below with their default values: cnstit = [], minsnr = 2, minpe = 0 Notes: ----- For more detailed information about ut_reconstr, please see https://github.com/wesleybowman/UTide """ debug = debug or self._debug time = self._var.matlabTime[time_ind] # TR_comments: Add debug flag in Utide: debug=self._debug Reconstruct = {} if velocity: U_recon, V_recon = ut_reconstr(time, harmo) Reconstruct["U"] = U_recon Reconstruct["V"] = V_recon if elevation: elev_recon, _ = ut_reconstr(time, harmo) Reconstruct["el"] = elev_recon return Reconstruct
def compareTG(data): ''' Does a comprehensive comparison between tide gauge height data and modeled data, much like the above function. Input is a dictionary containing all necessary tide gauge and model data. Outputs a dictionary of useful statistics. ''' # load data mod_elev = data['mod_timeseries']['elev'] obs_elev = data['obs_timeseries']['elev'] obs_datenums = data['obs_time'] mod_datenums = data['mod_time'] mod_harm = data['elev_mod_harmonics'] # convert times and grab values obs_time, mod_time = [], [] for i, v in enumerate(obs_datenums): obs_time.append(dn2dt(v)) for j, w in enumerate(mod_datenums): mod_time.append(dn2dt(w)) # check if they line up in the time domain if (mod_time[-1] < obs_time[0] or obs_time[-1] < mod_time[0]): # use ut_reconstr to create a new timeseries mod_elev_int = ut_reconstr(obs_datenums, mod_harm)[0] obs_elev_int = obs_elev step_int = obs_time[1] - obs_time[0] start_int = obs_time[0] else: # interpolate timeseries onto a common timestep (obs_elev_int, mod_elev_int, step_int, start_int) = \ smooth(mod_elev, mod_time, obs_elev, obs_time) # get validation statistics stats = TidalStats(mod_elev_int, obs_elev_int, step_int, start_int, debug=True, type='height') elev_suite = stats.getStats() elev_suite['r_squared'] = stats.linReg()['r_2'] elev_suite['phase'] = stats.getPhase(debug=False) return elev_suite
def compareTG(data): ''' Does a comprehensive comparison between tide gauge height data and modeled data, much like the above function. Input is a dictionary containing all necessary tide gauge and model data. Outputs a dictionary of useful statistics. ''' # load data mod_elev = data['mod_timeseries']['elev'] obs_elev = data['obs_timeseries']['elev'] obs_datenums = data['obs_time'] mod_datenums = data['mod_time'] mod_harm = data['elev_mod_harmonics'] print data['name'] # convert times and grab values obs_time, mod_time = [], [] for i, v in enumerate(obs_datenums): obs_time.append(dn2dt(v)) for j, w in enumerate(mod_datenums): mod_time.append(dn2dt(w)) # check if they line up in the time domain if (mod_time[-1] < obs_time[0] or obs_time[-1] < mod_time[0]): # use ut_reconstr to create a new timeseries mod_elev_int = ut_reconstr(obs_datenums, mod_harm)[0] obs_elev_int = obs_elev step_int = obs_time[1] - obs_time[0] start_int = obs_time[0] else: # interpolate timeseries onto a common timestep (obs_elev_int, mod_elev_int, step_int, start_int) = \ smooth(mod_elev, mod_time, obs_elev, obs_time) # get validation statistics stats = TidalStats(mod_elev_int, obs_elev_int, step_int, start_int, debug=True, type='height') elev_suite = stats.getStats() elev_suite['r_squared'] = stats.linReg()['r_2'] elev_suite['phase'] = stats.getPhase(debug=False) return elev_suite
def reconstr(self, harmo, time_ind=slice(None), **kwarg): ''' Description: ---------- This function reconstructs the velocity components or the surface elevation from harmonic coefficients. Harmonic_reconstruction calls ut_reconstr. This function assumes harmonics (ut_solv) has already been executed. Inputs: ------ - Harmo = harmonic coefficient from harmo_analysis Output: ------ - Reconstruct = reconstructed signal, dictionary Keywords: ------ - time_ind = time indices to process, list of integers Options: ------- Options are the same as for ut_reconstr, which are shown below with their default values: cnstit = [], minsnr = 2, minpe = 0 Notes: ----- For more detailed information about ut_reconstr, please see https://github.com/wesleybowman/UTide ''' time = self._var.matlabTime[time_ind] ts_recon, _ = ut_reconstr(time, harmo, **kwarg) return ts_recon
def reconstr(self, time): self.ts_recon, _ = ut_reconstr(time, self.coef)
import numpy as np def datetime2matlabdn(dt): ord = dt.toordinal() mdn = dt + timedelta(days = 366) frac = (dt-datetime(dt.year,dt.month,dt.day,0,0,0)).seconds / (24.0 * 60.0 * 60.0) return mdn.toordinal() + frac # load in struct harmonics filename = '/EcoII/EcoEII_server_data_tree/code/wesCode/project/june_2013_3D_station.p' file = open(filename, 'rb') struct = pickle.load(file) site = struct['june_2013_3D_station'][0] harmonics = site['vel_mod_harmonics'] # create datenums and reconstruct start = datetime(2013, 3, 1, 0, 0, 0) step = timedelta(minutes=10) steps = 6 * 24 * 90 dt = start + np.arange(steps) * step dn = np.zeros(dt.size) for i, v in enumerate(dt): dn[i] = datetime2matlabdn(v) print pred_uv = ut_reconstr(dn, harmonics) speed = np.sqrt(pred_uv[0]**2 + pred_uv[1]**2) # plot plt.plot(dt, speed) plt.show()
def compareUV(data): ''' Does a comprehensive validation process between modeled and observed data on the following: Current speed Current direction Harmonic constituents (for height and speed) Outputs a list of important statistics for each variable, calculated using the TidalStats class ''' # take data from input dictionary mod_time = data['mod_time'] obs_time = data['obs_time'] mod_u = data['mod_timeseries']['ua'] mod_v = data['mod_timeseries']['va'] mod_el = data['mod_timeseries']['elev'] obs_u = data['obs_timeseries']['ua'] obs_v = data['obs_timeseries']['va'] obs_el = data['obs_timeseries']['elev'] v_mod_harm = data['vel_mod_harmonics'] v_obs_harm = data['vel_obs_harmonics'] el_mod_harm = data['elev_mod_harmonics'] el_obs_harm = data['elev_mod_harmonics'] # convert times to datetime mod_dt, obs_dt = [], [] for i in mod_time: mod_dt.append(dn2dt(i)) for j in obs_time: obs_dt.append(dn2dt(j)) # put data into a useful format mod_spd = np.sqrt(mod_u**2 + mod_v**2) obs_spd = np.sqrt(obs_u**2 + obs_v**2) mod_dir = np.arctan2(mod_v, mod_u) * 180 / np.pi obs_dir = np.arctan2(obs_v, obs_u) * 180 / np.pi obs_el = obs_el - np.mean(obs_el) # check if the modeled data lines up with the observed data if (mod_time[-1] < obs_time[0] or obs_time[-1] < mod_time[0]): pred_uv = ut_reconstr(obs_time, v_mod_harm) pred_uv = np.asarray(pred_uv) pred_h = ut_reconstr(obs_time, el_mod_harm) pred_h = np.asarray(pred_h) # redo speed and direction and set interpolated variables mod_sp_int = np.sqrt(pred_uv[0]**2 + pred_uv[1]**2) mod_ve_int = mod_sp_int * np.sign(pred_uv[1]) mod_dr_int = np.arctan2(pred_uv[1], pred_uv[0]) * 180 / np.pi mod_el_int = pred_h[0] mod_u_int = pred_uv[0] mod_v_int = pred_uv[1] obs_sp_int = obs_spd obs_ve_int = obs_spd * np.sign(obs_v) obs_dr_int = obs_dir obs_el_int = obs_el obs_u_int = obs_u obs_v_int = obs_v step_int = obs_dt[1] - obs_dt[0] start_int = obs_dt[0] else: # interpolate the data onto a common time step for each data type # elevation (mod_el_int, obs_el_int, step_int, start_int) = \ smooth(mod_el, mod_dt, obs_el, obs_dt) # speed (mod_sp_int, obs_sp_int, step_int, start_int) = \ smooth(mod_spd, mod_dt, obs_spd, obs_dt) # direction (mod_dr_int, obs_dr_int, step_int, start_int) = \ smooth(mod_dir, mod_dt, obs_dir, obs_dt) # u velocity (mod_u_int, obs_u_int, step_int, start_int) = \ smooth(mod_u, mod_dt, obs_u, obs_dt) # v velocity (mod_v_int, obs_v_int, step_int, start_int) = \ smooth(mod_v, mod_dt, obs_v, obs_dt) # velocity i.e. signed speed (mod_ve_int, obs_ve_int, step_int, start_int) = \ smooth(mod_spd * np.sign(mod_v), mod_dt, obs_spd * np.sign(obs_v), obs_dt) ''' # separate into ebb and flow mod_dir_n = get_DirFromN(mod_u_int, mod_v_int) obs_dir_n = get_DirFromN(obs_u_int, mod_v_int) mod_signed_s, mod_PA = sign_speed(mod_u_int, mod_v_int, mod_sp_int, mod_dr_int, 0) obs_signed_s, obs_PA = sign_speed(obs_u_int, obs_v_int, obs_sp_int, obs_dr_int, 0) print mod_signed_s[:20], mod_PA[:20] print obs_signed_s[:20], obs_PA[:20] ''' # remove directions where velocities are small MIN_VEL = 0.5 for i in np.arange(obs_sp_int.size): if (obs_sp_int[i] < MIN_VEL): obs_dr_int[i] = np.nan if (mod_sp_int[i] < MIN_VEL): mod_dr_int[i] = np.nan # get stats for each tidal variable elev_suite = tidalSuite(mod_el_int, obs_el_int, step_int, start_int, type='elevation', plot=True) speed_suite = tidalSuite(mod_sp_int, obs_sp_int, step_int, start_int, type='speed', plot=False) dir_suite = tidalSuite(mod_dr_int, obs_dr_int, step_int, start_int, type='direction', plot=False) u_suite = tidalSuite(mod_u_int, obs_u_int, step_int, start_int, type='u velocity', plot=False) v_suite = tidalSuite(mod_v_int, obs_v_int, step_int, start_int, type='v velocity', plot=False) vel_suite = tidalSuite(mod_ve_int, obs_ve_int, step_int, start_int, type='velocity', plot=True) #ebb_suite = tidalSuite(mod_ebb, obs_ebb, step_int, start_int, # type='ebb', plot=True) #flo_suite = tidalSuite(mod_flo, obs_flo, step_int, start_int, # type='flow', plot=True) # output statistics in useful format return (elev_suite, speed_suite, dir_suite, u_suite, v_suite, vel_suite)
def compareUV(data, threeDim, depth=5, plot=False): ''' Does a comprehensive validation process between modeled and observed data on the following: Current speed Current direction Harmonic constituents (for height and speed) Outputs a list of important statistics for each variable, calculated using the TidalStats class ''' # take data from input dictionary mod_time = data['mod_time'] obs_time = data['obs_time'] mod_el = data['mod_timeseries']['elev'] obs_el = data['obs_timeseries']['elev'] v_mod_harm = data['vel_mod_harmonics'] v_obs_harm = data['vel_obs_harmonics'] el_mod_harm = data['elev_mod_harmonics'] el_obs_harm = data['elev_mod_harmonics'] #Check if 3D simulation if threeDim: obs_u_all = data['obs_timeseries']['u'] obs_v_all = data['obs_timeseries']['v'] mod_u_all = data['mod_timeseries']['u'] mod_v_all = data['mod_timeseries']['v'] bins = data['obs_timeseries']['bins'] siglay = data['mod_timeseries']['siglay'] # use depth interpolation to get a single timeseries mod_depth = mod_el + np.mean(obs_el) (mod_u, obs_u) = depthFromSurf(mod_u_all, mod_depth, siglay, obs_u_all, obs_el, bins, depth=depth) (mod_v, obs_v) = depthFromSurf(mod_v_all, mod_depth, siglay, obs_v_all, obs_el, bins, depth=depth) else: obs_u = data['obs_timeseries']['ua'] obs_v = data['obs_timeseries']['va'] mod_u = data['mod_timeseries']['ua'] mod_v = data['mod_timeseries']['va'] # convert times to datetime mod_dt, obs_dt = [], [] for i in mod_time: mod_dt.append(dn2dt(i)) for j in obs_time: obs_dt.append(dn2dt(j)) # put data into a useful format mod_spd = np.sqrt(mod_u**2 + mod_v**2) obs_spd = np.sqrt(obs_u**2 + obs_v**2) mod_dir = np.arctan2(mod_v, mod_u) * 180 / np.pi obs_dir = np.arctan2(obs_v, obs_u) * 180 / np.pi obs_el = obs_el - np.mean(obs_el) # check if the modeled data lines up with the observed data if (mod_time[-1] < obs_time[0] or obs_time[-1] < mod_time[0]): pred_uv = ut_reconstr(obs_time, v_mod_harm) pred_uv = np.asarray(pred_uv) pred_h = ut_reconstr(obs_time, el_mod_harm) pred_h = np.asarray(pred_h) # redo speed and direction and set interpolated variables mod_sp_int = np.sqrt(pred_uv[0]**2 + pred_uv[1]**2) mod_ve_int = mod_sp_int * np.sign(pred_uv[1]) mod_dr_int = np.arctan2(pred_uv[1], pred_uv[0]) * 180 / np.pi mod_el_int = pred_h[0] mod_u_int = pred_uv[0] mod_v_int = pred_uv[1] obs_sp_int = obs_spd obs_ve_int = obs_spd * np.sign(obs_v) obs_dr_int = obs_dir obs_el_int = obs_el obs_u_int = obs_u obs_v_int = obs_v step_int = obs_dt[1] - obs_dt[0] start_int = obs_dt[0] else: # interpolate the data onto a common time step for each data type # elevation (mod_el_int, obs_el_int, step_int, start_int) = \ smooth(mod_el, mod_dt, obs_el, obs_dt) # speed (mod_sp_int, obs_sp_int, step_int, start_int) = \ smooth(mod_spd, mod_dt, obs_spd, obs_dt) # direction (mod_dr_int, obs_dr_int, step_int, start_int) = \ smooth(mod_dir, mod_dt, obs_dir, obs_dt) # u velocity (mod_u_int, obs_u_int, step_int, start_int) = \ smooth(mod_u, mod_dt, obs_u, obs_dt) # v velocity (mod_v_int, obs_v_int, step_int, start_int) = \ smooth(mod_v, mod_dt, obs_v, obs_dt) # velocity i.e. signed speed (mod_ve_int, obs_ve_int, step_int, start_int) = \ smooth(mod_spd * np.sign(mod_v), mod_dt, obs_spd * np.sign(obs_v), obs_dt) ''' # separate into ebb and flow mod_dir_n = get_DirFromN(mod_u_int, mod_v_int) obs_dir_n = get_DirFromN(obs_u_int, mod_v_int) mod_signed_s, mod_PA = sign_speed(mod_u_int, mod_v_int, mod_sp_int, mod_dr_int, 0) obs_signed_s, obs_PA = sign_speed(obs_u_int, obs_v_int, obs_sp_int, obs_dr_int, 0) print mod_signed_s[:20], mod_PA[:20] print obs_signed_s[:20], obs_PA[:20] ''' # remove directions where velocities are small MIN_VEL = 0.5 for i in np.arange(obs_sp_int.size): if (obs_sp_int[i] < MIN_VEL): obs_dr_int[i] = np.nan if (mod_sp_int[i] < MIN_VEL): mod_dr_int[i] = np.nan # get stats for each tidal variable elev_suite = tidalSuite(mod_el_int, obs_el_int, step_int, start_int, type='elevation', plot=plot) speed_suite = tidalSuite(mod_sp_int, obs_sp_int, step_int, start_int, type='speed', plot=plot) dir_suite = tidalSuite(mod_dr_int, obs_dr_int, step_int, start_int, type='direction', plot=plot) u_suite = tidalSuite(mod_u_int, obs_u_int, step_int, start_int, type='u velocity', plot=plot) v_suite = tidalSuite(mod_v_int, obs_v_int, step_int, start_int, type='v velocity', plot=plot) vel_suite = tidalSuite(mod_ve_int, obs_ve_int, step_int, start_int, type='velocity', plot=plot) #ebb_suite = tidalSuite(mod_ebb, obs_ebb, step_int, start_int, # type='ebb', plot=True) #flo_suite = tidalSuite(mod_flo, obs_flo, step_int, start_int, # type='flow', plot=True) # output statistics in useful format return (elev_suite, speed_suite, dir_suite, u_suite, v_suite, vel_suite)
def getData(): ''' Extracts data and stores it in a pickle file. I'll write a better comment later. ''' # filename = '/home/wesley/github/aidan-projects/grid/dngrid_0001.nc' # filename = '/home/abalzer/scratch/standard_run_directory/0.0015/output/dngrid_0001.nc' # filename = '/home/wesley/ncfiles/smallcape_force_0001.nc' # filename = '/home/abalzer/standard_run_directory/0.0015/output/dngrid_0001.nc' filename = '/array/data1/rkarsten/dncoarse_bctest/output/dn_coarse_0001.nc' data = nc.Dataset(filename, 'r') x = data.variables['x'][:] y = data.variables['y'][:] lon = data.variables['lon'][:] lat = data.variables['lat'][:] ua = data.variables['ua'] va = data.variables['va'] time = data.variables['time'][:] trinodes = data.variables['nv'][:] #h = data.variables['zeta'][:] (nodexy, uvnodexy, dt, deltat, hour, thour, TP, rho, g, period, nodell, uvnodell, trinodes) = ncdatasort(x, y, time*24*3600, trinodes, lon, lat) time = mjd2num(time) Rayleigh = np.array([1]) # adcpFilename = '/home/wesley/github/karsten/adcp/dngrid_adcp_2012.txt' # adcpFilename = '/home/wesley/github/karsten/adcp/testADCP.txt' # adcpFilename = '/home/wesleyb/github/karsten/adcp/dngrid_adcp_2012.txt' adcpFilename = '/array/home/116822s/github/karsten/acadia_dngrid_adcp_2012.txt' adcp = pd.read_csv(adcpFilename) lonlat = np.array([adcp['Longitude'], adcp['Latitude']]).T index = closest_point(lonlat, lon, lat) # set up lists for output data, grab shape values adcp_out_u, adcp_out_v = [], [] fvc_out_u, fvc_out_v = [], [] for i, ii in enumerate(index): tmp_path = adcp.iloc[i, -1] if tmp_path != 'None': tmp_adcp = pd.read_csv(tmp_path, index_col=0) adcp_size = tmp_adcp['u'].values.size adcp_out_u.append(np.zeros(adcp_size)) adcp_out_v.append(np.zeros(adcp_size)) else: adcp_out_u.append('Nothing!') adcp_out_v.append('Nothing!') fvc_out_u, fvc_out_v = np.zeros([index.size, ua[:, 0].size]), \ np.zeros([index.size, ua[:, 0].size]) adcp_start, adcp_end, adcp_step = [], [], [] # main loop, loads in data for i, ii in enumerate(index): path = adcp.iloc[i, -1] if path != 'None': ADCP = pd.read_csv(path, index_col=0) ADCP.index = pd.to_datetime(ADCP.index) adcp_out_u[i] = ADCP['u'].values adcp_out_v[i] = ADCP['v'].values adcp_start.append(ADCP.index[0].to_datetime()) adcp_end.append(ADCP.index[-1].to_datetime()) adcp_step.append(ADCP.index[1].to_datetime() - adcp_start[i]) fvc_out_u[i] = ua[:, ii] fvc_out_v[i] = va[:, ii] else: adcp_start.append('Nothing!') adcp_end.append('Nothing!') # remove all those 'Nothing's created from empty data adcp_out_u = [i for i in adcp_out_u if i != 'Nothing!'] adcp_out_v = [i for i in adcp_out_v if i != 'Nothing!'] adcp_start = [i for i in adcp_start if i != 'Nothing!'] adcp_end = [i for i in adcp_end if i != 'Nothing!'] # set up times f_start = time[0] f_end = time[-1] f_start = datetime.fromordinal(int(f_start)) + \ timedelta(days=(f_start%1)) - timedelta(days=366) f_end = datetime.fromordinal(int(f_end)) + timedelta(days=(f_end%1)) - \ timedelta(days=366) f_step = datetime.fromordinal(int(time[1])) + \ timedelta(days=(time[1]%1)) - timedelta(days=366) - f_start # put together dictionaries, ready for interpolation/smoothing adcp_dicts = [] fvc_dicts = [] for i in np.arange(len(adcp_start)): adcp = {} adcp['start'] = adcp_start[i] adcp['end'] = adcp_end[i] adcp['step'] = adcp_step[i] adcp['pts'] = np.sqrt(adcp_out_u[i]**2 + adcp_out_v[i]**2) adcp_dicts.append(adcp) fvc = {} fvc['start'] = f_start fvc['end'] = f_end fvc['step'] = f_step fvc['pts'] = np.sqrt(fvc_out_u[i]**2 + fvc_out_v[i]**2) fvc_dicts.append(fvc) # load data into file using pickle filename_1 = '/array/home/116822s/tidal_data/stats_test/ADCP_data1.pkl' out_adcp = open(filename_1, 'wb') pickle.dump(adcp_dicts, out_adcp) filename_2 = '/array/home/116822s/tidal_data/stats_test/FVCOM_data1.pkl' out_fvc = open(filename_2, 'wb') pickle.dump(fvc_dicts, out_fvc) out_adcp.close() out_fvc.close() # start getting the harmonic data for i in np.arange(len(fvc_dicts)): order = ['M2','S2','N2','K2','K1','O1','P1','Q1'] print 'Getting harmonic data for new site' coef = ut_solv(time, ua[:, ii], va[:, ii], uvnodell[ii, 1], cnstit=order, rmin=Rayleigh[0], notrend=True, method='ols', nodiagn=True, linci=True, conf_int=True, ordercnstit='frq') # create time array for output time series start = adcp_dicts[i]['start'] step = adcp_dicts[i]['step'] num_steps = adcp_dicts[i]['pts'].size series = start + np.arange(num_steps) * step for v, vv in enumerate(series): series[v] = datetime2matlabdn(vv) t = series.astype(float) # reconstruct the time series using adcp times time_series = np.asarray(ut_reconstr(t, coef)) time_series = np.sqrt(time_series[0]**2 + time_series[1]**2) # ASK WESLEY WHAT THIS RETURNS, my idea might not be correct print np.where((time_series[1] - time_series[0]) != 0) fvc_dicts[i]['start'] = start fvc_dicts[i]['end'] = adcp_dicts[i]['end'] fvc_dicts[i]['step'] = step fvc_dicts[i]['pts'] = time_series # save harmonic data filename_3 = '/array/home/116822s/tidal_data/stats_test/hindcast_1.pkl' out_hind = open(filename_3, 'wb') pickle.dump(fvc_dicts, out_hind) out_hind.close() print 'Done!'
def compareUV(data): ''' Does a comprehensive validation process between modeled and observed data on the following: Current speed Current direction Harmonic constituents (for height and speed) Outputs a list of important statistics for each variable, calculated using the TidalStats class ''' # take data from input dictionary mod_time = data['mod_time'] obs_time = data['obs_time'] print 'Loading mod timeseries' mod_u_all = data['mod_timeseries']['u'][:, :, 0] mod_v_all = data['mod_timeseries']['v'][:, :, 0] mod_el = data['mod_timeseries']['elev'] print 'Loading obs timeseries' obs_u_all = data['obs_timeseries']['u'] obs_v_all = data['obs_timeseries']['v'] obs_el = data['obs_timeseries']['elev'] v_obs_harm = data['vel_obs_harmonics'] el_mod_harm = data['elev_mod_harmonics'] el_obs_harm = data['elev_mod_harmonics'] bins = data['obs_timeseries']['bins'] sig = -data['mod_timeseries']['siglay'][:, 0] # for some reason, the siglayers are repeated within siglay # this bit of code will pick out only one of those repetitions siglay = [] for i, v in enumerate(sig): siglay.append(v) if (sig[i + 1] < v): break siglay = np.asarray(siglay) print 'siglay: {}'.format(siglay) print 'mod shape: {}'.format(mod_u_all.shape) print 'obs shape: {}'.format(obs_u_all.shape) # use depth interpolation to get a single timeseries print 'Performing depth interpolation' mod_depth = mod_el + np.mean(obs_el) (mod_u, obs_u) = depthFromSurf(mod_u_all, mod_depth, siglay, obs_u_all, obs_el, bins) (mod_v, obs_v) = depthFromSurf(mod_v_all, mod_depth, siglay, obs_v_all, obs_el, bins) print 'Depth interpolation completed' # create new coefs based on depth interpolated timeseries v_mod_harm = ut_solv(mod_time, mod_u, mod_v, data['lat'], cnstit='auto', rmin=0.95, notrend=True, method='ols', nodiagn=True, linci=True, conf_int=True) # convert times to datetime mod_dt, obs_dt = [], [] for i in mod_time: mod_dt.append(dn2dt(i)) for j in obs_time: obs_dt.append(dn2dt(j)) # put data into a useful format mod_spd = np.sqrt(mod_u**2 + mod_v**2) obs_spd = np.sqrt(obs_u**2 + obs_v**2) mod_dir = np.arctan2(mod_v, mod_u) * 180 / np.pi obs_dir = np.arctan2(obs_v, obs_u) * 180 / np.pi obs_el = obs_el - np.mean(obs_el) # check if the modeled data lines up with the observed data if (mod_time[-1] < obs_time[0] or obs_time[-1] < mod_time[0]): pred_uv = ut_reconstr(obs_time, v_mod_harm) pred_uv = np.asarray(pred_uv) pred_h = ut_reconstr(obs_time, el_mod_harm) pred_h = np.asarray(pred_h) # redo speed and direction and set interpolated variables mod_sp_int = np.sqrt(pred_uv[0]**2 + pred_uv[1]**2) mod_ve_int = mod_sp_int * np.sign(pred_uv[1]) mod_dr_int = np.arctan2(pred_uv[1], pred_uv[0]) * 180 / np.pi mod_el_int = pred_h[0] mod_u_int = pred_uv[0] mod_v_int = pred_uv[1] obs_sp_int = obs_spd obs_ve_int = obs_spd * np.sign(obs_v) obs_dr_int = obs_dir obs_el_int = obs_el obs_u_int = obs_u obs_v_int = obs_v step_int = obs_dt[1] - obs_dt[0] start_int = obs_dt[0] else: # interpolate the data onto a common time step for each data type # elevation (mod_el_int, obs_el_int, step_int, start_int) = \ smooth(mod_el, mod_dt, obs_el, obs_dt) # speed (mod_sp_int, obs_sp_int, step_int, start_int) = \ smooth(mod_spd, mod_dt, obs_spd, obs_dt) # direction (mod_dr_int, obs_dr_int, step_int, start_int) = \ smooth(mod_dir, mod_dt, obs_dir, obs_dt) # u velocity (mod_u_int, obs_u_int, step_int, start_int) = \ smooth(mod_u, mod_dt, obs_u, obs_dt) # v velocity (mod_v_int, obs_v_int, step_int, start_int) = \ smooth(mod_v, mod_dt, obs_v, obs_dt) # velocity i.e. signed speed (mod_ve_int, obs_ve_int, step_int, start_int) = \ smooth(mod_spd * np.sign(mod_v), mod_dt, obs_spd * np.sign(obs_v), obs_dt) ''' # separate into ebb and flow mod_dir_n = get_DirFromN(mod_u_int, mod_v_int) obs_dir_n = get_DirFromN(obs_u_int, mod_v_int) mod_signed_s, mod_PA = sign_speed(mod_u_int, mod_v_int, mod_sp_int, mod_dr_int, 0) obs_signed_s, obs_PA = sign_speed(obs_u_int, obs_v_int, obs_sp_int, obs_dr_int, 0) print mod_signed_s[:20], mod_PA[:20] print obs_signed_s[:20], obs_PA[:20] ''' # remove directions where velocities are small MIN_VEL = 0.5 for i in np.arange(obs_sp_int.size): if (obs_sp_int[i] < MIN_VEL): obs_dr_int[i] = np.nan if (mod_sp_int[i] < MIN_VEL): mod_dr_int[i] = np.nan # get stats for each tidal variable elev_suite = tidalSuite(mod_el_int, obs_el_int, step_int, start_int, type='elevation', plot=True) speed_suite = tidalSuite(mod_sp_int, obs_sp_int, step_int, start_int, type='speed', plot=True) dir_suite = tidalSuite(mod_dr_int, obs_dr_int, step_int, start_int, type='direction', plot=False) u_suite = tidalSuite(mod_u_int, obs_u_int, step_int, start_int, type='u velocity', plot=False) v_suite = tidalSuite(mod_v_int, obs_v_int, step_int, start_int, type='v velocity', plot=False) vel_suite = tidalSuite(mod_ve_int, obs_ve_int, step_int, start_int, type='velocity', plot=False) #ebb_suite = tidalSuite(mod_ebb, obs_ebb, step_int, start_int, # type='ebb', plot=True) #flo_suite = tidalSuite(mod_flo, obs_flo, step_int, start_int, # type='flow', plot=True) # output statistics in useful format return (elev_suite, speed_suite, dir_suite, u_suite, v_suite, vel_suite)