1.0 Why use netCDF for the WOCE Global Data set?
2.0 Using FORTRAN to read neCDF files
3.0 Using MATLAB to read netCDF files
4.0 Using C to read netCDF files
5.0 Using IDL to read netCDF files
6.0 Other methods and examining netCDF files
7.0 Important Web sites
Appendix 1: Readnet.f created from cdf2fortran
Appendix 2: Example Matlab script for current meter data
Appendix 3: Example output from ncdump
Appendix 4: Bug in gennet.for
Return to the previous document.
This document describes some simple tools that are available for reading the netCDF files found in the WOCE Global Data set Volume 3. These tools allow the netCDF files to be read quickly and easily and to be manipulated by many common analysis packages in addition to traditional languages such as Fortran (both Fortran 77 and Fortran 90), C/C++ and Java.
Because netCDF format is now used for all of the data products in the WOCE Global Data set, the skills required to read one data product are the same as those needed to read the others. This reduces the hurdles involved in reading the different data products and allows the analyst to concentrate on the interpretation of observations from many different sources. Because the netCDF files are self-describing, the attributes of each variable (such as units and name) are defined in the data file, along with other information such as the source, creation date, investigator, position, etc. This documentation preserves much of the original information in the data file, reducing the chance of errors occurring during analysis.
Return to the top of the primer.
The netCDF format has many advantages, the most important of which is that it is
self-describing, meaning that software packages can directly read the data and
determine its structure, the variable names and essential metadata such as the
units. This self-describing aspect of netCDF file format means that the information
needed to ensure accurate work (reduce the incidence of errors) is available with
the data itself. Secondly, it means that programs described below can examine a netCDF
file and generate the code needed to read the file whether it be Fortran, C/C++,
JAVA or PERL. Thirdly, plotting and analysis packages (e.g. FERRET, IDL, Matlab) can
directly read the netCDF files for plotting or analysis.
Although there is an initial learning curve for the inexperienced netCDF user,
high efficiency in reading netCDF files and files from multiple sources can be readily
achieved as shown in the examples below. These savings translate to more time for
analysing data and addressing the synthesis of the WOCE Global Data.
I have assumed that netCDF libraries have already been installed on your system.
They can be obtained from
UCAR's netCDF site and are available for Unix, Windows and Macintosh based systems.
This site also contains an excellent description of the Fortran, JAVA and PERL interfaces
for netCDF files. Free and commercial software that uses netCDF for input is also listed
at these sites and includes products such as FERRET, GMT and GrADs as well as commercial
products such as Matlab, NCAR Graphics, IDL and others. Here we focus on reading netCDF
files with FORTRAN, Matlab, C, IDL, ncdump and ncBrowse.
Return to the top of the primer.
The simplest way to create the Fortran code you need to read a netCDF file
is to use either of the Fortran programs cdf2fortran.f or gennet.for.
cdf2fortran.f can be obtained at the UCAR site given above or at
and gennet.for can be downloaded from
These programs read a netCDF file and create another Fortran program with
the required calls to the netCDF libraries. This machine-generated program
needs only to be compiled (with the correct include file and netCDF libraries).
When executed this code fragment can then read the netCDF file and is ready
for the Fortran code to be added to undertake the analysis required by the
user. The variable names reflect the internal structure of the netCDF file
and this machine generated code is quite readable by humans.
2.1 Worked example of cdf2fortran
The cdf2fortran.f code has been tested on samples of the netCDF files in the WOCE
dataset. To utilize it, retrieve and unpack the cdf2fortran tar file; then use the
make command to compile the code. cdf2fortran.f utilizes the Unidata netCDF libraries
and includes, which you should already have downloaded from Unidata and installed on
your computer. You will have to check that the include directory and the library
directory are correct for your particular installation of the Unidata materials.
Note that the example shown here assumes a UNIX/Linux environment. You may need to
employ a different but equivalent procedure in a different environment. To compile
cdf2fortran just type
To execute the cdf2fortran code, provide cdf2fortran with the name of a
netcdf file, in this case a current meter record named rcm00683.nc. cdf2fortran
will create a new Fortran program named readnet.f:
Next, edit readnet.f to correct the "include ‘netcdf.inc’" statement for your
particular installation. Then compile readnet.f with
Alternatively, you can compile readnet.f using the -I
option to get the correct include file and the -l
option to get the correct library file:
Sometimes there is a problem at compilation because one of the netCDF file's variable
names may be the same as a parameter name in readnet.f. Changing the parameter name fixes
this problem and now you should have a complete Fortran code able to read your particular
netCDF file. The result of compiling readnet.f for a sample of the current meter data in
WOCE Global Data Set is shown in Appendix 1. Although this piece of code is quite long
(compared to the examples shown below) it is reliable and is quick to develop compared
to reading files that are not self-describing, such as plain ASCII files. The sample code
fragment can in principle be generalised to read the netCDF data for all of the
different current meter records. The program gennet.for works in a very similar way
and produces a slightly better-documented Fortran code. See Appendix 4 for fixing a
bug in the readnet.f programs created by gennet.for.
Return to the top of the primer.
Commonwealth Scientific Industrial Research Organisation (CSIRO) distributes
a Matlab interface for reading netCDF files
(www.marine.csiro.au/sw/matlab-netcdf.html). This is a very powerful
tool for those who are only interested in reading netCDF files. Those
who want to create netCDF files from within Matlab should use Chuck Denham's
interface
(http://crusty.er.usgs.gov/~cdenham).
You will also need this software to use the CSIRO Matlab/netCDF interface anyway.
Follow the install instructions at the two web sites above.
3.1 Sample commands of CSIRO Matlab/netCDF interface
Of the 6 main commands, the two most important are getnc (getcdf)
and inqnc (inqcdf). Detailed instructions on their use can be found at
www.marine.csiro.au/sw/matlab-netcdf.html;
only a bare bones description is given here. The use of inqnc allows
interactive interrogation of the netCDF file. In Matlab, for example:
creates a description of the contents of the current meter record rcm01037.nc.
The global attributes consist of general information about the data, and in this
example include the principal investigator, the instrument name, experiment name,
etc. In addition inqnc gives a list of the variables that are contained within the
file. In this case there are 8 different variables (date, time, speed, etc.) that
are organised as vectors with each element corresponding to a particular time
(i.e., these are time series). All the vectors have a length of 35954. Because
inqnc is interactive it is possible to determine the attributes of each of the
variables. To retrieve one of the variables within the above data set, such as
speed, the getnc command is used:
This is the simplest use of the getnc command. Because only two arguments are
provided getnc assumes that the data are to be automatically scaled, flagged data
will be changed to NaN (not a number), and all data are required. The Matlab script
in Appendix 2 shows how all of the Matlab data in the above test file can be read
with just 7 lines of code. This is considerably less than in the Fortran example
shown in Appendix 1. However the development time for the Fortran and Matlab examples
is similar and quick.
The getnc command also has arguments that allow changing missing values, changing
the stride length (i.e. allow sub-sampling of the variable), etc. In this way the
user can sub-sample, scale the data and read only the variables that are required
from the netCDF file. In very large files this represents an important advantage
to the user. A nice example of this capability is shown on the above website
(by Jim Mansbridge). The website also shows an example of the Matlab command
in which all the arguments are listed.
All of the netCDF files that appear in the WOCE Global Data Set can be read by
scripts based on just these two Matlab commands. By using the simplest form of
getnc you will be able to read most of the netCDF files from a particular WOCE
Data Assembly Centre with a single script. Thus it is easy and quick to create
macros that can read the different netCDF files from a WOCE Data Assembly Centre,
leading to significant savings in time and effort. Other important commands are
whatnc (gives a list of netCDF files in local directory) and attnc (gets the
attributes of particular variables, such as scale factor).
If necessary the scale factor applied to data can be obtained from the netCDF
file by using the attnc comand. For example,
would force the Latitude to be correctly scaled by the scale factor from
within the netcCDF file.
Return to the top of the primer.
The simplest way to create the C code you need to read a netCDF is to use the
C program cdf2c.c, which can be obtained from the Unidata site or from
This program reads a netCDF file and creates another C program with the required
calls to the netCDF libraries. The latter machine-generated program only needs
to be compiled, with the correct include file and netCDF library. When executed
this code fragment can then read the netCDF file and is ready for C code to be
added to undertake the analysis required by the user. The procedure for installing
and compiling is described in the documentation from the web site listed above and
is similar in operation to the cdf2fortran program described above.
Return to the top of the primer.
IDL can read netCDF files and specifically has a browser to do this
(see page 137 of What's new in IDL 5.3). In addition IDL has specific routines
for reading netCDF files. However, the simplest way to create the IDL code
you need to read a netCDF file is to use the IDL program cdf2idl, which is
available at the Unidata site or at
The concept of this program is similar to that of the cdf2fortran.f, cdf2c.c,
and cdf2asc.c programs and is provided by the same group (C4 Interactive Display
System). The program reads a netCDF file and create another IDL script which can
read the netCDF file.
5.1 Example of using cdf2idl
From within IDL all you need to do, to read the current meter record used
in the cdf2fortran example (Section 2.1) is
At the completion of this script all of the current meter data are in memory
ready to be analysed. A total of 3 lines of IDL code is needed to read this
data set. These three lines of code are so general that they will actually
read any of the netCDF files from any of the WOCE Data Assembly Centres
provided as part of the WOCE Global Data Set.
Return to the top of the primer.
6.1 ncdump
This utility is a very useful program for those who do not have Matlab or
IDL and want to check the attributes and obtain the data from a netCDF file.
The NetCDF User's Guide, which you can download from Unidata, describes this
command (and its partner ncgen) in detail. To obtain the attributes of the
current meter data one would enter
Appendix 3 shows the output from this command. To obtain the speed data in
this file type
or to obtain the speed and the direction data enter
The last command can lead to large files ASCII files that have a relatively
simple structure and can be read by programs. However, the chief value of ncdump
is that it allows one to check attributes and structure of netcdf files quickly
and easily. A more convenient way to examine netCDF files is to be able to
visualise the data using a graphical interface such as ncBrowse.
6.2 ncBrowse
This program is a Java application. It can be obtained at
www.epic.noaa.gov/java/ncBrowse/.
ncBrowse allows the contents of variables and global attributes to be viewed
graphically. It can run on any computer - UNIX workstation, PC or Macintosh - that
has the Java Virtual Machine installed. (See the above web site or http://java.sun.com/products/jdk/1.2
for information about Java.) The interface is largely self-explanatory and provides
a wonderful method for browsing generic netCDF files. ncBrowse can be slow on older
computers but is well worth installing and using to check netCDF files. Some of the
netCDF files on the WOCE Global Data CDROMs are EPIC compliant, which makes the
visualisation and plotting of these compliant data even easier.
Return to the top of the primer.
Return to the top of the primer.
This is a sample file produced by the cdf2fortran utility with the netCDF current
meter record rcm00683.nc found in the WOCE CDROM set. Note that this Fortran routine
can easily be generalised to read all of the WOCE current meter records.
Return to the top of the primer.
This is a Matlab macro to read the netCDF file rcm01037.nc found in the WOCE data set.
This file is the equivalent of the Fortran code listed in Appendix 1. Note that this
macro routine can be generalised to read all of the WOCE current meter records.
Return to the top of the primer.
We list below the attributes of the current meter record rcm00683.nc obtained
from ncdump -h. This is equivalent to the Matlab inqnc command. It describes the global
attributes, and each of the variables.
Return to the top of the primer.
The program in gennet.for is not quite perfect. When it creates the
readnet.f program it some times places the wrong routine call in readnet.for.
If you get a message like
the following may fix the problem. The line where readnet.for crashes is a
call to NCAGT. At this point, readnet.for tries to read a character variable
attribute "long_name" using a routine that is designed for numeric attributes
(NCAGT). To make the code work substitute a call to NCAGTC at this point in
the code and also to assign mtlen = 50 (the character width dimension of "name").
With these two changes the code runs like a charm.
Return to the top of the primer.
1.0 Why use netCDF for the WOCE CDROMs?
Using FORTRAN to read netCDF files
> make cdf2fortran
> cdf2fortran rcm00683.nc
Generated Fortran program called readnet.f
>
> f77 readnet.f
> f77 -c readnet.f -I/usr/local/netcdf/include
> f77 -o readnet readnet.o -l/usr/local/netcdf/lib/libnetcdf.a
3.0 Using Matlab to read netCDF files
>> inqnc('rcm01037')
--- Global attributes ---
experiment_name: Deep Currents (PCM6)
mooring_name: WHOI 947
pi_name: B.Owens/B.Warren
instrument_type: VACM
latitude: 40.6000
longitude: 147.3492
instrument_depth: 1999.0 m
seafloor_depth: 5280 m
sampling_interval: 30 min
earliest_start_time: 12-jun-1993 12:15:00
latest_stop_time: 01-jul-1995 12:45:00
null_value: -999.9
The 1 dimensions are 1) time = 35954.
time is unlimited in length
----- Get further information about the following variables -----
-1) None of them (no further information)
0) All of the variables
1) date 2) time 3) speed
4) direction 5) u 6) v
7) temperature 8) pressure
>>
>> speed=getnc('rcm01037','speed');
>> help inqnc
>> Latitude=getnc(file,'Latitude')*attnc(file,'Latitude','Scale');
4.0 Using C to read netCDF files
5.0 Using IDL to read netCDF files
IDL> .run cdf2idl.pro
IDL> cdf2idl, 'rcm00683.nc'
IDL> @script.idl
6.0 Other methods and examining netCDF files
>ncdump -h rcm00683.nc
>ncdump -v speed rcm00683.nc
>ncdump -v speed, direction rcm00683.nc
Appendix 1: Readnet.f created from cdf2fortran
c-----------------------------------------------------------------------
c
c readnet.f
c This file is a Fortran template file designed to read the given
c netCDF file into memory.
c
c-----------------------------------------------------------------------
c Do not forget to include the -I path_to_netcdf_includes in your
c compile statement
c Required include. Replace the location below with the directory where
c netcdf.inc has been placed on your machine (it will not necessarily be
c in /usr/local/netcdf/include).
include '/usr/local/netcdf/include/netcdf.inc'
c Define Variables.
c Variable ids run sequentially from 1 to nvars = 08
parameter (nvars = 8) ! number of variables
parameter (nrec= 36434) ! change this 'to generalize
parameter (ndims = 1) ! number of dimensions
parameter (itime = 36434)
integer*4 rcode ! error code
integer*4 recdim ! record dimension
real*8 date(nrec)
real*8 time(nrec)
real*4 speed(nrec)
real*4 direction(nrec)
real*4 u(nrec)
real*4 v(nrec)
real*4 temperature(nrec)
real*4 pressure(nrec)
integer*4 start(ndims) ! hyperslab starting index
integer*4 count(ndims) ! hyperslab count from start
integer vdims(ndims) ! max # of var dims
character*1024 strbuf ! string buffer for var and attr names
c Open netCDF file.
ncid=ncopn('rcm00683.nc',ncnowrit,rcode)
c Get info on the record dimension for this file.
call ncinq(ncid,ndims,nvars,ngatts,recdim,rcode)
call ncdinq(ncid,recdim,strbuf,nrecs,rcode)
c nrecs now contains the # of records for this file.
c Retrieve data for date variable.
call ncvinq(ncid, 1,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 1,start,count,date,rcode)
c Retrieve data for time variable.
call ncvinq(ncid, 2,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 2,start,count,time,rcode)
c Retrieve data for speed variable.
call ncvinq(ncid, 3,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 3,start,count,speed,rcode)
c Retrieve data for direction variable.
call ncvinq(ncid, 4,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 4,start,count,direction,rcode)
c Retrieve data for u variable.
call ncvinq(ncid, 5,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 5,start,count,u,rcode)
c Retrieve data for v variable.
call ncvinq(ncid, 6,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 6,start,count,v,rcode)
c Retrieve data for temperature variable.
call ncvinq(ncid, 7,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 7,start,count,temperature,rcode)
c Retrieve data for pressure variable.
call ncvinq(ncid, 8,strbuf,nctype,nvdim,vdims,nvatts,rcode)
lenstr=1
do j=1,nvdim
call ncdinq(ncid,vdims(j),strbuf,ndsize,rcode)
lenstr=lenstr*ndsize
start(j)=1
count(j)=ndsize
end do
call ncvgt(ncid, 8,start,count,pressure,rcode)
c ******************************************
c Begin writing statements to use the data.
c ******************************************
c End Program.
stop
end
Appendix 2: Example Matlab script for current meter data
%
% A simple Matlab script to read the RCM netcdf file.
%
% Author: Nathan Bindoff
% Date: 28 March 2000
% The script uses Jim Mansbridge's netcdf routines for Matlab.
%
% Documetation and description of these routines can be found at
% http://www.marine.csiro.au/sw/matlab-netcdf.html.
%
%
% Read the current meter data
%
inqnc('rcm01037')
%
%
file='rcm01037'
%
%
woce_date=getcdf(file,'date');
woce_time_of_day=getcdf(file,'time');
speed=getcdf(file,'speed');
direction=getcdf(file,'direction');
u=getcdf(file,'u');
v=getcdf(file,'v');
temperature=getcdf(file,'temperature');
pressure=getcdf(file,'pressure');
%
% Example of contents of inqnc('rcm01037')
%
%
% --- Global attributes ---
%experiment_name: Deep Currents (PCM6)
%mooring_name: WHOI 947
%pi_name: B.Owens/B.Warren
%instrument_type: VACM
%latitude: 40.6000
%longitude: 147.3492
%instrument_depth: 1999.0 m
%seafloor_depth: 5280 m
%sampling_interval: 30 min
%earliest_start_time: 12-jun-1993 12:15:00
%latest_stop_time: 01-jul-1995 12:45:00
%null_value: -999.9
%
%The 1 dimensions are 1) time = 35954.
%time is unlimited in length
%
%----- Get further information about the following variables -----
%
% -1) None of them (no further information)
% 0) All of the variables
% 1) date 2) time 3) speed
% 4) direction 5) u 6) v
% 7) temperature 8) pressure
Appendix 3: Example output from ncdump
netcdf rcm00683 {
dimensions:
time = unlimited; // (36434 currently)
variables:
double woce_date(time);
woce_date:long_name = "date (yr, mo, day)";
woce_date:units = "YYYYMMDD";
woce_date:valid_range = 19500101, 20501231;
double woce_time_of_day(time);
woce_time_of_day:long_name = "time (hr, min, sec)";
woce_time_of_day:units = "hhmmss.dd";
woce_time_of_day:valid_range = 0.0, 235959.99;
float speed(time);
speed:units = "m/sec";
speed:valid_range = 0.0, 3.0;
float direction(time);
direction:long_name = "true direction (toward)";
direction:units = "degrees, clockwise from N";
direction:valid_range = 0.0, 360.0;
float u(time);
u:long_name = "eastward velocity component";
u:units = "m/sec";
u:valid_range = -3.0, 3.0;
float v(time);
v:long_name = "northward velocity component";
v:units = "m/sec";
v:valid_range = -3.0, 3.0;
float temperature(time);
temperature:long_name = "water temperature";
temperature:units = "degrees C";
temperature:valid_range = -2.0, 35.0;
float pressure(time);
pressure:units = "decibars";
pressure:valid_range = 0.0, 12000.0;
// global attributes
:experiment_name = "Deep Currents (PCM6)";
:mooring_name = "WHOI 942";
:pi_name = "B.Owens/B.Warren";
:instrument_type = "VACM";
:latitude = " 36.4025";
:longitude = " 150.2307";
:instrument_depth = "2001.0 m";
:seafloor_depth = " 5829 m";
:sampling_interval = " 30 min";
:earliest_start_time = "08-jun-1993 12:15:00";
:latest_stop_time = "07-jul-1995 12:45:00";
:null_value = -999.9;
}
Appendix 4: Bug in gennet.for
>NCAGT: : Attempt to convert between text & numbers