1 /* This is part of the netCDF package.
2    Copyright 2006 University Corporation for Atmospheric Research/Unidata.
3    See COPYRIGHT file for conditions of use.
4 
5    This is an example which reads some surface pressure and
6    temperatures. The data file read by this program is produced
7    companion program sfc_pres_temp_wr.cxx. It is intended to
8    illustrate the use of the netCDF C++ API.
9 
10    This program is part of the netCDF tutorial:
11    http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
12 
13    Full documentation of the netCDF C++ API can be found at:
14    http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx
15 
16    $Id: sfc_pres_temp_rd.cpp,v 1.6 2010/02/11 22:36:42 russ Exp $
17 */
18 
19 #include <iostream>
20 #include <string>
21 #include <netcdf>
22 using namespace std;
23 using namespace netCDF;
24 using namespace netCDF::exceptions;
25 
26 // We are reading 2D data, a 6 x 12 lat-lon grid.
27 static const int NLAT = 6;
28 static const int NLON = 12;
29 
30 // These are used to calculate the values we expect to find.
31 static const float SAMPLE_PRESSURE = 900;
32 static const float SAMPLE_TEMP = 9.0;
33 static const float START_LAT = 25.0;
34 static const float START_LON = -125.0;
35 
36 // Return this code to the OS in case of failure.
37 static const int NC_ERR = 2;
38 
main(void)39 int main(void)
40 {
41    // These will hold our pressure and temperature data.
42    float presIn[NLAT][NLON];
43    float tempIn[NLAT][NLON];
44 
45    // These will hold our latitudes and longitudes.
46    float latsIn[NLAT];
47    float lonsIn[NLON];
48 
49   try
50   {
51    // Open the file and check to make sure it's valid.
52    NcFile dataFile("sfc_pres_temp.nc", NcFile::read);
53 
54    // There are a number of inquiry functions in netCDF which can be
55    // used to learn about an unknown netCDF file. In this case we know
56    // that there are 2 netCDF dimensions, 4 netCDF variables, no
57    // global attributes, and no unlimited dimension.
58 
59    //cout<<"there are "<<dataFile.getVarCount()<<" variables"<<endl;
60    //cout<<"there are "<<dataFile.getAttCount()<<" attributes"<<endl;
61    //cout<<"there are "<<dataFile.getDimCount()<<" dimensions"<<endl;
62    //cout<<"there are "<<dataFile.getGroupCount()<<" groups"<<endl;
63    //cout<<"there are "<<dataFile.getTypeCount()<<" types"<<endl;
64 
65    // Get the  latitude and longitude coordinate variables and read data
66    NcVar latVar, lonVar;
67    latVar = dataFile.getVar("latitude");
68    if(latVar.isNull()) return NC_ERR;
69    lonVar = dataFile.getVar("longitude");
70    if(lonVar.isNull()) return NC_ERR;
71    latVar.getVar(latsIn);
72    lonVar.getVar(lonsIn);
73 
74    // Check the coordinate variable data.
75    for(int lat = 0; lat < NLAT; lat++)
76       if (latsIn[lat] != START_LAT + 5. * lat)
77 	 return NC_ERR;
78 
79    // Check longitude values.
80    for (int lon = 0; lon < NLON; lon++)
81       if (lonsIn[lon] != START_LON + 5. * lon)
82 	 return NC_ERR;
83 
84    // Read in presure and temperature variables and read data
85    NcVar presVar, tempVar;
86    presVar = dataFile.getVar("pressure");
87    if(presVar.isNull()) return NC_ERR;
88    tempVar = dataFile.getVar("temperature");
89    if(tempVar.isNull()) return NC_ERR;
90    presVar.getVar(presIn);
91    tempVar.getVar(tempIn);
92 
93    // Check the data.
94    for (int lat = 0; lat < NLAT; lat++)
95       for (int lon = 0; lon < NLON; lon++)
96 	 if (presIn[lat][lon] != SAMPLE_PRESSURE + (lon * NLAT + lat)
97 	     || tempIn[lat][lon] != SAMPLE_TEMP + .25 * (lon * NLAT + lat))
98 	    return NC_ERR;
99 
100    // Each of the netCDF variables has a "units" attribute. Let's read
101    // them and check them.
102    NcVarAtt att;
103    string units;
104 
105    att = latVar.getAtt("units");
106    if(att.isNull()) return NC_ERR;
107 
108    att.getValues(units);
109    if (units != "degrees_north")
110      {
111        cout<<"getValue returned "<<units<<endl;
112        return NC_ERR;
113      }
114 
115 
116    att = lonVar.getAtt("units");
117    if(att.isNull()) return NC_ERR;
118 
119    att.getValues(units);
120    if (units != "degrees_east")
121      {
122        cout<<"getValue returned "<<units<<endl;
123        return NC_ERR;
124      }
125 
126    att = presVar.getAtt("units");
127    if(att.isNull()) return NC_ERR;
128 
129    att.getValues(units);
130    if (units != "hPa")
131      {
132        cout<<"getValue returned "<<units<<endl;
133        return NC_ERR;
134      }
135 
136    att = tempVar.getAtt("units");
137    if(att.isNull()) return NC_ERR;
138 
139    att.getValues(units);
140    if (units != "celsius")
141      {
142        cout<<"getValue returned "<<units<<endl;
143        return NC_ERR;
144      }
145 
146    // The file will be automatically closed by the destructor. This
147    // frees up any internal netCDF resources associated with the file,
148    // and flushes any buffers.
149    //cout << "*** SUCCESS reading example file sfc_pres_temp.nc!" << endl;
150    return 0;
151   }
152   catch(NcException e)
153   {
154      e.what();
155      cout<<"FAILURE********************************8"<<endl;
156      return NC_ERR;
157   }
158 }
159