Convert NECOFS (FVCOM) MassBay ocean model to GNOME format NetCDF

This script calls routines from the utools library by Amy MacFadyen (NOAA ERL) to convert FVCOM datasets to GNOME compabible format for particle tracking. GNOME is available here: http://response.restoration.noaa.gov/oil-and-chemical-spills/oil-spills/response-tools/gnome.html. This script could be modified to read other FVCOM data sources very easily, but currently it requires a boundary file unique to a particular grid as input. From Amy's e-mail, it's not yet possible to create automatically in this script. Here we are reading an archive of NECOFS MassBay Forecast data using a boundary file that Amy provided.

To create a gnome dataset for downloading, modify the time values below, and then when the script is completed, download the data using this link:
http://geoport.whoi.edu/thredds/fileServer/usgs/data2/notebook/MassBay_depave.nc
Note that a week of data is about 220MB, so you probably don't want to specify the entire range.

You can watch the video below for how to use this script and use the results in GNOME, although for legibility of text you may prefer to watch in HD here: http://www.youtube.com/v/qZhLcm_xspc


In [29]:
from IPython.lib.display import YouTubeVideo
YouTubeVideo('qZhLcm_xspc')


Out[29]:

In [16]:
import utools
import netCDF4
import datetime as dt

In [17]:
data_url = 'http://www.smast.umassd.edu:8080/thredds/dodsC/fvcom/archives/necofs_mb'
bndry_file = 'MassB.bry'

nc = netCDF4.Dataset(data_url)

In [18]:
print nc.variables['ua']


<type 'netCDF4.Variable'>
float32 ua(u'time', u'nele')
    long_name: Vertically Averaged x-velocity
    units: meters s-1
    grid: fvcom_grid
    type: data
    coordinates: time latc lonc
    mesh: nv
    location: face
unlimited dimensions = ()
current size = (8352, 165095)


In [19]:
time_var = nc.variables['time']
dtime = netCDF4.num2date(time_var[:],time_var.units)
print 'Dataset start time: %s' % dtime[0]
print 'Dataset stop time: %s' % dtime[-1]


Dataset start time: 2011-01-18 00:00:00
Dataset stop time: 2011-12-31 22:58:08

In [20]:
# modify these time values:
start = dt.datetime(2011,7,10,0,0,0)
stop = dt.datetime(2011,7,17,0,0,0)
istart = netCDF4.date2index(start,time_var,select='nearest')
istop = netCDF4.date2index(stop,time_var,select='nearest')
print istart,istop


4152 4320

In [21]:
# lets see what variables are available
nc.variables.keys()


Out[21]:
[u'nprocs',
 u'partition',
 u'x',
 u'y',
 u'lon',
 u'lat',
 u'xc',
 u'yc',
 u'lonc',
 u'latc',
 u'siglay',
 u'siglev',
 u'h',
 u'nv',
 u'nbe',
 u'ntsn',
 u'nbsn',
 u'ntve',
 u'nbve',
 u'a1u',
 u'a2u',
 u'aw0',
 u'awx',
 u'awy',
 u'art2',
 u'art1',
 u'iint',
 u'time',
 u'Itime',
 u'Itime2',
 u'Times',
 u'zeta',
 u'file_date',
 u'u',
 u'v',
 u'omega',
 u'ww',
 u'ua',
 u'va',
 u'temp',
 u'salinity',
 u'km',
 u'kh',
 u'kq',
 u'q2',
 u'q2l',
 u'l',
 u'wet_nodes',
 u'wet_cells',
 u'wet_nodes_prev_int',
 u'wet_cells_prev_int',
 u'wet_cells_prev_ext']

In [22]:
# Let's take a look at a variable
print nc.variables['ua']


<type 'netCDF4.Variable'>
float32 ua(u'time', u'nele')
    long_name: Vertically Averaged x-velocity
    units: meters s-1
    grid: fvcom_grid
    type: data
    coordinates: time latc lonc
    mesh: nv
    location: face
unlimited dimensions = ()
current size = (8352, 165095)


In [23]:
# Use a mapping of FVCOM variable names to common names so that the class methods can also
#work with SELFE and ADCIRC which have different var names
#This seemed easier than finding them by CF long_names etc
var_map = { 'longitude':'lon', \
            'latitude':'lat', \
            'time':'time', \
            'u_velocity':'ua', \
            'v_velocity':'va', \
            'nodes_surrounding_ele':'nv',\
            'eles_surrounding_ele':'nbe',\
          }  

necofs = utools.ugrid(data_url)

In [24]:
print 'Downloading data'
necofs.get_data(var_map,tindex=[istart,istop,1]) # get all time steps in range
#necofs.get_data(var_map) #All time steps in file


Downloading data

In [25]:
necofs.adjust_time() #GNOME can't handle pre 1980 start dates (in units)

In [26]:
necofs.get_bndry(bndry_file) 
#This file was pre-generated for this grid (somewhat manually as open water/land boundaries
#are not specified in the model output

In [27]:
necofs.atts['nbe']['order'] = 'cw'
#GNOME needs to know whether the elements are ordered clockwise (FVCOM) or counter-clockwise (SELFE)

In [28]:
print 'Writing to GNOME file'
necofs.write_unstruc_grid('MassBay_depave.nc')


Writing to GNOME file