NetCDF  4.9.2
sfc_pres_temp_rd.c
Go to the documentation of this file.
1 /* Copyright 2018 University Corporation for Atmospheric
2  Research/Unidata. See COPYRIGHT file for conditions of use. */
15 #include <stdio.h>
16 #include <string.h>
17 #include <netcdf.h>
18 
19 /* This is the name of the data file we will read. */
20 #define FILE_NAME "sfc_pres_temp.nc"
21 
22 /* We are reading 2D data, a 6 x 12 lat-lon grid. */
23 #define NDIMS 2
24 #define NLAT 6
25 #define NLON 12
26 
27 #define LAT_NAME "latitude"
28 #define LON_NAME "longitude"
29 #define PRES_NAME "pressure"
30 #define TEMP_NAME "temperature"
31 
32 /* These are used to calculate the values we expect to find. */
33 #define SAMPLE_PRESSURE 900
34 #define SAMPLE_TEMP 9.0
35 #define START_LAT 25.0
36 #define START_LON -125.0
37 
38 /* For the units attributes. */
39 #define UNITS "units"
40 #define PRES_UNITS "hPa"
41 #define TEMP_UNITS "celsius"
42 #define LAT_UNITS "degrees_north"
43 #define LON_UNITS "degrees_east"
44 #define MAX_ATT_LEN 80
45 
46 /* Handle errors by printing an error message and exiting with a
47  * non-zero status. */
48 #define ERR(e) {printf("Error: %s\n", nc_strerror(e)); return 2;}
49 
50 int
51 main()
52 {
53  int ncid, pres_varid, temp_varid;
54  int lat_varid, lon_varid;
55 
56  /* We will read surface temperature and pressure fields. */
57  float pres_in[NLAT][NLON];
58  float temp_in[NLAT][NLON];
59 
60  /* For the lat lon coordinate variables. */
61  float lats_in[NLAT], lons_in[NLON];
62 
63  /* To check the units attributes. */
64  char pres_units_in[MAX_ATT_LEN], temp_units_in[MAX_ATT_LEN];
65  char lat_units_in[MAX_ATT_LEN], lon_units_in[MAX_ATT_LEN];
66 
67  /* We will learn about the data file and store results in these
68  program variables. */
69  int ndims_in, nvars_in, ngatts_in, unlimdimid_in;
70 
71  /* Loop indexes. */
72  int lat, lon;
73 
74  /* Error handling. */
75  int retval;
76 
77  /* Open the file. */
78  if ((retval = nc_open(FILE_NAME, NC_NOWRITE, &ncid)))
79  ERR(retval);
80 
81  /* There are a number of inquiry functions in netCDF which can be
82  used to learn about an unknown netCDF file. NC_INQ tells how
83  many netCDF variables, dimensions, and global attributes are in
84  the file; also the dimension id of the unlimited dimension, if
85  there is one. */
86  if ((retval = nc_inq(ncid, &ndims_in, &nvars_in, &ngatts_in,
87  &unlimdimid_in)))
88  ERR(retval);
89 
90  /* In this case we know that there are 2 netCDF dimensions, 4
91  netCDF variables, no global attributes, and no unlimited
92  dimension. */
93  if (ndims_in != 2 || nvars_in != 4 || ngatts_in != 0 ||
94  unlimdimid_in != -1) return 2;
95 
96  /* Get the varids of the latitude and longitude coordinate
97  * variables. */
98  if ((retval = nc_inq_varid(ncid, LAT_NAME, &lat_varid)))
99  ERR(retval);
100  if ((retval = nc_inq_varid(ncid, LON_NAME, &lon_varid)))
101  ERR(retval);
102 
103  /* Read the coordinate variable data. */
104  if ((retval = nc_get_var_float(ncid, lat_varid, &lats_in[0])))
105  ERR(retval);
106  if ((retval = nc_get_var_float(ncid, lon_varid, &lons_in[0])))
107  ERR(retval);
108 
109  /* Check the coordinate variable data. */
110  for (lat = 0; lat < NLAT; lat++)
111  if (lats_in[lat] != START_LAT + 5.*lat)
112  return 2;
113  for (lon = 0; lon < NLON; lon++)
114  if (lons_in[lon] != START_LON + 5.*lon)
115  return 2;
116 
117  /* Get the varids of the pressure and temperature netCDF
118  * variables. */
119  if ((retval = nc_inq_varid(ncid, PRES_NAME, &pres_varid)))
120  ERR(retval);
121  if ((retval = nc_inq_varid(ncid, TEMP_NAME, &temp_varid)))
122  ERR(retval);
123 
124  /* Read the data. Since we know the contents of the file we know
125  * that the data arrays in this program are the correct size to
126  * hold all the data. */
127  if ((retval = nc_get_var_float(ncid, pres_varid, &pres_in[0][0])))
128  ERR(retval);
129  if ((retval = nc_get_var_float(ncid, temp_varid, &temp_in[0][0])))
130  ERR(retval);
131 
132  /* Check the data. */
133  for (lat = 0; lat < NLAT; lat++)
134  for (lon = 0; lon < NLON; lon++)
135  if (pres_in[lat][lon] != SAMPLE_PRESSURE + (lon * NLAT + lat) ||
136  temp_in[lat][lon] != SAMPLE_TEMP + .25 * (lon * NLAT + lat))
137  return 2;
138 
139  /* Each of the netCDF variables has a "units" attribute. Let's read
140  them and check them. */
141  if ((retval = nc_get_att_text(ncid, lat_varid, UNITS, lat_units_in)))
142  ERR(retval);
143  if (strncmp(lat_units_in, LAT_UNITS, strlen(LAT_UNITS)))
144  return 2;
145 
146  if ((retval = nc_get_att_text(ncid, lon_varid, UNITS, lon_units_in)))
147  ERR(retval);
148  if (strncmp(lon_units_in, LON_UNITS, strlen(LON_UNITS)))
149  return 2;
150 
151  if ((retval = nc_get_att_text(ncid, pres_varid, UNITS, pres_units_in)))
152  ERR(retval);
153  if (strncmp(pres_units_in, PRES_UNITS, strlen(PRES_UNITS)))
154  return 2;
155 
156  if ((retval = nc_get_att_text(ncid, temp_varid, UNITS, temp_units_in)))
157  ERR(retval);
158  if (strncmp(temp_units_in, TEMP_UNITS, strlen(TEMP_UNITS))) return 2;
159 
160  /* Close the file. */
161  if ((retval = nc_close(ncid)))
162  ERR(retval);
163 
164  printf("*** SUCCESS reading example file sfc_pres_temp.nc!\n");
165  return 0;
166 }
EXTERNL int nc_get_att_text(int ncid, int varid, const char *name, char *ip)
Get a text attribute.
Definition: dattget.c:222
EXTERNL int nc_close(int ncid)
Close an open netCDF dataset.
Definition: dfile.c:1302
EXTERNL int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
Definition: dfile.c:1637
EXTERNL int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
Definition: dfile.c:666
EXTERNL int nc_inq_varid(int ncid, const char *name, int *varidp)
Find the ID of a variable, from the name.
Definition: dvarinq.c:60
int nc_get_var_float(int ncid, int varid, float *ip)
Read an entire variable in one call.
Definition: dvarget.c:1075
Main header file for the C API.
#define NC_NOWRITE
Set read-only access for nc_open().
Definition: netcdf.h:126