1C     This is part of the netCDF package.
2C     Copyright 2006 University Corporation for Atmospheric Research/Unidata.
3C     See COPYRIGHT file for conditions of use.
4
5C     This is an example which reads some 4D pressure and
6C     temperatures. The data file read by this program is produced by
7C     the companion program pres_temp_4D_wr.f. It is intended to
8C     illustrate the use of the netCDF Fortran 77 API.
9
10C     This program is part of the netCDF tutorial:
11C     http://www.unidata.ucar.edu/software/netcdf/docs/tutorial_8dox.html
12
13C     Full documentation of the netCDF Fortran 77 API can be found at:
14C     http://www.unidata.ucar.edu/software/netcdf/docs-fortran/nc_f77_interface_guide.html
15
16C     Ed Hartnett
17
18      program pres_temp_4D_rd
19      implicit none
20      include 'netcdf.inc'
21
22C     This is the name of the data file we will read.
23      character*(*) FILE_NAME
24      parameter (FILE_NAME='pres_temp_4D.nc')
25      integer ncid
26
27C     We are reading 4D data, a 12 x 6 x 2 lon-lat-lvl grid, with 2
28C     timesteps of data.
29      integer NDIMS, NRECS
30      parameter (NDIMS = 4, NRECS = 2)
31      integer NLVLS, NLATS, NLONS
32      parameter (NLVLS = 2, NLATS = 6, NLONS = 12)
33      character*(*) LVL_NAME, LAT_NAME, LON_NAME, REC_NAME
34      parameter (LVL_NAME = 'level')
35      parameter (LAT_NAME = 'latitude', LON_NAME = 'longitude')
36      parameter (REC_NAME = 'time')
37
38C     The start and count arrays will tell the netCDF library where to
39C     read our data.
40      integer start(NDIMS), count(NDIMS)
41
42C     In addition to the latitude and longitude dimensions, we will also
43C     create latitude and longitude variables which will hold the actual
44C     latitudes and longitudes. Since they hold data about the
45C     coordinate system, the netCDF term for these is: "coordinate
46C     variables."
47      real lats(NLATS), lons(NLONS)
48      integer lon_varid, lat_varid
49
50C     We will read surface temperature and pressure fields. In netCDF
51C     terminology these are called "variables."
52      character*(*) PRES_NAME, TEMP_NAME
53      parameter (PRES_NAME='pressure')
54      parameter (TEMP_NAME='temperature')
55      integer pres_varid, temp_varid
56
57C     We recommend that each variable carry a "units" attribute.
58      character*(*) UNITS
59      parameter (UNITS = 'units')
60      character*(*) PRES_UNITS, TEMP_UNITS, LAT_UNITS, LON_UNITS
61      parameter (PRES_UNITS = 'hPa', TEMP_UNITS = 'celsius')
62      parameter (LAT_UNITS = 'degrees_north')
63      parameter (LON_UNITS = 'degrees_east')
64
65C     Program variables to hold the data we will read in. We will only
66C     need enough space to hold one timestep of data; one record.
67      real pres_in(NLONS, NLATS, NLVLS)
68      real temp_in(NLONS, NLATS, NLVLS)
69      real SAMPLE_PRESSURE
70      parameter (SAMPLE_PRESSURE = 900.0)
71      real SAMPLE_TEMP
72      parameter (SAMPLE_TEMP = 9.0)
73
74C     Use these to calculate the values we expect to find.
75      integer START_LAT, START_LON
76      parameter (START_LAT = 25.0, START_LON = -125.0)
77
78C     Loop indices.
79      integer lvl, lat, lon, rec, i
80
81C     Error handling.
82      integer retval
83
84C     Open the file.
85      retval = nf_open(FILE_NAME, nf_nowrite, ncid)
86      if (retval .ne. nf_noerr) call handle_err(retval)
87
88C     Get the varids of the latitude and longitude coordinate variables.
89      retval = nf_inq_varid(ncid, LAT_NAME, lat_varid)
90      if (retval .ne. nf_noerr) call handle_err(retval)
91      retval = nf_inq_varid(ncid, LON_NAME, lon_varid)
92      if (retval .ne. nf_noerr) call handle_err(retval)
93
94C     Read the latitude and longitude data.
95      retval = nf_get_var_real(ncid, lat_varid, lats)
96      if (retval .ne. nf_noerr) call handle_err(retval)
97      retval = nf_get_var_real(ncid, lon_varid, lons)
98      if (retval .ne. nf_noerr) call handle_err(retval)
99
100C     Check to make sure we got what we expected.
101      do lat = 1, NLATS
102         if (lats(lat) .ne. START_LAT + (lat - 1) * 5.0) stop 2
103      end do
104      do lon = 1, NLONS
105         if (lons(lon) .ne. START_LON + (lon - 1) * 5.0) stop 2
106      end do
107
108C     Get the varids of the pressure and temperature netCDF variables.
109      retval = nf_inq_varid(ncid, PRES_NAME, pres_varid)
110      if (retval .ne. nf_noerr) call handle_err(retval)
111      retval = nf_inq_varid(ncid, TEMP_NAME, temp_varid)
112      if (retval .ne. nf_noerr) call handle_err(retval)
113
114C     Read 1 record of NLONS*NLATS*NLVLS values, starting at the
115C     beginning of the record (the (1, 1, 1, rec) element in the netCDF
116C     file).
117      count(1) = NLONS
118      count(2) = NLATS
119      count(3) = NLVLS
120      count(4) = 1
121      start(1) = 1
122      start(2) = 1
123      start(3) = 1
124
125C     Read the surface pressure and temperature data from the file, one
126C     record at a time.
127      do rec = 1, NRECS
128         start(4) = rec
129         retval = nf_get_vara_real(ncid, pres_varid, start, count,
130     $        pres_in)
131         if (retval .ne. nf_noerr) call handle_err(retval)
132         retval = nf_get_vara_real(ncid, temp_varid, start, count,
133     $        temp_in)
134         if (retval .ne. nf_noerr) call handle_err(retval)
135
136         i = 0
137         do lvl = 1, NLVLS
138            do lat = 1, NLATS
139               do lon = 1, NLONS
140                  if (pres_in(lon, lat, lvl) .ne. SAMPLE_PRESSURE + i)
141     $                 stop 2
142                  if (temp_in(lon, lat, lvl) .ne. SAMPLE_TEMP + i)
143     $                 stop 2
144                  i = i + 1
145               end do
146            end do
147         end do
148C     next record
149      end do
150
151C     Close the file. This frees up any internal netCDF resources
152C     associated with the file.
153      retval = nf_close(ncid)
154      if (retval .ne. nf_noerr) call handle_err(retval)
155
156C     If we got this far, everything worked as expected. Yipee!
157      print *,'*** SUCCESS reading example file pres_temp_4D.nc!'
158      end
159
160      subroutine handle_err(errcode)
161      implicit none
162      include 'netcdf.inc'
163      integer errcode
164
165      print *, 'Error: ', nf_strerror(errcode)
166      stop 2
167      end
168