Community Modelers NetCDF Page

NetCDF standards for data interchange between common hydrodynamic models.

Last Modified Dec. 16 2004 by Tom Gross on crclinux

SourceForge.net Logo Support This Project

This software is supported on the SOURCEFORGE project page for OceanModelersOutput
( This page and the software described were originally created at the NOAA/Coast Survey Developement Laboratory. The software is now being offered up to the Chesapeake Community Modeling Program.)

Down loadable files DOWNLOADS

Table of Contents

  • Purpose of Standard NetCDF for Models
  • Grid Specifications
  • Vertical Coordinate
  • Global Attributes
  • Time Variable
  • Variable Names
  • Units
  • Missing Values
  • Modelers NetCDF CDL file
  • Stations NetCDF
  • Writing the Files
  • 3D Grid Subroutines
  • Station Data Subroutine
  • FEM Subroutines
  • NWLON Station Data
  • Downloads
  • Matlab and NetCDF
  • Back to Table of Contents

    Purpose of Standard NetCDF for Models

    A standard output medium for the hydrodynamic models could be beneficial to both quality and ease of use for our development projects. A standard output would allow us to develop standard graphics and statistical analysis programs. The demand that each developer create custom made graphics for each model could be removed. Skill assessment tools could be a single package, guaranteeing standard quality across all models. Finally an unambiguous output file could be made available to the outside world. The model outputs could be taken by third parties and used for new applications beyond the NOAA "Safe Navigation" charge.

    NOAA's CSDL presently uses at least four different modeling systems. Each is different in various ways and all have unique output file formats. A common output format will not be the optimal solution for every model, or any model. It will be a compromise of some attributes in order to achieve a useful universal standard. We propose that a core set of variables can be listed which will be valuable output and usable for the widest set of graphical displays. The time and location of velocity, sea level and optionally salinity and temperature are the core variables. The Modelers NetCDF file format will specify these universal variables while maintaining as much fidelity of the original model as possible. The main approximation is in the specification of a location and time for all variables. Most models use staggered grids and sometimes staggered time steps. It will be necessary to perform some degree of averaging to place all variables on a single location and time step grid.

    NetCDF is only one of dozens of "universally accepted" file formats. It is probably the most popular in the oceanographic community and is also widely used by the atmospheric modeling community. In theory it is "self describing". This means that programs written with the NetCDF library may read these files, find the names and descriptions of the included variables and pull out enough information to make meaningful graphs quickly. They are also flexible. For instance a standard NetCDF file may have extra variables and attributes added to the file, at anytime, and still be perfectly usable by graphics programs which expected the older files. Of course if the self description specifies the contents to be Speed and Direction rather than U, eastward and V, northward the universal graphics plotter may not be able to make sense of it. So we will specify some common sense names and units for the expected variables of a Modelers NetCDF file.

    Back to Table of Contents

    Grid Specifications:

    The geographic grid specification for the models is the most difficult part of creating a generalized NetCDF standard. This is simply because there are a variety of methods used to specify the computational grid of the models. It might be that we agree to sub-sample, interpolate and average the model outputs to common grid specifications. However this will introduce a level of corruption of the model results which will not be equally acceptable to all modelers or users. Therefore a certain level of flexibility must be maintained to accommodate different model formulations.

    One issue is the question of map projections. When a model runs on a grid in units of meters there must have been some sort of a mapping projection applied to go between meters and longitude, latitude. These are complicated and particular to each model. I believe our response to this should be that the NetCDF file be required to give the latitude and longitude of the grid. The x,y components of the grid in meters or kilometers may be optionally included in the NetCDF file.

    The oceanographic models usually have complicated spatial distributions of points. Therefore, unlike the atmospheric models, their grids can seldom be described with one-dimensional vectors of latitude and longitude to describe a two dimensional array of latitude, longitude pairs. The curvilinear grids (POM, ROMS, CH3D) must specify the latitude and longitude for every location in their 2-D grids. Either uniform or curvilinear grids will require a mask array to determine land and water points. The finite element models, (quoddy, adcirc, elcirc) must be specified with a one dimensional vector of latitudes and longitudes along with an element connectivity array to describe which nodes belong to each triangular mesh element (or most generally, polygonal elements of 3 or more nodes) and a boundary array which describes the nodes of the outer boundary, whether they are land or water or part of an interior island. A complication of the finite element or volume dimensions is the difference between nodal values of a parameter and elemental values, specified within the elements. This difference must be resolved by the modeler and all values reported at the nodes.

    Of the models I looked at POM, and ROMS are both Arakawa C type grids, which means that the u,v and rho variables are not specified at the same location. The conversion to the same location is a modeling issue. Provision for this is not included here. It is assumed that same sized arrays of all such parameters will be output. The display methods for these arrays would require special action. It will therefore be necessary for the modeller to perform an interpolation to place all of the variables or a computational cell at single location.

    A compromise will be made to move toward a single simple graphical output file format. All of the variables will be transformed, interpolated, rotated, averaged or whatever, to a single set of longitude, latitude locations. This is a nodal system and is not the natural grid for either finite volume or flux oriented finite difference methods where the velocities are only the normal velocity to the walls surrounding a box. The modeler may chose to also provide all parameters at the corners of their boxes, or the box centers, or a point on the walls. But the Modelers NetCDF standard will require specification at single points as well. It is hoped that this single location standard will be the easiest for graphical models and other post-processing software.

    There are still three different dimension methods for different model grids. These are the uniform, lat, lon grid, the curvilinear lat, lon grid and the finite element lat, lon mesh. The difference between the uniform and curvilinear grids is simply whether lon and lat are specified as vectors or arrays. The graphical programs will undoubtedly simply transform the vectors into arrays to become the same as the curvilinear grid. In fact it will be recommended that provision for the vector lon, lat files be dropped. Below are the examples of the other two NetCDF grids:

    //Curvilinear lat, lon grid
    dimensions: 
         nx=360;
         ny=90; 
    variables:  
          float lon(ny,nx);
          float lat(ny,nx);
          int mask(ny,nx);
          float salt(time,z,ny,nx);
    //Element based grid<
    dimensions:
          node=32400;
          nface=3;
          nele=45300;
    variables:
          float lon(node);
          float lat(node);
          int bnd(nbnd,nbi) ;
             bnd:long_name = "Boundary Segment Node List" ;
             bnd:units = "index_start_1" ;
          int ele(nele,nface);
             ele:long_name = "Horizontal Triangular Element Incidence List" ;
    	 ele:units = "index_start_1" ;
         float salt(time,z,node);
    
    Back to Table of Contents

    Vertical Coordinate

    The vertical dimension may also be somewhat controversial. The sigma coordinate models may be described by specifying the model depth, the surface displacement and the non-dimensional sigma distribution. The internal profile depths are then calculated with Z(i,j,k) = -(zeta(i,j)+depth(i,j))*sigma(k)+zeta(i,j). Where the Z coordinate ranges from the zeta value of sea surface displacement from mean sea level (=0.0) to negative the depth at the sea bed. sigma ranges 0:+1, with depth positive, sigma positive is down. Sigma=0.0 is the Sea Surface (zeta), Sigma=+1.0 is the sea bed (-depth). The signs in this calculation require the "positive" attribute be given for sigma, zeta and depth. Or the 3-D field of Z may be explicitly specified. Since these are interchangeable the recommendation is to require zeta, depth and sigma and optionally include Z. Regular z-coordinate models (ELCIRC) will not specify sigma, but must specify Zgrid, the vertical box locations.

    Index order for the Z coordinate and sigma matters. The vertical index of all 3D data will use index 1 to represent the sea bed and dimension sigma to represent the sea surface. The POM, ELCIRC and Quoddy all use the following conventions. (ECOM is the odd one out. It's modelling definations will be manipulated so that its output file agrees with the following conventions.)

    An example of all this:

    Index           1             2            3      .......      10       11 
    Sigma           1.0          0.9          0.8     .......      0.1      0.0 
    zeta=+.5 
    depth=+35.0 
                 
    Z derived   =     -(zeta + depth)*sigma +zeta   = -35.5*sigma +.5 
    Z               -35.0       -31.45       -27.90    .....      -3.05     0.5 
    
    //sigma model
    dimensions:
        sigma=11;
    variables:
        float sigma(sigma);
          
    sigma:long_name = "Stretched Vertical Coordinate" ;
           sigma:units = "sigma_level" ;
          
    sigma:positive = "down";
        float depth(ny,nx);
          
    depth:positive = "down";
        float zeta(time,ny,nx);
          
    zeta:positive = "up";
        float salt(time,sigma,ny,nx);
        float z(time,sigma,ny,nx);   //optional full z specification
    
    // z-coordinate
    dimensions:
         Zgrid=15;
    variables:
        float Zgrid(Zgrid);
          Zgrid:positive = "up";
        float depth(lat,lon);
        int mask(Zgrid,ny,nx);    //Might be necessary to be 3-D ?
        float zeta(time,ny,nx);
          
    zeta:positive = "up";
        float salt(time,Zgrid,ny,nx);
    

    PS Also note that sigma or Zgrid are "coordinate" variables. They represent both the spatial variable and the dimension with the same name. Our other spatial variables of lat and lon cannot play this role as they are spatially variable 2D arrays or scatter data.

    Back to Table of Contents

    Global Attributes:

    Global attributes are a set of variables which can be used to describe attributes of the whole NetCDF file. These will distinguish the source of the file, the model, the experiment or operational version, the grid type, vertical type and location type. While the character variables filling these can be free format, my programs require less than 40 characters. The Modelers NetCDF will require that these global variables be set:

    :file_type Describes the type of NetCDF file.
    "Station", "Full_Grid" "FEM"
    :grid_type Describes the type of grid
    "Curvilinear", "Uniform", "Triangular", "Quadralateral"
    :z_type The type of vertical spacing of the data and model
    "Sigma" "Z-coordinate"
    :model Generic name of the model
    "POM" "Quoddy5.1" "MECCA21"
    :title The description of the run. Quite variable.
    "CBOFS" "Houston Galveston" "NY NJ"
    "Mecca year long retrospective" "Quoddy barotropic MY2.5 test"

    Other standard Global attributes from the CF conventions which we use:
    :comment "More miscillaneous information. Redundant with ""experiment?""
    "spaces are allowed now thanks to len_trim() "
    :institution "NOAA/NOS/CS/CSDL/MMAP"
    :source "usually the computer name, opsea, opmarine"
    :history "original"
    :references "owner@noaa.gov"
    :related_url "http://noaa.gov/model.html"
    :creation_date = "2002-11-07 11:33:15 -00:00"

    Upon recommendations from NOAA/PMEL we have made a few changes to the Modelers NetCDF files to bring them into conformation with a subset of the COARDS standard convention. I am unsure about this but he recommends:
    :Conventions = "COARDS";
    // Cooperative Ocean/Atmosphere Research Data Services

    Back to Table of Contents

    Time Variable:

    The specification of the time must include complete information to construct full dates, indicate forecast hours and averaging periods and time offsets. The required time variable will be specified in days with a base_date array provided as an attribute. Time will be "time since" the base_date. So if time = 0.5, and base_date = 2001 01 01 00. We are specifying noon on Jan. 1, 2001. This is one day less than the usage of the common yearday which has that noon on Jan. 1 is 1.5day. That introduces a confusing question of whether to add an extra day to calculations of Julian day. A convention must be chosen and it is for "time since". In matlab this is correct:
    jday = datenum(base_date(1), base_date(2), base_date(3)+time, base_date(4));
    plottitle=["The Gregorian Day is", datestr(jday)];

    If the modeler insists upon using the yearday convention where Jan. 1 noon is 1.5 yearday then the base_date can be specified as Day Zero of Jan. This is pretty wierd, but it is understood by the matlab datenum function. Thus time=1.5, base_date= 2001 01 00 00 specifies Jan. 01 noon. ( In another interpretation 2001 01 00 00 is the same as 2000 12 31 00, the morning of the last day of the previous year.)

    Variables can sometimes be averages over a period of time. This need not be a global attribute of all the data in the file, so should not be part of the time variable attributes. Therefore data variables may be given the optional attributes of averaging_window and averaging_offset to specify the length of averaging and how its center should be described relative to "time". For instance averaging_window=1/24. averaging_offset=-.5/24. would specify an hour average over the previous hour, centered at half an hour ago. These should always be in the same units as time, which is supposed to be "days" for HydroNetCDF. In their absence the default is 0 averaging and 0 offset. ( I still haven't actually used these. )

    By including an attribute base_date we can directly access the vector of values of the date which can be used in the matlab datenum command as above. However CF conventions encode the same information into the units attribute. Apparently someone likes to unformat string data. Stupid choice, but thats a standard. So we redundantly include the information in the units attribute. The last part of that string is the UTC hour offset. In Modelers NetCDF files this will always be 0:00 as all files are UTC.

    dimensions:
     time = UNLIMITED ; // (3 currently)
    variables:
         float time(time) ;
            time:long_name = "Time" ;
            time:units = "days since 1990-1-1 0:0:0 0:00" ;
            time:base_date = 1990, 1, 1, 0 ;
         float salt(time,sigma,lat,lon);
            salt:averaging_window=1./24.;
            salt:averaging_offset=-.5/24. ;
    
    Back to Table of Contents

    Variable names

    The usual hydrodynamic variables for interchange between models do not form an excessively large set. However, agreement should be reached as to names and units so that interchange will be more easily facilitated. The Unidata web site has a list of several conventions which might be chosen: http://www.unidata.ucar.edu/packages/netcdf/conventions.html. NAVO has also provided a table of variable names and units.

    The CF convention is a product of NCAR, UK Met Office, LLNL and NOAA/PMEL (www.cgd.ucar.edu/cms/eaton/netcdf/CF-working.html). However their conventions are geared so strongly to atmospheric data that they would have us use unwieldy variable names like "eastward_sea_water_velocity" instead of "u". The CF convention seems to be geared to defining how to create names, rather than suggesting or codifying names. They especially lack in guidance on the geometry specifications, favoring esoteric generalizations.

    Nevertheless the CF-COARDS conventions are most likely the way of the future. An advantage of the CF conventions is that they allow great freedom in variable names, but they mandate, and suggest "standard_name", "units" and sometimes "long_name". We will implment the CF standards as they come on line. This powerpoint is a useful introduction to CF PPT

    Another convention (also from PMEL) is the EPIC convention The epic.key file includes variable names, long_name, units and an EPIC code number. The code number is apparently used by the PMEL EPIC software to add metadata not included within the NetCDF file. The additional variable attribute, epic_code, provides this information. The key file now has 767 lines with a large amount of redundancy. For instance a new epic_code is assigned for different units. Obviously that is unnecessary with NetCDF, where the units attribute should always be specified. We are mainly interested in consistency in the variable names which are provided by the epic.key file. There are dozens of names for velocity, but they all boil down to u,v,w or U,V,W. EPIC seems to favor capitalization, which is not favored by any of the models. A snippet of the EPIC key file demonstrating the redundancy:

    320:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::measured w/r true N 
    321:V  :MERIDIONAL CURRENT (CM/S):v:cm s-1: :measured w/r true N
    322:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::relative w/r true N 
    324:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::instrument w/r true N 
    326:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::tracked w/r true N 
    330:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::measured w/r magnetic N 
    332:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::relative w/r magnetic N 
    334:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::instrument w/r magnetic N 
    336:U  :ZONAL CURRENT (CM/S)     :u:cm s-1::tracked w/r magnetic N 
    1204:w   :VerticalVelocity        :w:cm/s: :VerticalVelocity 
    1205:u   :EastwardVelocity        :u:cm/s: :EastwardVelocity 
    1206:v   :NorthwardVelocity       :v:cm/s: :NorthwardVelocity 
    4080:u  :East(m)                  :u:cm s-1:f8.2:U component (magnetic) 
    4081:v  :North(m)                 :v:cm s-1:f8.2:V component (magnetic) 
    4082:u  :East(t)                  :u:cm s-1 :f8.2:U component (true north) 
    4083:v  :North(t)                 :v:cm s-1:f8.2:V component (true North) 
    4084:u  :East(r)                  :u:cm s-1 :f8.2:U component (rotated) 
    4085:v  :North(r)                 :v:cm s-1:f8.2:V component (rotated) 
    

    Blending these conventions we can be somewhat consistent with the EPIC conventions and match existing model values. My suggestions are in this table: (in file /VariableTable.html ) The variable names for the same quantity are given for the models and for the EPIC and CF, where applicable and located. The units vary between the models and conventions, but that is a NetCDF attribute, so should not be specified. Units should conform to NetCDF standards, as outlined in CF. I have put forward variable names, long_names and units to be used in our NetCDF files. These are reasonable blends of the other standards. They might favor the simple language used by the POM/ECOM models.

    Back to Table of Contents

    Units:

    For the question of units we actually have a strong answer. Part of the UNIDATA netcdf project has been the development of software for conversion of units, e.g. kilograms to pounds. The UDUNITS package is a complete set of conversion software. These people were careful in the creation of this package and they refer back to the NIST Special Publication 811, 1995 Edition: "Guide for the Use of the International System of Units (SI)" by Barry N. Taylor. URL <http://physics.nist.gov/Divisions/Div840/SI.html>. N And ANSI/IEEE Std 260-1978: "IEEE Standard Letter Symbols for Units of Measurement". It should be understood that the "units" attribute of the netcdf variables is not a long description of the variable, it is the units which can be used for conversion purposes. For example "m/s horizontal" would not be appropriate, and we would use "m/s" only.

    The following are examples of udunits formatted specifications that can be interpreted by the utScan() function:

             10 kilogram.meters/seconds2  
             10 kg-m/sec2  
             10 kg m/s^2  
             (PI radian)2  
             degF  
             100rpm  
             geopotential meters  
             33 feet water 
    

    A unit is specified as an arbitrary product of constants and unit names raised to arbitrary integral powers. Division is indicated by a slash `/'. Multiplication is indicated by whitespace, a period `.', or a hyphen `-'. Exponentiation is indicated by an integer suffix or by the exponentiation operators `^' and `**'. Parentheses may be used for grouping and disambiguation.

    Back to Table of Contents

    Missing Values:

    An attribute can be assigned to each variable which identifies flagged values as out of range or not applicable. This would be used for missing or bad data from an observation time series. A model result really shouldn't require such a variable. The mask variable would be used to cover all values which are not assigned. However it is important to maintain coherence between the observation files and the model files and incidently maintain COARDS compliance. Every data variable (except Mask) will be given this attribute:
    vari:missing_value = -99999. ;

    The Scaled NetCDF file converts the floating values and records only integers. The conversion of -99999. will blow up the writing scheme. So the minimum integer (-32767) must be used as the missing value flag. Since missing_value does not have any special meaning to NetCDF file structure the floating point value of the missing_value can be assigned to the minimum range value for reference to remind the reader that the -99999. value had to be converted prior to writing. The -99999. value becomes nonsensical and will not appear in the scaled NetCDF file.

    Translation Method

    Universal agreement upon these variable choices may not occur. A modeler may insist upon their own nomenclature, or that of their own laboratory's standards. Or it might be preferable for a modeler to use the native NetCDF writing routines provided with the model (ROMS is very likely in this category). It is possible in those cases to translate existing NetCDF files into the Modelers nomenclature using NetCDF tools designed for the purpose. If such translation to or from Modelers file standards are done an entry in the table above should be created so that the translation maybe referred to and understood.

    Back to Table of Contents

    Modelers NetCDF CDL file:

    A NetCDF CDL file is a special format description of the dimensions, variables and attributes of a NetCDF file. The CDL is the "network Common data form Description Language" used to describe a NetCDF file. In the above descriptions of possible variable names I have been using CDL conventions. In addition to clarifying the layout of your NetCDF files it can be used to construct FORTRAN or C code to write the file. The FORTRAN code is derived using the clever NetCDF utility, ncgen, which converts a NetCDF header CDL file into useful FORTRAN code for creating and writing the NetCDF file.

    ncgen -f CSDL_netcdf_header.cdl > write_netcdf_CSDL_proto.f

    But more usefully the CDL file can be constructed from an existing NetCDF file to confirm the variables and everything in the file are what you want:

    ncdump -h csdl_pom.nc > csdl_pom.cdl

    ncdump is an extremely useful utility with many attributes. The contents of a single variable can be dumped with the -v option:

    ncdump -v time csdl_pom.nc

    See the web page tutorial for ncgen and ncdump.

    The CDL file for the example POM writer: csdl_pom.cdl
    The CDL file for the example FEM writer: csdl_fem.cdl

    Back to Table of Contents

    Stations NetCDF


    We require an additional NetCDF output file which contains higher temporal resolution at a small subset of points. This is of great value to the NOAA/CSDL models which report their water levels at particular gauge locations. The same variable names as the 3d files will be used. The dimensions and an additional attribute are necessary. Luckily these types of files are independent of grid type, but might be dependent upon the Z coordinate method. The vertical coordinate is therefore exactly as in the previous 3D files. If a single level in the vertical is desired then the dimension of sigma can be set to 1. The global attribute will distinguish this type of file as 'Stations'. Provision for an array of Place Name variables should be provided.

    An optional variable for the Station data could be the model indices used to access the stations from the full 3D data. This would contain the one or two indices to specify node or i,j. The dimension of the mesh variable must be given as 1 or 2 to allow for the two types of meshes.

    //Station File
    dimensions:
    station=10;
    sigma=15;
    meshdim=2;
    variables:
    char Place_Name(station);
    int stationij(meshdim,station);
    float lon(station);
    float lat(station);
    float depth(station);
    float sigma(sigma);
    float zeta(time,station);
    float salt(time,sigma,station);

    // global attributes:
    :grid_type = "Station" ;
    :z_type = "Sigma" ;

    A complete CDL header file for the station format is CSDL_netcdf_station_header

    Back to Table of Contents

    Writing the Files:

    Standards are an imposition on scientists unless they can make the scientist's work easier. To overcome the work hurdle, example subroutines are presented to write NetCDF files which adhere to these standards for our three major models, POM, Quoddy and ROMS. Also matlab plotting routines which use the NetCDF files will be demonstrated.

    A single subroutine to be called from the model will be edited by the modeller, write_netcdf. It will contain an included common block with all the model's variables. A controlling calling parameter, imode, will take on three values: 1 open and initialize the NetCDF file; 2 write a time step of data to NetCDF file; 3 close the NetCDF file. This will be a "wrapper" for our generalized writing program which will be written with our codified variable names, write_netcdf_CSDL. In schematic form the programs will have this structure:

    ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

    program mainmodel
    common model/Tsec,long(n,m),lati(n,m),u3d(n,m,k),v3d(n,m,k)
    ...
    common modeldim/n=30,m=50,k=10/
    call write_netcdf(1) //initialize

    do iter=1,1e6
    ..run model..
    if (mod(tsec,3600).eq.0) call write_netcdf(2)
    enddo

    call write_netcdf(3) //close
    end
    ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    subroutine write_netcdf(imode)
    common model/Tsec,long(n,m),lati(n,m),u3d(n,m,k),v3d(n,m,k) ...
    common modeldim/n=30,m=50,k=10/
    data ibasedate/1990,1,1,0/
    netcdf_file='modeloutput.nc'
    c Particular manipulation of model data to Hydro_netcdfs standards
    ....
    Day = Tsec/3600./24.
    call write_netcdf_Hydro_fem(netcdf_file,imode,n,m,k, & Day,ibasedate,long,lati,u3d,v3d,...)
    return
    end
    ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

    subroutine write_netcdf_Hydro_fem(netcdf_file,ncid,imode,...
    & time,ibasedate,lon,lat,u,v,...)
    dimension lon(*,*),lat(*,*),u(*,*,*),v(*,*,*) ....
    if imode.eq. 1
    open file
    define variables
    write lon,lat
    elseif imode.eq.2
    write time,u,v,....
    else
    close file
    end
    return
    end

    An actual example of these programs are found in maintestgrid.f. This program has a fake mainline model section and an example of the write_netcdf(imode) subroutine. The write_netcdf(imode) subroutine calls the two library routine,s write_netcdf_Hydro and write_netcdf_Hydro_scale, which are provided in Hydro_netcdfs_grid.f.

    A compilation line for these routines, which has the include and netcdf library as well as the Hydro_netcdfs_grid.f subroutines:

    f90  maintestgrid.f Hydro_netcdfs_grid.f -O -I/usr/local/include -L/usr/local/lib -lnetcdf
    Back to Table of Contents

    3D Grid Subroutines:

    The subroutine write_netcdf_HYDRO is found in Hydro_netcdfs_grid.f . This version of the program is tailored to the POM style curvilinear grid specification. Two versions are included, one which preserved "real" variable accuracy and another which uses data offsets and range scaling to write out smaller files using integers. The integer type files are only one half the size of the real type files. However they compress using gzip by up to 70%, whereas the real type files only compress by about 20%. The calling parameters of the subroutines are:

          subroutine write_netcdf_Hydro(netcdf_file,ncid,imode,
         &  globalstr,m,n,l,
         & time,ibasedate,lon,lat,mask,sigma,depth,
         & zeta,u,v,w,temp,salt,wx,wy)
    
          subroutine write_netcdf_Hydro_scale(netcdf_file,ncid,imode,
         & globalstr,m,n,l,
         & time,ibasedate,lon,lat,mask,sigma,depth,
         & zeta,u,v,w,temp,salt,wx,wy)
    
    
    
    c Inputs:
    c netcdf_file    char*80  filename for the netcdf output
    c ncid                    netcdf id; generated on initialization 
    c imode  1 for initialization, 2 for writing, 3 for closing file
    c globalstr Global Attributes.  Set in a data statement like
    c        data globalstr/
    c     &  'grid_type','z_type','model'
    c     & ,'title','comment','source',
    c     &  'institution','history','references'/
    c 
    c m     dimension of the X coordinate (Longitude)
    c n     dimension of the Y coordinate (Latitude)
    c l     dimension of vertical outputs. may be =1
    c time    time in days
    c ibasedate(4)   iyear, imonth, iday, ihour of base date (time = 0)
    c lon(m,n) ,lat(m,n)    longitude, latitude of stations
    c sigma(l)  sigma values for vertical outputs 0:-1 0 surface, -1 seabed
    c zeta(m,n)  sea surface displacement
    c u(m,n,l),v(m,n,l),w(m,n,l) Velocities
    c temp(m,n,l),salt(m,n,l)         Temperature, Salinity 
    c we(m,n),wn(m,n) Wind Velocity Vectors (wind toward)
    c   
    C optional variable writing:
    c                  Upon initialization set a writing variable =1
    C                  If the variable is negative then
    c                  no variable is created or written later written.
    c             Only options are:  zeta,u,v,w,temp,salt,we,wn
    C   Example first call
    c      subroutine write_netcdf_Hydro(netcdf_file,ncid,imode,
    c     &  globalstr,m,n,l,
    c     & time,ibasedate,lon,lat,mask,sigma,depth,1.,1.,1.,0.,0.,0.,0.,0.)
    c  This will only create and write variables zeta,u,v   
    c
    c
    

    Upon initializatin (imode=1) the netcdf file is created, dimensions set and variables setup. In order to make the variable list somewhat controllable it is possible to eliminate variables by setting their values to less than or equal to zero for the initialization call. Thus a file with only the zeta, u and v variables may be created. Subsequent calls to the routine for writing (imode=2) will skip all references to the other variables. However in fortran we still need to keep the variables in the calling parameter list.

    The global variables are given values passed through the character array globalstr(9)*40 . The writecdf routine sets their values in a data statement like:
    data globalstr/
    & 'rectilinear','sigma','POMfake'
    & ,'test_netcdf_options','dummy','opsea','CSDL','original','user@noaa.gov'/

    The attributes to be set to the values are, in order: grid_type,z_type,model,title,comment,source,institution, history, references . The file_type attribute is hard coded into the write_netcdf_CSDL subroutines ("Full_Grid"). The other global values are set by the subroutine: file_type, conventions, creation_date.

    Back to Table of Contents

    Station Data Subroutine

    The station data NetCDF file is written with a similar subroutine in Hydro_netcdfs_station.f. This subroutine has slightly different calling parameters from the write_netcdf_CSDL routine. It includes the provisions for a list of the node locations of the stations and a character array to hold long names of the stations. Typically the station node locations and the long names will be fixed data statements in your write_cdf subroutine. For instance these lines are included for the CBOFS implementation:

    parameter( istation=14)
    character stationnames(istation)*40
    integer stationij(istation,2)
    data stationnames/
    & 'ocean boundary','CBBT','Hampton Roads'
    & ,'Kiptopeake','Glouster Pt','Lewisetta'
    & ,'Colonial Beach','Solomons','Cambridge'
    & ,'Annapolis','Baltimore','Tolchester'
    & ,'Thomas Point Light','CBOS Midbay' /

    data stationij/
    & 34, 32, 28, 32, 24, 21, 18, 20, 24, 16, 13, 18, 16, 19
    & , 50, 52, 53, 48, 48, 33, 32, 28, 21, 15, 11, 10, 15, 21/

    c call write_netcdf_Hydro_station(netcdf_file,ncid,imode,
    c & globalstr,istation,stationnames,stationij,meshdim,l,
    c & time,ibasedate,lon,lat,sigma,depth,zeta,u,v,w,temp,salt,windx,windy)
    c
    c
    c Inputs:
    c netcdf_file char*80 filename for the netcdf output
    c ncid netcdf id; generated on initialization
    c imode 1 for initialization, 2 for writing, 3 for closing file
    c globalstr Global Attributes. Set in a data statement like
    c data globalstr/
    c & 'grid_type','z_type','model'
    c & ,'experiment'/
    c
    c istation number of output stations
    c stationnames char stationnames(istation)*20 Ascii station labels
    c stationij(istation,meshdim) indices of main mesh of the stations
    c meshdim dimension of the main mesh 2 for u(i,j), 1 for fem u(inode)
    c possibly 3 for three surrounding nodes of fem
    c l dimension of vertical outputs. may be =1
    c time time in days
    c ibasedate(4) iyear, imonth, iday, ihour of base date (time = 0)
    c lon(istation) ,lat(istation) longitude, latitude of stations
    c sigma(l) sigma values for vertical outputs
    c zeta(istation) sea surface displacement
    c u(istation,l),v(istation,l),w(istation,l) Velocities
    c temp(istation,l),salt(istation,l) Temperature, Salinity
    c wx(istation),wy(istation) Eastward, Northward Air Velocity vectors
    c
    C optional variable writing:
    c Upon initialization set a writing variable =1
    C If the variable is negative then
    c no variable is created or written later written.
    c Only options are: zeta,u,v,w,temp,salt
    C Example first call
    c call write_netcdf_CSDL_station(netcdf_file,ncid,1,
    c & globalstr,istation,stationnames,stationij,meshdim,l,
    c & time,ibasedate,lon,lat,sigma,depth,1.,1.,1.,-1.,-1.,-1..-1.,-1.)
    c This will only create and write variables zeta,u,v
    c
    c

    Back to Table of Contents

    FEM Subroutines

    A similar package was prepared for the finite element NetCDF files.
    /usr/home/tgross/netcdf/NOAAstandards/progsfem maintestfem.f Hydro_netcdfs_fem.f
    The write_netcdf wrapper program used in zzrtquoddylinux on CSDL's computer bassmmap is quoddy_write_netcdf.f

    ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    c Real values in 3D
    subroutine write_netcdf_Hydro(netcdf_file,ncid,imode,ne,nn,l,
    & time,ibasedate,lon,lat,ele,sigma,depth,zeta,u,v,w,temp,salt) ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
    c 3D files scaled to short integers
    subroutine write_netcdf_Hydro_scale(netcdf_file,ncid,imode,ne,nn,l,
    & time,ibasedate,lon,lat,ele,sigma,depth,zeta,u,v,w,temp,salt)

    Back to Table of Contents

    NWLON Station Data

    The CO-OPS NWLON database holds several years worth of water level observations and contemporary data up to the hour which can be used with plotting and statistical analysis. It is desirable to be able to download this data and put it into a NetCDF file of the Station type. A routine which performs this task is described here: getnwlon.sh.


    Back to Table of Contents

    Downloads:


    Copies of files may be found on this web site and at the SourceForge project. These are supposed to be copies of the most recent versions. They are copied from a Sourceforge CVS download of oceanmodelfiles to the CCMP web page. But you really should go to the SOURCEFORGE site for the files now. For a CVS download go to CVSHELP and follow the directions. It isn't hard. The modulename is HYDRONetCDF

    Local File Copies:
    Hydro_netcdfs_grid.f
    Hydro_netcdfs_fem.f
    Hydro_netcdfs_station.f
    maintestgrid.f
    modelcommondim.inc
    maintestfem.f
    modelcommondimfem.inc
    Makefile
    quoddy_write_netcdf.f
    writecbofsnetcdf.f
    write_netcdf_pom.f
    write_netcdf_elcirc.f90
    nwloncdf/
    getnwlon.sh
    stationdata.input
    columncatnetcdf.f
    matlab/
    readcsdlpom.m
    readcsdlfem.m
    readnwlonnc.m

    The Quoddy example files as posted to the NECCM web site.
    quoddynetcdf.tar.gz

    Some FORTRAN warnings:


    Make sure the data arrays are dimensioned exactly to what the NetCDF wants.
    Make sure the data is in range when using the scaling. (Put a limiter in the subroutine. )
    In SGI FORTRAN subroutine variables must be explicitly save'ed. This can potentially cause problems with the variable id's when writing to more than one file with the same subroutine.

    Back to Table of Contents

    Matlab and NetCDF:

    I don't think I would have wanted to pursue the NetCDF standards without the Matlab interface created by Chuck Denham, USGS. The community owes him a debt of gratitude. The system is now a SourceForge mexcdf project , with its own web page, MATLAB MexCDF .

    Some example matlab routines reading the Modelers NetCDF files:
    Make a matlab routine to read thePOMNetCDF file. matlab/readcsdlpom.m
    Make a matlab routine to read the new quoddy NetCDF file. matlab/readcsdlfem.m
    Make a matlab routine to read the NWLON NetCDF file. matlab/readnwlonnc.m