/* CENTER FOR OCEAN-ATMOSPHERIC PREDICTION STUDIES, THE FLORIDA STATE UNIVERSITY DIRECT ALL QUESTIONS TO: nscat-anim@coaps.fsu.edu ******************************************************************* Function: readncdf_vort Author: Jiangyi Hu Date: June 3, 2008 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), V(LAT, LON) AND VORT(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 NINE 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 ***vort Holds the vorticity 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, v and vort are returned they will 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,v and vort values to the screen with their respective latitude and longitude values. ----------------------------- #include #include "/usr/local/include/netcdf.h" #include "readncdf_vort.c" int main() { char *input; float **u, **v, **vort, *lat, *lon; int i, j, latsize, lonsize; float missing = 9999.0; input = "QSCAT_Indian_200812000.nc"; readncdf_vort(input, &u, &v, &vort, &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, %8.2f)\n", lat[i], lon[j], u[i][j], v[i][j], vort[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_vort(char *input, float ***u, float ***v, float ***vort, int *lat_num, int *lon_num, float **lat, float **lon, float missing) { int ncid, u_id, v_id, vort_id, latid, lonid; int i, j, usf_len, vsf_len, um_len, vm_len, vortm_len; long latsize, lonsize; short *u_out, *v_out, *u_miss, *v_miss; float *vort_out, *vort_miss; nc_type usf_type, vsf_type, um_type, vm_type, vortm_type; float *u_sfactor, *v_sfactor, u_miss_fl, v_miss_fl, vort_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, v and vort 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); vort_out = (float *)malloc(sizeof(float) * 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; } (*vort) = (float **)malloc( sizeof(float *) * (sizeof(float *) * latsize) ); (*vort)[0] = (float *)malloc( sizeof(float) * (sizeof(float)*latsize*lonsize) ); for (i = 1; i < latsize; i++) { (*vort)[i] = (*vort)[0] + i*lonsize; } /* Gets the u, v and vort values from the opened file, plus their scale factors and missing values */ u_id = ncvarid(ncid, "u"); v_id = ncvarid(ncid, "v"); vort_id = ncvarid(ncid, "vort"); ncvarget(ncid, u_id, start, count, (void *) u_out); ncvarget(ncid, v_id, start, count, (void *) v_out); ncvarget(ncid, vort_id, start, count, (void *) vort_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); ncattinq (ncid, vort_id, "missing_value", &vortm_type, &vortm_len); u_miss = (short*) malloc(um_len * nctypelen(um_type)); v_miss = (short*) malloc(vm_len * nctypelen(vm_type)); vort_miss = (float*) malloc(vortm_len * nctypelen(vortm_type)); ncattget(ncid, u_id, "missing_value", (void *)(u_miss)); ncattget(ncid, v_id, "missing_value", (void *)(v_miss)); ncattget(ncid, vort_id, "missing_value", (void *)(vort_miss)); /* Multiplies by the scale factor */ u_miss_fl = (float)*u_miss; v_miss_fl = (float)*v_miss; vort_miss_fl = (float)*vort_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]; (*vort)[i][j] = (float)vort_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; if ((*vort)[i][j] == vort_miss_fl) (*vort)[i][j] = missing; } } free(u_out); free(v_out); free(vort_out); free(u_sfactor); free(v_sfactor); free(u_miss); free(v_miss); free(vort_miss); /* Closes *.nc file */ ncclose(ncid); }