nctimestring2double.c 4.41 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>
#include <DD.h>

#define THIS_OK	1
#define UNKNOWN_TIME_FORMAT -100

/**************************
   Function prototypes
**************************/
 
void handle_netcdf_error (int);
double ISO2Double(char *);


main(int argc, char **argv)
{
      int ncID, timeID, newTimeID, ndims, dimids[NC_MAX_DIMS];
      nc_type type;
      size_t len, nrecs;
      double *time_double;
      char varname[NC_MAX_NAME];
       
      int i, ii, j, status, nvars;
      dd_time_t Time; 
      char IsoTime[24];
      
      static size_t TimeStart[2] = {0L,0L};
      static size_t TimeCount[2] = {1L,17L};
       
       
      char SpecialSymbol[9] = {' ', '#', '%', '@', '+', '.', '>', '<', '-'};
      
      
        if (argc <= 1) {
            printf("Incorrect number of arguments\n"); 
   	    exit(0);
	}
	
	/* open nc file to write */
	if((status = nc_open(argv[1],NC_WRITE|NC_SHARE,&ncID)) != NC_NOERR){
	    printf("%d",status);
	    exit(0);
	}
		
	if ((status = nc_inq_varid(ncID, "Time", &timeID)) != NC_NOERR) {
	      timeID = 0; 	                     
	} 
	
	if ((status = nc_inq_vartype(ncID, timeID, &type)) != NC_NOERR) {
	      printf("%d",status);
	      exit(0);   		 
	} 
	
	if (type == NC_DOUBLE)  {
	      printf("%d", THIS_OK);
	      exit(0); 
	}
      
	if (type != NC_CHAR)  {
	      printf("%d", UNKNOWN_TIME_FORMAT);
	      exit(0); 
	}
	
	if ((status = nc_inq_varndims(ncID, timeID, &ndims)) != NC_NOERR) {
	      printf("%d", status);
	      exit(0); 
	} 
	
	if ((status = nc_inq_vardimid(ncID, timeID, dimids)) != NC_NOERR){
	      printf("%d", status);
	      exit(0); 
	}
	
	if ((status = nc_inq_dimlen(ncID,dimids[1], &len)) != NC_NOERR){	 
	      printf("%d", status);
	      exit(0);  
	} 
	
	if ((status = nc_inq_dimlen(ncID,dimids[0], &nrecs)) != NC_NOERR){	 
	      printf("%d", status);
	      exit(0);  
	} 
	
//TODO all possible char formats	
	if (len != 17 && len != 23 && len != 24) {
	      printf("%d", UNKNOWN_TIME_FORMAT);
	      exit(0);  	  	  
	}
	  
       time_double = (double *)malloc(sizeof(double)*nrecs);
       
       if (len == 17) {
	  for (i = 0; i < nrecs; i++) {
	      if ((status =  nc_get_vara_text(ncID,  timeID, TimeStart,  TimeCount,  Time)) != NC_NOERR){
		      printf("%d", status);
		      exit(0);  
	      }  
	      
	      TimeStart[0]++;
	      time_double[i] = DD_Time2Double(Time);
	  }
       }
       else {
	  TimeCount[1] = len;
	  for (i = 0; i < nrecs; i++) {
	      if ((status =  nc_get_vara_text(ncID,  timeID, TimeStart,  TimeCount,  IsoTime)) != NC_NOERR){
		      printf("%d", status);
		      exit(0);  
	      }  
	      
	      TimeStart[0]++;
	      time_double[i] = ISO2Double(IsoTime);
	  }
       }
       
      /* get info on number of variables */
        status = nc_inq_nvars(ncID, &nvars);       	 
	
	status = nc_redef(ncID);
        for (j = 0; j < nvars; j++) {      
      /* get the name of variable by its ID */
          status = nc_inq_varname(ncID, j, varname);                
      /* Replace special symbols with underscore(s) */      
          for (ii = 0; ii < 9; ii++) 
            for (i = 0; i < strlen(varname); i++) {
                  if (varname[i] == SpecialSymbol[ii]) varname[i] = '_'; 
              }
      /* Rename the variable */      
            status = nc_rename_var(ncID, j, varname);
            nc_sync(ncID);      
        }
        status = nc_rename_var(ncID, timeID, "TimeString");
	status = nc_def_var(ncID, "Time", NC_DOUBLE, 1, &dimids[0], &newTimeID);
	status = nc_enddef(ncID);
	
	status = nc_put_var_double(ncID,newTimeID,time_double); 
        nc_sync(ncID);
	
	printf("%d", THIS_OK);
        status = nc_close(ncID);
}
/*--------------------------------------------------------------------------
 *  Handles a netCDF error.
 *--------------------------------------------------------------------------*/

void handle_netcdf_error(int status) {
  fprintf(stderr, "%s\n", nc_strerror(status));  
}

/*--------------------------------------------------------------------------
 *   ISO time to DD Double (UNIX)
 *   2007-07-12T13:08:02.000
 *--------------------------------------------------------------------------*/
 double ISO2Double(char *IsoTime) {   
   dd_tmstr_t *Time;
   int UT[7];

   sscanf(IsoTime, "%d-%d-%dT%d:%d:%d.%d", 
                              &UT[0],&UT[1],&UT[2],&UT[3],&UT[4],&UT[5],&UT[6]); 

   Time = (dd_tmstr_t *)UT2double(UT);
  
  return  Time->times;
}