/*************************************************************/ /* */ /* Program: netcdf2ascii.c */ /* */ /* Paul A. Kucera */ /* National Center for Atmospheric Research */ /* Research Application Laboratory */ /* P.O. Box 3000 */ /* Boulder, CO 80307 */ /* pkucera@ucar.edu */ /* */ /* Started: 17 FEB 2005 */ /* Working: 18 FEB 2005 */ /* Modified: 20 JUN 2008 */ /* */ /* This program reads in netCDF formatted Cartesian radar */ /* files and creates a simple ascii formatted file. This */ /* code was originally created to read in netCDF format */ /* radar products from NPOL during CRYSTAL FACE */ /* ascii file. */ /*************************************************************/ /* 06/20/08: Updated code for NAMMA and made the code more */ /* flexible in terms fo the inputs. */ /*************************************************************/ #include /********************************** */ #include /* */ #include /* */ #include /* Not all are used in this program */ #include /* */ #include /* */ #include /* */ #include /* */ #include /********************************** */ #define YES 1 #define NO 0 /* No longer hardwired #define X 450 #define Y 450 */ /** command option variables **/ extern char *optarg; extern int optind, opterr; char *options = "i:h:S:x:y:"; /** internal functions **/ void file_open(FILE *(*in_ptr), char *in_name, char *file_type); /*** functions ***/ void file_open(FILE *(*in_ptr), char *in_name, char *file_type) { if(((*in_ptr) = fopen(in_name, file_type)) == NULL) { printf("Can't open file: %s\n", in_name); printf("Exiting program now...\n"); exit(0); } return; } void handle_error(int status) { if (status != NC_NOERR) { fprintf(stderr, "%s\n", nc_strerror(status)); exit(0); } return; } FILE *fp; main(int argc,char *argv[]) { static size_t start[] = {0,0}; static size_t size_index[] = {1}; /** Variable List **/ size_t length; int i, j, a, k, x_dim, y_dim, count[2]; int ncid, status, short_yr, y_len, x_len, cnt, cnt1, check; int valid, yrid, mmid, ddid, hrid, mnid, lvlid, nlvlid; int yr, mm, dd, hr, mn, num_of_lvls, level; int XDIM, YDIM; float lvl[25], **recovered_val, **values, *aptr, hgt; float ascii_values[800][800]; char outfile[200], infile[200], sitename[10], type[5]; char type1[2], infile_char[50]; /** Initialize variables **/ cnt = 1; cnt1 = 0; check = 0; /** Testing the # of parameters on the command line **/ if(argc < 11) { printf("Wrong number of arguments...\n\n"); printf("The command line should include the following:\n"); printf("netcdf2ascii -i input_file -h height -x x_grid_size "); printf("-y y_grid_size -S Sitename\n"); printf("Required command line options:\n"); printf("Defn: i : Input ASCII Grid File\n"); printf(" h : Height to extract(enter 0 for all heights)\n"); printf(" x : X grid size\n"); printf(" y : Y grid size\n"); printf(" S : Sitename: NPOL...etc\n"); printf("Try again...\n"); exit(0); } /** Extracting command line information **/ while((a = getopt(argc, argv, options)) != -1) { switch(a) { case 'i': strcpy(infile, optarg); break; case 'h': sscanf(optarg, "%f", &hgt); break; case 'x': sscanf(optarg, "%d", &XDIM); break; case 'y': sscanf(optarg, "%d", &YDIM); break; case 'S': strcpy(sitename, optarg); break; default: printf("\nUnknown usage...\n"); printf("Leaving program...\n"); exit(0); } } /** Open net cdf file for reading **/ status = nc_open(infile, NC_NOWRITE, &ncid); if (status != NC_NOERR) handle_error(status); /** Get map dimensions **/ status = nc_inq_dimid(ncid, "MAP_X", &valid); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid, valid, &x_dim); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimid(ncid, "MAP_Y", &valid); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid, valid, &y_dim); if (status != NC_NOERR) handle_error(status); /**Set count variable for printing **/ count[0] = y_dim; count[1] = x_dim; /** Get Year from File **/ status = nc_inq_varid(ncid, "YEAR", &yrid); if (status != NC_NOERR) handle_error(status); status = nc_get_var1_int(ncid, yrid, size_index, &yr); if (status != NC_NOERR) handle_error(status); /** Get Month from File **/ status = nc_inq_varid(ncid, "MONTH", &mmid); if (status != NC_NOERR) handle_error(status); status = nc_get_var1_int(ncid, mmid, size_index, &mm); if (status != NC_NOERR) handle_error(status); /** Get Day from File **/ status = nc_inq_varid(ncid, "DAY", &ddid); if (status != NC_NOERR) handle_error(status); status = nc_get_var1_int(ncid, ddid, size_index, &dd); if (status != NC_NOERR) handle_error(status); /** Get Hour from File **/ status = nc_inq_varid(ncid, "HOUR", &hrid); if (status != NC_NOERR) handle_error(status); status = nc_get_var1_int(ncid, hrid, size_index, &hr); if (status != NC_NOERR) handle_error(status); /** Get Minute from File **/ status = nc_inq_varid(ncid, "MINUTE", &mnid); if (status != NC_NOERR) handle_error(status); status = nc_get_var1_int(ncid, mnid, size_index, &mn); if (status != NC_NOERR) handle_error(status); /** Get level numbers from File **/ status = nc_inq_varid(ncid, "HGTS", &lvlid); if (status != NC_NOERR) handle_error(status); status = nc_get_var_float(ncid, lvlid, lvl); if (status != NC_NOERR) handle_error(status); /** Get number of levels from File **/ status = nc_inq_varid(ncid, "NUMBER_OF_LVLS", &nlvlid); if (status != NC_NOERR) handle_error(status); status = nc_get_var1_int(ncid, nlvlid, size_index, &num_of_lvls); if (status != NC_NOERR) handle_error(status); if (hgt != 0.0) { /** Finding level in data set corresponding to height input **/ for (i = 0; i <= num_of_lvls; i++) { if (lvl[i] == hgt) { level = (i+1); check = YES; } } if (check == NO) { printf("No data avalible at specified height!\n"); printf("Exiting!!!\n"); exit(0); } } /** Allocate memory for recovered values from net cdf file **/ aptr = malloc(y_dim * x_dim * sizeof(float)); values = malloc(y_dim * sizeof(float *)); for(k = 0; k < y_dim; k++) values[k] = aptr + (k * x_dim); /** Get data from File **/ status = nc_inq_varid(ncid, "VALUE", &valid); if (status != NC_NOERR) handle_error(status); status = nc_get_vara_float(ncid, valid, start, count, *values); if (status != NC_NOERR) handle_error(status); /** Testing the year **/ if (yr == 2002) short_yr = yr - 2000; else short_yr = yr; /** Gathering the type of infile **/ length = strlen(infile); /** Finding type of file **/ sscanf(infile, "%s", &infile_char); sprintf(type,"%c%c",infile_char[length-5],infile_char[length-4]); if(hgt == 0.0) { /** Creating outputfile **/ sprintf(outfile,"%s_%02d%02d%02d_%02d%02d_%s.ascii",sitename,short_yr,mm,dd,hr,mn,type); } else { /** Creating outputfile **/ sprintf(outfile,"%s_%02d%02d%02d_%02d%02d_%dkm%s.ascii",sitename,short_yr,mm,dd,hr,mn,(int)hgt,type); } /** Open output file for writing **/ file_open(&fp, outfile, "w"); /** Print Headers **/ fprintf(fp, "%02d %02d %d %02d %02d\n",mm, dd, yr, hr, mn); if (hgt == 0.0) { fprintf(fp, "%d %d %d\n", num_of_lvls, x_dim, (y_dim/num_of_lvls)); for (i = 0; i < num_of_lvls; i++) { if( i == (num_of_lvls - 1)) fprintf(fp, "%3.1f\n", lvl[i]); else fprintf(fp, "%3.1f ", lvl[i]); } } else { fprintf(fp, "%d %d %d\n", 1, x_dim, (y_dim/num_of_lvls)); fprintf(fp, "%3.1f\n", hgt); } if (hgt == 0.0) { /** Sort through recovered values and print all values to output file **/ for (i = 0; i < y_dim; i++) for (j = 0; j < x_dim; j++) { if (j == XDIM-1) fprintf(fp, "%6.1f\n", values[i][j]); else fprintf(fp, "%6.1f ", values[i][j]); } } else { /** Sorting through the correct levels **/ for(i = 0; i < y_dim; i++) { if ((i >= (YDIM*(level-1)))&&(i <= (YDIM*level))) { for(j = 0; j < x_dim; j++) { ascii_values[cnt1][j] = values[i][j]; } cnt1++; } } /** Printing selected height data values to ascii file **/ for (i = 0; i < YDIM; i++) for (j = 0; j < XDIM; j++) { if (j == XDIM-1) fprintf(fp, "%6.1f\n", ascii_values[i][j]); else fprintf(fp, "%6.1f ", ascii_values[i][j]); } } /** Close files **/ fclose(fp); status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); printf("Finish processing file %s!\n",infile); }