def test_timestamp_index_error(nc_dataset): """timestamp returns expected Arrow instance """ nc_dataset.createDimension('time_counter') time_counter = nc_dataset.createVariable('time_counter', float, ('time_counter', )) time_counter.time_origin = '2002-OCT-26 00:00:00' time_counter[:] = np.array([8.5 * 60 * 60]) with pytest.raises(IndexError): nc_tools.timestamp(nc_dataset, 1)
def _prep_plot_data(grid_T_hr, timezone, tidal_predictions): results_t_start, results_t_end = nc_tools.timestamp(grid_T_hr, (0, -1)) ttide = shared.get_tides("Point Atkinson", tidal_predictions) ttide.time = ttide.time.dt.tz_convert(pytz.timezone(timezone)) plot_data = namedtuple("PlotData", "results_t_start, results_t_end, ttide") return plot_data(results_t_start.to(timezone), results_t_end.to(timezone), ttide)
def test_timestamp_value(nc_dataset): """timestamp returns expected Arrow instance """ nc_dataset.createDimension('time_counter') time_counter = nc_dataset.createVariable('time_counter', float, ('time_counter', )) time_counter.time_origin = '2002-OCT-26 00:00:00' time_counter[:] = np.array([8.5 * 60 * 60]) timestamp = nc_tools.timestamp(nc_dataset, 0) assert timestamp == arrow.get(2002, 10, 26, 8, 30, 0)
def _prep_plot_data( place, grid_T_hr, grids_15m, bathy, timezone, weather_path, tidal_predictions, ): ssh_hr = grid_T_hr.variables['sossheig'] time_ssh_hr = nc_tools.timestamp( grid_T_hr, range(grid_T_hr.variables['time_counter'].size)) try: j, i = places.PLACES[place]['NEMO grid ji'] except KeyError as e: raise KeyError(f'place name or info key not found in ' f'salishsea_tools.places.PLACES: {e}') itime_max_ssh = np.argmax(ssh_hr[:, j, i]) time_max_ssh_hr = time_ssh_hr[itime_max_ssh] ssh_15m_ts = nc_tools.ssh_timeseries_at_point(grids_15m[place], 0, 0, datetimes=True) ttide = shared.get_tides(place, tidal_predictions) ssh_corr = shared.correct_model_ssh(ssh_15m_ts.ssh, ssh_15m_ts.time, ttide) max_ssh_15m, time_max_ssh_15m = shared.find_ssh_max( place, ssh_15m_ts, ttide) tides_15m = shared.interp_to_model_time(ssh_15m_ts.time, ttide.pred_all, ttide.time) residual = ssh_corr - tides_15m max_ssh_residual = residual[ssh_15m_ts.time == time_max_ssh_15m][0] wind_4h_avg = wind_tools.calc_wind_avg_at_point( arrow.get(time_max_ssh_15m), weather_path, places.PLACES[place]['wind grid ji'], avg_hrs=-4) wind_4h_avg = wind_tools.wind_speed_dir(*wind_4h_avg) plot_data = namedtuple( 'PlotData', 'ssh_max_field, time_max_ssh_hr, ssh_15m_ts, ssh_corr, ' 'max_ssh_15m, time_max_ssh_15m, residual, max_ssh_residual, ' 'wind_4h_avg, ' 'ttide, bathy') return plot_data( ssh_max_field=ssh_hr[itime_max_ssh], time_max_ssh_hr=time_max_ssh_hr.to(timezone), ssh_15m_ts=ssh_15m_ts, ssh_corr=ssh_corr, max_ssh_15m=max_ssh_15m - places.PLACES[place]['mean sea lvl'], time_max_ssh_15m=arrow.get(time_max_ssh_15m).to(timezone), residual=residual, max_ssh_residual=max_ssh_residual, wind_4h_avg=wind_4h_avg, ttide=ttide, bathy=bathy, )
def combine_files(files, var, kss, jss, iss): """Returns the value of the variable entered over multiple files covering a certain period of time at a set of grid coordinates. :arg files: Multiple result files in chronological order. :type files: list :arg var: Name of variable (sossheig = sea surface height, vosaline = salinity, votemper = temperature, vozocrtx = Velocity U-component, vomecrty = Velocity V-component). :type var: string :arg kss: list of model depth levels (<=39) 'None' if depth is not applicable (example sea surface height). :type kss: integer or string :arg jss: list of (y) indices of location (<=897). :type jss: list of integers :arg iss: list of (x) indices of location (<=397). :type iss: list of integers :returns: var_ary, time - array of model results and time. """ time = np.array([]) var_list = [] for f in files: with nc.Dataset(f) as G: if kss == 'None': try: # for variavles with no depht like ssh var_tmp = G.variables[var][..., jss, iss] except IndexError: # for variables with depth var_tmp = G.variables[var][:, :, jss, iss] else: var_tmp = G.variables[var][..., kss, jss, iss] var_list.append(var_tmp) t = nc_tools.timestamp(G, np.arange(var_tmp.shape[0])) try: for ind in range(len(t)): t[ind] = t[ind].datetime except TypeError: t = t.datetime time = np.append(time, t) var_ary = np.concatenate(var_list, axis=0) return var_ary, time
def get_model_time_variables(grid_T): """Return start time, end time, and the time counter values from a NEMO tracer results dataset. :arg grid_T: Tracer results dataset from NEMO. :type grid_T: :py:class:`netCDF4.Dataset` :returns: dataset start time, dataset end time, and array of output times all as datetime objects. """ time = nc_tools.timestamp(grid_T, range(grid_T.variables["time_counter"].size)) time = np.array([t.datetime for t in time]) return time[0], time[-1], time
def test_timestamp_value_list(nc_dataset): """timestamp returns expected list of Arrow instances """ nc_dataset.createDimension('time_counter') time_counter = nc_dataset.createVariable('time_counter', float, ('time_counter', )) time_counter.time_origin = '2002-OCT-26 00:00:00' time_counter[:] = np.array([0.5, 1.5]) * 60 * 60 timestamp = nc_tools.timestamp(nc_dataset, (0, 1)) expected = [ arrow.get(2002, 10, 26, 0, 30, 0), arrow.get(2002, 10, 26, 1, 30, 0), ] assert timestamp == expected
def _prep_plot_data(grid_T_hr): si, ei = 200, 610 sj, ej = 20, 370 lons = grid_T_hr.variables["nav_lon"][si:ei, sj:ej] lats = grid_T_hr.variables["nav_lat"][si:ei, sj:ej] model_depth_level = 1 # 1.5 m ## TODO: model time step for salinity contour map should be calculated from ## ferry route time model_time_step = 3 # 02:30 UTC sal_hr = grid_T_hr.variables["vosaline"] ## TODO: Use mesh mask instead of 0 for masking sal_masked = np.ma.masked_values( sal_hr[model_time_step, model_depth_level, si:ei, sj:ej], 0) timestamped_sal = namedtuple("timestamped_sal", "salinity, timestamp") sal_model = timestamped_sal(teos_tools.psu_teos(sal_masked), nc_tools.timestamp(grid_T_hr, model_time_step)) return lons, lats, sal_model, None
def plot_vel_NE_gridded(station, grid, figsize=(14, 10)): """Plots the hourly averaged North/South and East/West velocities at a chosen VENUS node station using data that is calculated every 15 minutes. :arg station: Name of the station ('East' or 'Central') :type station: string :arg grid: Quarter-hourly velocity and tracer results dataset from NEMO. :type grid: :class:`netCDF4.Dataset` :arg figsize: Figure size (width, height) in inches or 'default'. :type figsize: 2-tuple :returns: matplotlib figure object instance (fig). """ u_u = grid.variables['vozocrtx'] v_v = grid.variables['vomecrty'] w_w = grid.variables['vovecrtz'] dep_t = grid.variables['depthv'] dep_w = grid.variables['depthw'] t = grid.variables['time_counter'] dt = (t[1]-t[0])/3600. maxt = dt*t.shape[0] t_axis = np.arange(0, maxt, dt) u_E, v_N = unstag_rot(u_u, v_v) u_E = u_E[..., 0, 0] v_N = v_N[..., 0, 0] fig, (axu, axv, axw) = plt.subplots(3, 1, figsize=figsize, sharex=True) fig.patch.set_facecolor('#2B3E50') max_array = np.maximum(abs(v_N), abs(u_E)) max_speed = np.amax(max_array) vmax = max_speed vmin = - max_speed step = 0.03 # viz_tools.set_aspect(axu) timestamp = nc_tools.timestamp(grid, 0) cmap = plt.get_cmap('jet') dep_s = SITES['VENUS'][station]['depth'] axu.invert_yaxis() mesh = axu.contourf( t_axis, dep_t[:], u_E.transpose(), np.arange(vmin, vmax, step), cmap=cmap) cbar = fig.colorbar(mesh, ax=axu) axu.set_ylim([dep_s, 0]) axu.set_xlim([0, maxt]) axu.set_ylabel('Depth [m]', **axis_font) figures.axis_colors(axu, 'white') axu.set_title( f'East/West Velocities at VENUS {station} on ' f'{timestamp.format("DD-MMM-YYYY")}', **title_font) plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w') cbar.set_label('[m/s]', **axis_font) axv.invert_yaxis() mesh = axv.contourf( t_axis, dep_t[:], v_N.transpose(), np.arange(vmin, vmax, step), cmap=cmap) cbar = fig.colorbar(mesh, ax=axv) axv.set_ylim([dep_s, 0]) axv.set_xlim([0, maxt]) axv.set_ylabel('Depth [m]', **axis_font) figures.axis_colors(axv, 'white') axv.set_title( f'North/South Velocities at VENUS {station} on ' f'{timestamp.format("DD-MMM-YYYY")}', **title_font) plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w') cbar.set_label('[m/s]', **axis_font) axw.invert_yaxis() mesh = axw.contourf( t_axis, dep_w[:], w_w[:, :, 1, 1].transpose(), np.arange(vmin/70, vmax/70, step/80), cmap=cmap) cbar = fig.colorbar(mesh, ax=axw) axw.set_ylim([dep_s, 0]) axw.set_xlim([0, maxt]) axw.set_xlabel('Time [h]', **axis_font) axw.set_ylabel('Depth [m]', **axis_font) figures.axis_colors(axw, 'white') axw.set_title( f'Vertical Velocities at VENUS {station} on ' f'{timestamp.format("DD-MMM-YYYY")}', **title_font) plt.setp(plt.getp(cbar.ax.axes, 'yticklabels'), color='w') cbar.set_label('[m/s]', **axis_font) return fig
def _prep_plot_data( place, grid_T_hr, dev_grid_T_hr, timezone, mesh_mask, dev_mesh_mask, ): try: j, i = places.PLACES[place]['NEMO grid ji'] except KeyError as e: raise KeyError( 'place name or info key not found in ' 'salishsea_tools.places.PLACES: {e}') node_depth = places.PLACES[place]['depth'] station_code = places.PLACES[place]['ONC stationCode'] # Production model results model_time = nc_tools.timestamp( grid_T_hr, range(grid_T_hr.variables['time_counter'].size)) try: # NEMO-3.4 mesh mask gdept = mesh_mask.variables['gdept'] except KeyError: # NEMO-3.6 mesh mask gdept = mesh_mask.variables['gdept_0'] tracer_depths = gdept[..., j, i][0] tracer_mask = mesh_mask.variables['tmask'][..., j, i][0] try: # NEMO-3.4 mesh mask gdepw = mesh_mask.variables['gdepw'] except KeyError: # NEMO-3.6 mesh mask gdepw = mesh_mask.variables['gdepw_0'] w_depths = gdepw[..., j, i][0] salinity_profiles = grid_T_hr.variables['vosaline'][..., j, i] temperature_profiles = grid_T_hr.variables['votemper'][..., j, i] model_salinity_ts = _calc_results_time_series( salinity_profiles, model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths) model_temperature_ts = _calc_results_time_series( temperature_profiles, model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths) # Development model results dev_model_time = nc_tools.timestamp( dev_grid_T_hr, range(grid_T_hr.variables['time_counter'].size)) tracer_depths = dev_mesh_mask.variables['gdept_0'][..., j, i][0] tracer_mask = dev_mesh_mask.variables['tmask'][..., j, i][0] w_depths = dev_mesh_mask.variables['gdepw_0'][..., j, i][0] salinity_profiles = dev_grid_T_hr.variables['vosaline'][..., j, i] temperature_profiles = dev_grid_T_hr.variables['votemper'][..., j, i] dev_model_salinity_ts = _calc_results_time_series( salinity_profiles, dev_model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths) dev_model_temperature_ts = _calc_results_time_series( temperature_profiles, dev_model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths) # Observations onc_data = data_tools.get_onc_data( 'scalardata', 'getByStation', os.environ['ONC_USER_TOKEN'], station=station_code, deviceCategory='CTD', sensors='salinity,temperature', dateFrom=data_tools.onc_datetime(model_time[0], 'utc'), dateTo=data_tools.onc_datetime(model_time[-1], 'utc')) plot_data = namedtuple( 'PlotData', 'model_salinity_ts, model_temperature_ts, ' 'dev_model_salinity_ts, dev_model_temperature_ts, ' 'ctd_data') return plot_data( model_salinity_ts=model_salinity_ts, model_temperature_ts=model_temperature_ts, dev_model_salinity_ts=dev_model_salinity_ts, dev_model_temperature_ts=dev_model_temperature_ts, ctd_data=data_tools.onc_json_to_dataset(onc_data), )
def _prep_plot_data( place, grid_T_hr, dev_grid_T_hr, timezone, mesh_mask, dev_mesh_mask ): try: j, i = places.PLACES[place]["NEMO grid ji"] except KeyError as e: raise KeyError( "place name or info key not found in salishsea_tools.places.PLACES: {e}" ) node_depth = places.PLACES[place]["depth"] station_code = places.PLACES[place]["ONC stationCode"] # Production model results model_time = nc_tools.timestamp( grid_T_hr, range(grid_T_hr.variables["time_counter"].size) ) try: # NEMO-3.4 mesh mask gdept = mesh_mask.variables["gdept"] except KeyError: # NEMO-3.6 mesh mask gdept = mesh_mask.variables["gdept_0"] tracer_depths = gdept[..., j, i][0] tracer_mask = mesh_mask.variables["tmask"][..., j, i][0] try: # NEMO-3.4 mesh mask gdepw = mesh_mask.variables["gdepw"] except KeyError: # NEMO-3.6 mesh mask gdepw = mesh_mask.variables["gdepw_0"] w_depths = gdepw[..., j, i][0] salinity_profiles = grid_T_hr.variables["vosaline"][..., j, i] temperature_profiles = grid_T_hr.variables["votemper"][..., j, i] model_salinity_ts = _calc_results_time_series( salinity_profiles, model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths, ) model_temperature_ts = _calc_results_time_series( temperature_profiles, model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths, ) # Development model results dev_model_time = nc_tools.timestamp( dev_grid_T_hr, range(grid_T_hr.variables["time_counter"].size) ) tracer_depths = dev_mesh_mask.variables["gdept_0"][..., j, i][0] tracer_mask = dev_mesh_mask.variables["tmask"][..., j, i][0] w_depths = dev_mesh_mask.variables["gdepw_0"][..., j, i][0] salinity_profiles = dev_grid_T_hr.variables["vosaline"][..., j, i] temperature_profiles = dev_grid_T_hr.variables["votemper"][..., j, i] dev_model_salinity_ts = _calc_results_time_series( salinity_profiles, dev_model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths, ) dev_model_temperature_ts = _calc_results_time_series( temperature_profiles, dev_model_time, node_depth, timezone, tracer_depths, tracer_mask, w_depths, ) # Observations onc_data = data_tools.get_onc_data( "scalardata", "getByStation", os.environ["ONC_USER_TOKEN"], station=station_code, deviceCategory="CTD", sensors="salinity,temperature", dateFrom=data_tools.onc_datetime(model_time[0], "utc"), dateTo=data_tools.onc_datetime(model_time[-1], "utc"), ) plot_data = namedtuple( "PlotData", "model_salinity_ts, model_temperature_ts, " "dev_model_salinity_ts, dev_model_temperature_ts, " "ctd_data", ) return plot_data( model_salinity_ts=model_salinity_ts, model_temperature_ts=model_temperature_ts, dev_model_salinity_ts=dev_model_salinity_ts, dev_model_temperature_ts=dev_model_temperature_ts, ctd_data=data_tools.onc_json_to_dataset(onc_data), )