ascii2nc.c 8.61 KB

/** @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 <stdio.h>
#include <stdlib.h>
#include <netcdf.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#include <DD.h>
 
#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);
}