/* CENTER FOR OCEAN-ATMOSPHERIC PREDICTION STUDIES, THE FLORIDA STATE UNIVERSITY DIRECT ALL QUESTIONS TO: nscat-anim@coaps.fsu.edu Modifications: ******************************************************* Author : Josh Grant Date : July 5th, 2001 Version : 1.2 Description: Added one argument to the function. Now the function is called with 8 arguments. The last argument added is used for setting the missing values of the dataset. This argument list is getting longer than I would like and the function might be completely changed very soon. ********************************************************************** Modifications: ******************************************************* Author : Josh Grant Date : February 15th, 2001 Version : 1.1 Description: Added two arguments to the function. Now the function is called with 7 arguments. The last two were added to store the latitude and longitude values of the points. Updated the example program below to reflect the new changes. ********************************************************************** ******************************************************************* Function: readncdf Author: Josh Grant Date: September 1st, 2000 Version: 1.0 Purpose: Reads a gridded NetCDF file and stores in arrays ******************************************************************* DATA IN MATRIX BEGINS IN SOUTHERN HEMISPHERE. 'LAT' IS THE DIMENSION OF THE VERTICAL WHILE 'LON' IS THE DIMENSION OF THE HORIZONTAL. MATRICES U(LAT, LON) AND V(LAT, LON) BEGIN AT THE UPPER LEFT-HAND PORTION OF THE MATRIX (REPRESENTING THE SOUTHWESTERN CORNER OF THE WORLD MAP) AND END AT THE LOWER RIGHT-HAND PORTION OF THE MATRIX (REPRESENTING THE NORTHEASTERN CORNER OF THE WORLD MAP) THERE ARE EIGHT INPUTS FOR THIS FUNCTION input Name of the NetCDF file you wish to read ***u Holds the u wind component values as a 2D array ***v Holds the v wind component values as a 2D array *lat_num Holds the total number of latitudes *lon_num Holds the total number of longitudes **lat Holds the latitude values in an array of size lat_num **lon Holds the longitude values in an array of size lon_num missing the value you would like all missing values set to When u and v are returned they will both have dimensions lat x lon and the values are accessed with the conventional double bracket method. For the value at lat = 5, lon = 100... float value = u[5][100]; Example: Prints all the u and v component values to the screen with their respective latitude and longitude values. ----------------------------- #include #include "/usr/local/include/netcdf.h" #include "readncdf.c" int main() { char *input; float **u, **v, *lat, *lon; int i, j, latsize, lonsize; float missing = 9999.0; input = "qdir/gcv_QSCAT_2000025.nc"; readncdf(input, &u, &v, &latsize, &lonsize, &lat, &lon, missing); for(i = 0; i < latsize; i++) { for(j = 0; j < lonsize; j++) { printf("%6.2f, %6.2f = (%8.2f, %8.2f)\n", lat[i], lon[j], u[i][j], v[i][j]); } } return 0; } ----------------------------- When compiling the entire project you will need to include the library: -L/usr/local/netcdf/lib32 -lnetcdf or if using object 64 code -L/usr/local/netcdf/lib64 -lnetcdf */ /* This might need to be modified to point to your system's copy of netcdf.h */ #include "/usr/local/include/netcdf.h" void readncdf(char *input, float ***u, float ***v, int *lat_num, int *lon_num, float **lat, float **lon, float missing) { int ncid, u_id, v_id, latid, lonid; int i, j, usf_len, vsf_len, um_len, vm_len; long latsize, lonsize; short *u_out, *v_out, *u_miss, *v_miss; nc_type usf_type, vsf_type, um_type, vm_type; float *u_sfactor, *v_sfactor, u_miss_fl, v_miss_fl; static long start[] = {0, 0}; static long count[] = {0, 0}; /* Opens NetCDF for reading and other two files for writing. */ ncid = ncopen(input, NC_NOWRITE); latid = ncdimid(ncid, "lat"); ncdiminq(ncid, latid, (char *)0, &latsize); count[0] = latsize; *lat_num = latsize; lonid = ncdimid(ncid, "lon"); ncdiminq(ncid, lonid, (char *)0, &lonsize); count[1] = lonsize; *lon_num = lonsize; (*lat) = (float *)malloc(sizeof(float) * latsize); (*lon) = (float *)malloc(sizeof(float) * lonsize); latid = ncvarid(ncid, "lat"); lonid = ncvarid(ncid, "lon"); ncvarget (ncid, latid, &(start[0]), &(count[0]), (void *) (*lat)); ncvarget (ncid, lonid, &(start[0]), &(count[1]), (void *) (*lon)); /*The below garbage is used to dynamically allocate the u and v arrays and keep the conventional double subscript of 2D arrays. Unless you know what you are doing, I would suggest not changing this code.*/ u_out = (short *)malloc(sizeof(short) * latsize * lonsize); v_out = (short *)malloc(sizeof(short) * latsize * lonsize); (*u) = (float **)malloc( sizeof(float *) * (sizeof(float *) * latsize) ); (*u)[0] = (float *)malloc( sizeof(float) * (sizeof(float)*latsize*lonsize) ); for (i = 1; i < latsize; i++) { (*u)[i] = (*u)[0] + i*lonsize; } (*v) = (float **)malloc( sizeof(float *) * (sizeof(float *) * latsize) ); (*v)[0] = (float *)malloc( sizeof(float) * (sizeof(float)*latsize*lonsize) ); for (i = 1; i < latsize; i++) { (*v)[i] = (*v)[0] + i*lonsize; } /* Gets the u and v values from the opened file, plus their scale factors and missing values */ u_id = ncvarid(ncid, "u"); v_id = ncvarid(ncid, "v"); ncvarget(ncid, u_id, start, count, (void *) u_out); ncvarget(ncid, v_id, start, count, (void *) v_out); ncattinq (ncid, u_id, "scale_factor", &usf_type, &usf_len); ncattinq (ncid, v_id, "scale_factor", &vsf_type, &vsf_len); u_sfactor = (float*) malloc(usf_len * nctypelen(usf_type)); v_sfactor = (float*) malloc(vsf_len * nctypelen(vsf_type)); ncattget(ncid, u_id, "scale_factor", (void *)(u_sfactor)); ncattget(ncid, v_id, "scale_factor", (void *)(v_sfactor)); ncattinq (ncid, u_id, "missing_value", &um_type, &um_len); ncattinq (ncid, v_id, "missing_value", &vm_type, &vm_len); u_miss = (short*) malloc(um_len * nctypelen(um_type)); v_miss = (short*) malloc(vm_len * nctypelen(vm_type)); ncattget(ncid, u_id, "missing_value", (void *)(u_miss)); ncattget(ncid, v_id, "missing_value", (void *)(v_miss)); /* Multiplies by the scale factor */ u_miss_fl = (float)*u_miss; v_miss_fl = (float)*v_miss; for(i = 0; i < latsize; i++) { for(j = 0; j < lonsize; j++) { (*u)[i][j] = (float)u_out[i*lonsize + j]; (*v)[i][j] = (float)v_out[i*lonsize + j]; if ((*u)[i][j] != u_miss_fl) (*u)[i][j] = (*u)[i][j] * (*u_sfactor); else (*u)[i][j] = missing; if ((*v)[i][j] != v_miss_fl) (*v)[i][j] = (*v)[i][j] * (*v_sfactor); else (*v)[i][j] = missing; } } free(u_out); free(v_out); free(u_sfactor); free(v_sfactor); free(u_miss); free(v_miss); /* Closes *.nc file */ ncclose(ncid); }