/* This is part of the netCDF package. Copyright 2006 University Corporation for Atmospheric Research/Unidata. See COPYRIGHT file for conditions of use. This is a simple example which writes and then reads some surface pressure and temperatures, and stores additional metadata as dimension variables, an attribute. $Id: sfc_pres_temp_more.c,v 1.2 2006/03/25 15:57:55 ed Exp $ */ #include #define FILE_NAME basic1.nc #define NDIMS 2 #define LAT_NAME "latitude" #define LAT_LEN 40 #define LON_NAME "longitude" #define LON_LEN 80 #define PRES_NAME "surface_pressure" #define TEMP_NAME "surface_temperature" #define SONNET_NAME "Brownings_sonnet_mangled_by_Hartnett" char data_poem[] = "How do I love data? Let me count the ways.\n I love data to the depth and breadth and height\n My model can reach, when running overnight\n From the ends of CONUS and ideal Space.\n I love data to the level of every day's\n 6Z ob, by Sun and Linux box.\n I love data freely, as PIs strive for funding;\n I love data purely, as good C code is compiled,\n I love data with the passion put to use\n In my old programs, and with my childhood's TRS-80.\n I love data with a love I seemed to lose\n With my lost password -I love data with the constants,\n expressions, statements, of all my code! -and, if NSF choose,\n I shall love data better after processing."; int main() { int ncid, lon_dimid, lat_dimid, pres_varid, temp_varid; int dimids[NDIMS]; float pres_out[LAT_LEN][LON_LEN], pres_in[LAT_LEN][LON_LEN]; float temp_out[LAT_LEN][LON_LEN], temp_in[LAT_LEN][LON_LEN]; char *att_in; size_t len_in; int error = 0; int lat, lon, retval; /* Create phoney data. If this wasn't an example program, we would * have some real data to write, for example, model output. */ for (lat = 0; lat < LAT_LEN; lat++) for (lon = 0; lon < LON_LEN; lon++) { pres_out[lat][lon] = 1013.1; temp_out[lat][lon] = 12.5; } /* These are the latitudes and longitudes which corespond with * ticks on the dimension axes. */ for (lat = 0; lat < LAT_LEN; lat++) latitude[lat] = 40. + lat * 2.5; for (lon = 0; lon < LON_LEN; lon++) longitude[lon] = -90. - lon * 5; /* Create the file. */ if ((retval = nc_create(FILE_NAME, NC_CLOBBER, &ncid))) return retval; /* Add data sonnet. By using NC_GLOBAL we mean that this attribute * applies to the entire file, not just to one variable. Don't * forget that sizeof does not include the null terminator, so if * you want it, you need to add one more byte. */ if ((retval = nc_put_att_text(ncid, NC_GLOBAL, SONNET_NAME, sizeof(poem) + 1, poem))) return retval; /* Define the dimensions. */ if ((retval = nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid))) return retval; if ((retval = nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid))) return retval; /* Save the dimension information, in variables of the same * name. First we need to define these variables. */ dimids[0] = lat_dimid; if ((retval = nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid))) return retval; dimids[0] = lon_dimid; if ((retval = nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid))) return retval; /* Define the variables. */ dimids[0] = lat_dimid; dimids[1] = lon_dimid; if ((retval = nc_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS, dimids, &pres_varid))) return retval; if ((retval = nc_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS, dimids, &temp_varid))) return retval; /* End define mode. */ if ((retval = nc_enddef(ncid))) return retval; /* Write the dimension metadata. */ if ((retval = nc_put_var_float(ncid, lat_varid, latitude_out))) return retval; if ((retval = nc_put_var_float(ncid, lon_varid, longitude_out))) return retval; /* Write the phoney data. */ if ((retval = nc_put_var_float(ncid, pres_varid, pres_out))) return retval; if ((retval = nc_put_var_float(ncid, temp_varid, temp_out))) return retval; /* Close the file. */ if ((retval = nc_close(ncid))) return retval; /* Open the file and check that everything's OK. */ if ((retval = nc_open(FILE_NAME, 0, &ncid))) return retval; /* Read the attribute. First find it's length to allocate storage * for it. */ if ((retval = nc_inq_attlen(ncid, NC_GLOBAL, SONNET_NAME, &len_in))) return retval; if (!(att_in = malloc(len_in))) return NC_ENOMEM; if (strcmp(att_in, data_poem)) error++; free(att_in); if (error) return -2; /* Read the data. */ if ((retval = nc_get_var_float(ncid, pres_varid, pres_in))) return retval; if ((retval = nc_get_var_float(ncid, temp_varid, temp_in))) return retval; /* Check the data. */ for (lat = 0; lat < LAT_LEN; lat++) for (lon = 0; lon < LON_LEN; lon++) if (pres_in[lat][lon] != pres_out[lat][lon] || temp_in[lat][lon] != temp_out[lat][lon]) return -2; /* Close the file. */ if ((retval = nc_close(ncid))) return retval; return 0; }