/** @file ascii2nc.c * @brief Stand alone executable to tranform ASCII to DD netCDF * @version $Id: ascii2nc.c,v 1.8 2011/09/05 11:26:55 budnik Exp $ * @arg FileName, [any symbol] * 2 args => DOY2DDTime; 3 args => MonthDay2DDTime */ #include #include #include #include #include #include #include #include #define MAX_FILE_NAME_LEN 120 /* Max. file name length */ #define MAXLEN 4096 /************************************* Global variables and structures **************************************/ int ncid; /*netCDF file ID*/ char Time[TIMELENGTH]; char *StartT; // Start time char *StopT; // Stop time size_t TimeCount[2] = {1L, TIMELENGTH}; size_t Start[2] = {0L, 0L}; size_t buffCount[2]; /************************** Function prototypes **************************/ void handle_netcdf_error (int); void mapskp2DD(char *buffer, char *Time); void monthday2DD(char *buffer, char *Time); /**************************************************************************** *****************************************************************************/ int main(int argc, char *argv[]) { FILE *inFile; int status, /* netCDF status code */ dummy, i, j, n; int ndims, nvars, ngatts, unlimitdimid; int var_ndims, var_dims[NC_MAX_DIMS], var_natts; nc_type var_type, t_type; char var_name[NC_MAX_NAME+1]; size_t dimsize, t_length; int First = 1; char fileName[MAX_FILE_NAME_LEN]; char *buffer, *tempBuff; float buffFloat[NC_MAX_DIMS][NC_MAX_DIMS], attFloat; double buffDouble[NC_MAX_DIMS][NC_MAX_DIMS], attDouble; int buffInt[NC_MAX_DIMS][NC_MAX_DIMS], attInt; size_t buffSize[NC_MAX_DIMS]; nc_type buffType[NC_MAX_DIMS]; double deltaT, ddTime; buffer = (char *)malloc(MAXLEN*sizeof(char)); tempBuff = buffer; buffCount[0] = 1L; if (argc <= 1) { printf ("** inputFile file is not specified **\n"); /* input file name not specified */ exit (1); } else { strcpy(fileName, argv[1]); /* Get the input file name */ } /***********************************************/ /* Open Input File */ /***********************************************/ if ((inFile = fopen(fileName, "r")) == NULL) { printf ("** Cannot open inputFile file: %s **\n", fileName); exit (1); } status = nc_open("temp.nc", NC_WRITE, &ncid); if (status != NC_NOERR) { handle_netcdf_error(status); exit (1); } // Now inquire status = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimitdimid); // printf (" ndims %d, nvars %d, ngatts %d, unlimitdimid %d\n",ndims, nvars, ngatts, unlimitdimid); for (i = 0; i < nvars; i++) { status = nc_inq_var(ncid, i, var_name, &var_type, &var_ndims, var_dims, &var_natts); if (status != NC_NOERR) handle_netcdf_error(status); // printf ("\n varname %s, var_type %d, var_ndims %d, var_natts %d ", // var_name, var_type, var_ndims, var_natts); if ( var_ndims == 1 ) buffSize[i] = 1; else { status = nc_inq_dimlen(ncid, var_dims[1], &dimsize); buffSize[i] = dimsize; } buffType[i] = var_type; } status = nc_inq_att(ncid, NC_GLOBAL, "minSampling", &t_type, &t_length); if (status != NC_NOERR) deltaT = 0.0; else switch (t_type) { case NC_FLOAT: status = nc_get_att_float(ncid, NC_GLOBAL, "minSampling", &attFloat); deltaT = (double)(attFloat)/2.0 ; break; case NC_DOUBLE: status = nc_get_att_double(ncid, NC_GLOBAL, "minSampling", &attDouble); deltaT = attDouble/2.0; break; case NC_INT: status = nc_get_att_int(ncid, NC_GLOBAL, "minSampling", &attInt); deltaT = (double)attInt/2.0; break; default: status = nc_get_att_float(ncid, NC_GLOBAL, "minSampling", &attFloat); deltaT = (double)(attFloat)/2.0 ; } // printf (" deltaT %lf\n", deltaT); /*********************************************************************** ***********************************************************************/ // Skip first line in RPWS_KEY.... if (strncmp(fileName,"RPWS_KEY",8) == 0) fgets(buffer, MAXLEN, inFile); while (!feof(inFile) && !ferror(inFile)) { fgets(buffer, MAXLEN, inFile); if (strlen(buffer) > 10 && !feof(inFile)) { if (argc > 2) monthday2DD(buffer, Time); else mapskp2DD(buffer, Time); status = nc_put_vara_text(ncid, 0, Start, TimeCount, Time); if (First) { // add +/- deltaT from attribute.... ddTime = DD_Time2Double(Time); StartT = Double2DD_Time(ddTime - deltaT); status = nc_put_vara_text(ncid, 1, &Start[1], &TimeCount[1], StartT); } First = 0; // Time variables are defined already for (i = 3; i < nvars; i++) { for (j = 0; j < buffSize[i]; j++) { while (isspace(buffer[0])) buffer++; buffer = strpbrk(buffer," "); switch (buffType[i]) { case NC_FLOAT: sscanf(buffer, "%f", &buffFloat[i][j]); break; case NC_DOUBLE: sscanf(buffer, "%lf", &buffDouble[i][j]); break; case NC_INT: sscanf(buffer, "%d", &buffInt[i][j]); break; default: sscanf(buffer, "%f", &buffFloat[i][j]); } buffCount[1] = buffSize[i]; switch (buffType[i]) { case NC_FLOAT: status = nc_put_vara_float(ncid, i, Start, buffCount, &(buffFloat[i][0])); break; case NC_DOUBLE: status = nc_put_vara_double(ncid, i, Start, buffCount, &(buffDouble[i][0])); break; case NC_INT: status = nc_put_vara_int(ncid, i, Start, buffCount, &(buffInt[i][0])); break; default: status = nc_put_vara_float(ncid, i, Start, buffCount, &(buffFloat[i][0])); } } } Start[0]++; // return pointer to the beginning buffer = tempBuff; } // if ! "\n" } // add +/- deltaT from attribute.... ddTime = DD_Time2Double(Time); StopT = Double2DD_Time(ddTime + deltaT - 1.0); status = nc_put_vara_text(ncid, 2, &Start[1], &TimeCount[1], StopT); status = nc_close(ncid); if (status != NC_NOERR) handle_netcdf_error(status); fclose(inFile); } /*-------------------------------------------------------------------------- * Handles a netCDF error. *--------------------------------------------------------------------------*/ void handle_netcdf_error(int status) { fprintf(stderr, "%s\n", nc_strerror(status)); } /*-------------------------------------------------------------------------- * MAPSKP time to DD *--------------------------------------------------------------------------*/ void mapskp2DD(char *buffer, char *Time) { int err; int YEAR, DAY, HOUR, MINUTE, SEC, MSK = 0; err = sscanf(buffer, "%d-%dT%d:%d:%d.%d", &YEAR, &DAY, &HOUR, &MINUTE, &SEC, &MSK); if (err == 5) MSK = 0; sprintf(Time,"%04d%03d%02d%02d%02d%03d\0", YEAR, DAY-1, HOUR, MINUTE, SEC, MSK); } /*-------------------------------------------------------------------------- * MONTH-DAY time to DD *--------------------------------------------------------------------------*/ void monthday2DD(char *buffer, char *Time) { int days[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int i, YEAR, MONTH, DAY, HOUR, MINUTE, SEC, MSK, DOY=0; sscanf(buffer, "%d-%d-%dT%d:%d:%d.%d", &YEAR, &MONTH, &DAY, &HOUR, &MINUTE, &SEC, &MSK); // Leap year // if ((YEAR % 4 == 0) && (YEAR % 100 != 0)) days[1] += 1; if (YEAR % 4 == 0) days[1] += 1; // if (YEAR % 400 == 0) // if (YEAR == 2000) days[1] += 1; // Sum of days from Jan 1 to the input date for (i = 0; i < MONTH - 1; i++) DOY += days[i]; DOY += DAY; sprintf(Time,"%04d%03d%02d%02d%02d%03d\0", YEAR, DOY-1, HOUR, MINUTE, SEC, MSK); }