netCDF 4.2.1.1
|
00001 00013 #include <stdio.h> 00014 #include <string.h> 00015 #include <netcdf.h> 00016 00017 /* This is the name of the data file we will create. */ 00018 #define FILE_NAME "sfc_pres_temp.nc" 00019 00020 /* We are writing 2D data, a 6 x 12 lat-lon grid. We will need two 00021 * netCDF dimensions. */ 00022 #define NDIMS 2 00023 #define NLAT 6 00024 #define NLON 12 00025 #define LAT_NAME "latitude" 00026 #define LON_NAME "longitude" 00027 00028 /* Names of things. */ 00029 #define PRES_NAME "pressure" 00030 #define TEMP_NAME "temperature" 00031 #define UNITS "units" 00032 #define DEGREES_EAST "degrees_east" 00033 #define DEGREES_NORTH "degrees_north" 00034 00035 /* These are used to construct some example data. */ 00036 #define SAMPLE_PRESSURE 900 00037 #define SAMPLE_TEMP 9.0 00038 #define START_LAT 25.0 00039 #define START_LON -125.0 00040 00041 /* Handle errors by printing an error message and exiting with a 00042 * non-zero status. */ 00043 #define ERR(e) {printf("Error: %s\n", nc_strerror(e)); return 2;} 00044 00045 int 00046 main() 00047 { 00048 int ncid, lon_dimid, lat_dimid, pres_varid, temp_varid; 00049 00050 /* In addition to the latitude and longitude dimensions, we will also 00051 create latitude and longitude netCDF variables which will hold the 00052 actual latitudes and longitudes. Since they hold data about the 00053 coordinate system, the netCDF term for these is: "coordinate 00054 variables." */ 00055 int lat_varid, lon_varid; 00056 00057 int dimids[NDIMS]; 00058 00059 /* We will write surface temperature and pressure fields. */ 00060 float pres_out[NLAT][NLON]; 00061 float temp_out[NLAT][NLON]; 00062 float lats[NLAT], lons[NLON]; 00063 00064 /* It's good practice for each netCDF variable to carry a "units" 00065 * attribute. */ 00066 char pres_units[] = "hPa"; 00067 char temp_units[] = "celsius"; 00068 00069 /* Loop indexes. */ 00070 int lat, lon; 00071 00072 /* Error handling. */ 00073 int retval; 00074 00075 /* Create some pretend data. If this wasn't an example program, we 00076 * would have some real data to write, for example, model 00077 * output. */ 00078 for (lat = 0; lat < NLAT; lat++) 00079 lats[lat] = START_LAT + 5.*lat; 00080 for (lon = 0; lon < NLON; lon++) 00081 lons[lon] = START_LON + 5.*lon; 00082 00083 for (lat = 0; lat < NLAT; lat++) 00084 for (lon = 0; lon < NLON; lon++) 00085 { 00086 pres_out[lat][lon] = SAMPLE_PRESSURE + (lon * NLAT + lat); 00087 temp_out[lat][lon] = SAMPLE_TEMP + .25 * (lon * NLAT + lat); 00088 } 00089 00090 /* Create the file. */ 00091 if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid))) 00092 ERR(retval); 00093 00094 /* Define the dimensions. */ 00095 if ((retval = nc_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid))) 00096 ERR(retval); 00097 if ((retval = nc_def_dim(ncid, LON_NAME, NLON, &lon_dimid))) 00098 ERR(retval); 00099 00100 /* Define coordinate netCDF variables. They will hold the 00101 coordinate information, that is, the latitudes and longitudes. A 00102 varid is returned for each.*/ 00103 if ((retval = nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid, 00104 &lat_varid))) 00105 ERR(retval); 00106 if ((retval = nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid, 00107 &lon_varid))) 00108 ERR(retval); 00109 00110 /* Define units attributes for coordinate vars. This attaches a 00111 text attribute to each of the coordinate variables, containing 00112 the units. Note that we are not writing a trailing NULL, just 00113 "units", because the reading program may be fortran which does 00114 not use null-terminated strings. In general it is up to the 00115 reading C program to ensure that it puts null-terminators on 00116 strings where necessary.*/ 00117 if ((retval = nc_put_att_text(ncid, lat_varid, UNITS, 00118 strlen(DEGREES_NORTH), DEGREES_NORTH))) 00119 ERR(retval); 00120 if ((retval = nc_put_att_text(ncid, lon_varid, UNITS, 00121 strlen(DEGREES_EAST), DEGREES_EAST))) 00122 ERR(retval); 00123 00124 /* Define the netCDF variables. The dimids array is used to pass 00125 the dimids of the dimensions of the variables.*/ 00126 dimids[0] = lat_dimid; 00127 dimids[1] = lon_dimid; 00128 if ((retval = nc_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS, 00129 dimids, &pres_varid))) 00130 ERR(retval); 00131 if ((retval = nc_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS, 00132 dimids, &temp_varid))) 00133 ERR(retval); 00134 00135 /* Define units attributes for vars. */ 00136 if ((retval = nc_put_att_text(ncid, pres_varid, UNITS, 00137 strlen(pres_units), pres_units))) 00138 ERR(retval); 00139 if ((retval = nc_put_att_text(ncid, temp_varid, UNITS, 00140 strlen(temp_units), temp_units))) 00141 ERR(retval); 00142 00143 /* End define mode. */ 00144 if ((retval = nc_enddef(ncid))) 00145 ERR(retval); 00146 00147 /* Write the coordinate variable data. This will put the latitudes 00148 and longitudes of our data grid into the netCDF file. */ 00149 if ((retval = nc_put_var_float(ncid, lat_varid, &lats[0]))) 00150 ERR(retval); 00151 if ((retval = nc_put_var_float(ncid, lon_varid, &lons[0]))) 00152 ERR(retval); 00153 00154 /* Write the pretend data. This will write our surface pressure and 00155 surface temperature data. The arrays of data are the same size 00156 as the netCDF variables we have defined. */ 00157 if ((retval = nc_put_var_float(ncid, pres_varid, &pres_out[0][0]))) 00158 ERR(retval); 00159 if ((retval = nc_put_var_float(ncid, temp_varid, &temp_out[0][0]))) 00160 ERR(retval); 00161 00162 /* Close the file. */ 00163 if ((retval = nc_close(ncid))) 00164 ERR(retval); 00165 00166 printf("*** SUCCESS writing example file sfc_pres_temp.nc!\n"); 00167 return 0; 00168 }