Testing Glider DAC access in Python

This is a url from Kerfooot's TDS server, using the multidimensional NetCDF datasets created by a private ERDDAP instance. These multidimensonal datasets are also available from ERDDAP, along with a flattened NetCDF representation and a ragged NetCDF representation.

The glider ERDDAP is here: http://erddap.marine.rutgers.edu/erddap

The glider TDS is here: http://tds.marine.rutgers.edu:8080/thredds/catalog/cool/glider/all/catalog.html


In [1]:
import iris

url = 'http://tds.marine.rutgers.edu:8080/thredds/dodsC/cool/glider/all/ru22-20130924T2010.ncCFMA.nc3.nc'
cubes = iris.load_raw(url)

print(cubes)


0: longitude Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
1: CTD Metadata / (1)                  (-- : 1; -- : 3294; -- : 680)
2: Profile ID / (unknown)              (-- : 1; -- : 3294)
3: longitude / (degrees)               (-- : 1; -- : 3294; -- : 680)
4: time / (seconds since 1970-01-01T00:00:00Z) (-- : 1; -- : 3294; -- : 680)
5: latitude / (degrees)                (-- : 1; -- : 3294; -- : 680)
6: sea_water_electrical_conductivity / (S m-1) (-- : 1; -- : 3294; -- : 680)
7: sea_water_temperature / (Celsius)   (-- : 1; -- : 3294; -- : 680)
8: sea_water_density / (kg m-3)        (-- : 1; -- : 3294; -- : 680)
9: Trajectory Name / (no_unit)         (-- : 1; -- : 18)
10: lat_uv Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
11: Platform Metadata / (1)             (-- : 1; -- : 3294; -- : 680)
12: lon_uv Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
13: u Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
14: WMO ID / (no_unit)                  (-- : 1; -- : 7)
15: sea_water_pressure / (dbar)         (-- : 1; -- : 3294; -- : 680)
16: precise_time Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
17: precise_lon Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
18: sea_water_salinity / (1e-3)         (-- : 1; -- : 3294; -- : 680)
19: time_uv Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
20: lat Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
21: eastward_sea_water_velocity / (m s-1) (-- : 1; -- : 3294)
22: v Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
23: northward_sea_water_velocity / (m s-1) (-- : 1; -- : 3294)
24: latitude Variable Quality Flag / (unknown) (-- : 1; -- : 3294; -- : 680)
/home/filipe/miniconda/envs/ioos/lib/python2.7/site-packages/iris/fileformats/cf.py:269: UserWarning: Missing CF-netCDF ancillary data variable u'lat_qc', referenced by netCDF variable u'precise_lat'
  warnings.warn(message % (name, nc_var_name))
/home/filipe/miniconda/envs/ioos/lib/python2.7/site-packages/iris/fileformats/cf.py:269: UserWarning: Missing CF-netCDF ancillary data variable u'lon_qc', referenced by netCDF variable u'precise_lon'
  warnings.warn(message % (name, nc_var_name))

In [2]:
cube = cubes.extract('sea_water_temperature')[0]  #<- it always returns a list!
print(cube)


sea_water_temperature / (Celsius)   (-- : 1; -- : 3294; -- : 680)
     Auxiliary coordinates:
          latitude                      x       x          -
          longitude                     x       x          -
          time                          x       x          -
          depth                         x       x          x
     Attributes:
          Conventions: Unidata Dataset Discovery v1.0, COARDS, CF-1.6
          Easternmost_Easting: -74.2846128922
          Metadata_Conventions: Unidata Dataset Discovery v1.0, COARDS, CF-1.6
          Northernmost_Northing: 37.7880349112
          Southernmost_Northing: 37.0371716345
          Westernmost_Easting: -75.5659652921
          _ChunkSize: 1
          acknowledgment: This deployment supported by NOAA U.S. IOOS
          actual_range: [  9.8394  23.0101]
          cdm_data_type: TrajectoryProfile
          cdm_profile_variables: time_uv,lat_uv,lon_uv,u,v,profile_id,time,latitude,longitude
          cdm_trajectory_variables: trajectory,wmo_id
          colorBarMaximum: 32.0
          colorBarMinimum: 0.0
          comment: Glider operatored by the Rutgers University Coastal Ocean Observation Lab,...
          contributor_name: Scott Glenn, Oscar Schofield, Josh Kohut, David Aragon, Tina Haskins, Chip...
          contributor_role: Principal Investigator, Principal Investigator, Principal Investigator,...
          creator_email: kerfoot@marine.rutgers.edu
          creator_name: John Kerfoot
          creator_url: http://rucool.marine.rutgers.edu
          date_created: 2014-10-03T15:53:28Z
          date_issued: 2014-10-03T15:53:28Z
          defaultDataQuery: &trajectory=ru22-20130924T2010
          defaultGraphQuery: longitude,latitude,time&.draw=linesAndMarkers&.marker=2|5&.color=0xFFF...
          featureType: TrajectoryProfile
          format_version: IOOS_Glider_NetCDF_v2.0.nc
          geospatial_lat_max: 37.7880349112
          geospatial_lat_min: 37.0371716345
          geospatial_lat_units: degrees_north
          geospatial_lon_max: -74.2846128922
          geospatial_lon_min: -75.5659652921
          geospatial_lon_units: degrees_east
          geospatial_vertical_max: 91.53
          geospatial_vertical_min: 1.0
          geospatial_vertical_positive: down
          geospatial_vertical_units: m
          history: 2014-10-03T15:53:28Z /home/kerfoot/slocum/matlab/spt/export/nc/IOOS/DAC/writeIoosGliderFlatNc.m
2014-10-11T14:34:46Z...
          id: ru22-20130924T2010_f070_8f49_1646
          infoUrl: http://rucool.marine.rutgers.edu
          institution: Rutgers University
          instrument: instrument_ctd
          ioos_category: Temperature
          keywords: AUVS > Autonomous Underwater Vehicles, Oceans > Ocean Pressure > Water...
          keywords_vocabulary: GCMD Science Keywords
          license: This data may be redistributed and used without restriction.  Data provided...
          naming_authority: edu.rutgers.marine
          observation_type: measured
          platform: platform
          platform_type: Slocum Glider
          processing_level: Timestamp and gps positions checked for validity.
          project: MARACOOS
          publisher_email: kerfoot@marine.rutgers.edu
          publisher_name: John Kerfoot
          publisher_url: http://rucool.marine.rutgers.edu
          sea_name: Mid-Atlantic Bight
          source: Observational data from a profiling glider
          sourceUrl: (local files)
          standard_name_vocabulary: CF-v25
          subsetVariables: trajectory,wmo_id,time_uv,lat_uv,lon_uv,u,v,profile_id,time,latitude,l...
          summary: U.S. IOOS Mid-Atlantic Regional Consortium of Ocean Observing Systems (MARACOOS)...
          time_coverage_end: 2013-10-17T00:19:33Z
          time_coverage_start: 2013-09-24T20:18:47Z
          title: ru22-20130924T2010

In [3]:
import numpy as np
import numpy.ma as ma
import seawater as sw
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

%matplotlib inline


def plot_glider(cube, mask_topo=False, track_inset=False, **kw):
    """Plot glider cube."""
    cmap = kw.pop('cmap', plt.cm.rainbow)
    
    lon = cube.coord(axis='X').points.squeeze()
    lat = cube.coord(axis='Y').points.squeeze()
    z = cube.coord(axis='Z').points.squeeze()
    data = ma.masked_invalid(cube.data.squeeze())
    t = cube.coord(axis='T')
    t = t.units.num2date(t.points.squeeze())
    
    dist, pha = sw.dist(lat, lon, units='km')
    dist = np.r_[0, np.cumsum(dist)]
    
    dist, z = np.broadcast_arrays(dist[..., None], z)

    try:
        z_range = cube.coord(axis='Z').attributes['actual_range']
    except KeyError:
        z_range = z.min(), z.max()
    try:
        data_range = cube.attributes['actual_range']
    except KeyError:        
        data_range = data.min(), data.max()
    
    condition = np.logical_and(data >= data_range[0], data <= data_range[1])
    data = ma.masked_where(~condition, data)
    
    condition = np.logical_and(z >= z_range[0], z <= z_range[1])
    z = ma.masked_where(~condition, z)

    fig, ax = plt.subplots(figsize=(9, 3.75))
    cs = ax.pcolor(dist, z, data, cmap=cmap, snap=True, **kw)
    if mask_topo:
        h = z.max(axis=1)
        x = dist[:, 0]
        ax.plot(x, h, color='black', linewidth='0.5', zorder=3)
        ax.fill_between(x, h, y2=h.max(), color='0.9', zorder=3)
    ax.invert_yaxis()
    ax.set_title('Glider track from {} to {}'.format(t[0], t[-1]))
    fig.tight_layout()
    
    if track_inset:
        axin = inset_axes(ax, width="25%", height="30%", loc=4)
        axin.plot(lon, lat, 'k.')
        start, end = (lon[0], lat[0]), (lon[-1], lat[-1])
        kw = dict(marker='o', linestyle='none')
        axin.plot(*start, color='g', **kw)
        axin.plot(*end, color='r', **kw)
        axin.axis('off')
    return fig, ax, cs

In [4]:
fig, ax, cs = plot_glider(cube, mask_topo=False, track_inset=True)
fig, ax, cs = plot_glider(cube, mask_topo=True)