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 "pres_temp_4D.nc" 00019 00020 /* We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2 00021 timesteps of data. */ 00022 #define NDIMS 4 00023 #define NLAT 6 00024 #define NLON 12 00025 #define LAT_NAME "latitude" 00026 #define LON_NAME "longitude" 00027 #define NREC 2 00028 #define REC_NAME "time" 00029 #define LVL_NAME "level" 00030 #define NLVL 2 00031 00032 /* Names of things. */ 00033 #define PRES_NAME "pressure" 00034 #define TEMP_NAME "temperature" 00035 #define UNITS "units" 00036 #define DEGREES_EAST "degrees_east" 00037 #define DEGREES_NORTH "degrees_north" 00038 00039 /* These are used to construct some example data. */ 00040 #define SAMPLE_PRESSURE 900 00041 #define SAMPLE_TEMP 9.0 00042 #define START_LAT 25.0 00043 #define START_LON -125.0 00044 00045 /* For the units attributes. */ 00046 #define UNITS "units" 00047 #define PRES_UNITS "hPa" 00048 #define TEMP_UNITS "celsius" 00049 #define LAT_UNITS "degrees_north" 00050 #define LON_UNITS "degrees_east" 00051 #define MAX_ATT_LEN 80 00052 00053 /* Handle errors by printing an error message and exiting with a 00054 * non-zero status. */ 00055 #define ERR(e) {printf("Error: %s\n", nc_strerror(e)); return 2;} 00056 00057 int 00058 main() 00059 { 00060 /* IDs for the netCDF file, dimensions, and variables. */ 00061 int ncid, lon_dimid, lat_dimid, lvl_dimid, rec_dimid; 00062 int lat_varid, lon_varid, pres_varid, temp_varid; 00063 int dimids[NDIMS]; 00064 00065 /* The start and count arrays will tell the netCDF library where to 00066 write our data. */ 00067 size_t start[NDIMS], count[NDIMS]; 00068 00069 /* Program variables to hold the data we will write out. We will only 00070 need enough space to hold one timestep of data; one record. */ 00071 float pres_out[NLVL][NLAT][NLON]; 00072 float temp_out[NLVL][NLAT][NLON]; 00073 00074 /* These program variables hold the latitudes and longitudes. */ 00075 float lats[NLAT], lons[NLON]; 00076 00077 /* Loop indexes. */ 00078 int lvl, lat, lon, rec, i = 0; 00079 00080 /* Error handling. */ 00081 int retval; 00082 00083 /* Create some pretend data. If this wasn't an example program, we 00084 * would have some real data to write, for example, model 00085 * output. */ 00086 for (lat = 0; lat < NLAT; lat++) 00087 lats[lat] = START_LAT + 5.*lat; 00088 for (lon = 0; lon < NLON; lon++) 00089 lons[lon] = START_LON + 5.*lon; 00090 00091 for (lvl = 0; lvl < NLVL; lvl++) 00092 for (lat = 0; lat < NLAT; lat++) 00093 for (lon = 0; lon < NLON; lon++) 00094 { 00095 pres_out[lvl][lat][lon] = SAMPLE_PRESSURE + i; 00096 temp_out[lvl][lat][lon] = SAMPLE_TEMP + i++; 00097 } 00098 00099 /* Create the file. */ 00100 if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid))) 00101 ERR(retval); 00102 00103 /* Define the dimensions. The record dimension is defined to have 00104 * unlimited length - it can grow as needed. In this example it is 00105 * the time dimension.*/ 00106 if ((retval = nc_def_dim(ncid, LVL_NAME, NLVL, &lvl_dimid))) 00107 ERR(retval); 00108 if ((retval = nc_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid))) 00109 ERR(retval); 00110 if ((retval = nc_def_dim(ncid, LON_NAME, NLON, &lon_dimid))) 00111 ERR(retval); 00112 if ((retval = nc_def_dim(ncid, REC_NAME, NC_UNLIMITED, &rec_dimid))) 00113 ERR(retval); 00114 00115 /* Define the coordinate variables. We will only define coordinate 00116 variables for lat and lon. Ordinarily we would need to provide 00117 an array of dimension IDs for each variable's dimensions, but 00118 since coordinate variables only have one dimension, we can 00119 simply provide the address of that dimension ID (&lat_dimid) and 00120 similarly for (&lon_dimid). */ 00121 if ((retval = nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid, 00122 &lat_varid))) 00123 ERR(retval); 00124 if ((retval = nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid, 00125 &lon_varid))) 00126 ERR(retval); 00127 00128 /* Assign units attributes to coordinate variables. */ 00129 if ((retval = nc_put_att_text(ncid, lat_varid, UNITS, 00130 strlen(DEGREES_NORTH), DEGREES_NORTH))) 00131 ERR(retval); 00132 if ((retval = nc_put_att_text(ncid, lon_varid, UNITS, 00133 strlen(DEGREES_EAST), DEGREES_EAST))) 00134 ERR(retval); 00135 00136 /* The dimids array is used to pass the dimids of the dimensions of 00137 the netCDF variables. Both of the netCDF variables we are 00138 creating share the same four dimensions. In C, the 00139 unlimited dimension must come first on the list of dimids. */ 00140 dimids[0] = rec_dimid; 00141 dimids[1] = lvl_dimid; 00142 dimids[2] = lat_dimid; 00143 dimids[3] = lon_dimid; 00144 00145 /* Define the netCDF variables for the pressure and temperature 00146 * data. */ 00147 if ((retval = nc_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS, 00148 dimids, &pres_varid))) 00149 ERR(retval); 00150 if ((retval = nc_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS, 00151 dimids, &temp_varid))) 00152 ERR(retval); 00153 00154 /* Assign units attributes to the netCDF variables. */ 00155 if ((retval = nc_put_att_text(ncid, pres_varid, UNITS, 00156 strlen(PRES_UNITS), PRES_UNITS))) 00157 ERR(retval); 00158 if ((retval = nc_put_att_text(ncid, temp_varid, UNITS, 00159 strlen(TEMP_UNITS), TEMP_UNITS))) 00160 ERR(retval); 00161 00162 /* End define mode. */ 00163 if ((retval = nc_enddef(ncid))) 00164 ERR(retval); 00165 00166 /* Write the coordinate variable data. This will put the latitudes 00167 and longitudes of our data grid into the netCDF file. */ 00168 if ((retval = nc_put_var_float(ncid, lat_varid, &lats[0]))) 00169 ERR(retval); 00170 if ((retval = nc_put_var_float(ncid, lon_varid, &lons[0]))) 00171 ERR(retval); 00172 00173 /* These settings tell netcdf to write one timestep of data. (The 00174 setting of start[0] inside the loop below tells netCDF which 00175 timestep to write.) */ 00176 count[0] = 1; 00177 count[1] = NLVL; 00178 count[2] = NLAT; 00179 count[3] = NLON; 00180 start[1] = 0; 00181 start[2] = 0; 00182 start[3] = 0; 00183 00184 /* Write the pretend data. This will write our surface pressure and 00185 surface temperature data. The arrays only hold one timestep worth 00186 of data. We will just rewrite the same data for each timestep. In 00187 a real application, the data would change between timesteps. */ 00188 for (rec = 0; rec < NREC; rec++) 00189 { 00190 start[0] = rec; 00191 if ((retval = nc_put_vara_float(ncid, pres_varid, start, count, 00192 &pres_out[0][0][0]))) 00193 ERR(retval); 00194 if ((retval = nc_put_vara_float(ncid, temp_varid, start, count, 00195 &temp_out[0][0][0]))) 00196 ERR(retval); 00197 } 00198 00199 /* Close the file. */ 00200 if ((retval = nc_close(ncid))) 00201 ERR(retval); 00202 00203 printf("*** SUCCESS writing example file %s!\n", FILE_NAME); 00204 return 0; 00205 }