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