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