join_nc.c 5.31 KB
/* $Id: join_nc.c,v 1.2 2008/06/13 09:17:30 elena Exp $ */ 
/** 
*  @file join_nc.c
*  @brief append input nc file to output nc file
*  @arg input-file output-file
*  @todo  Process errors - if needed ?
*  @date 03.01.2008
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netcdf.h>

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

int main(int argc, char *argv[])
{
   int status, ncID, infoID;
   int ndims, nvars, ngatts, unlimdimid;
   size_t dimlength, totalDimension = 1;
   size_t *start, *count;
   char dimname[NC_MAX_NAME], varname[NC_MAX_NAME], attname[NC_MAX_NAME];
   int i, j;
   int dimID[NC_MAX_DIMS];
   int varID[NC_MAX_DIMS];
   char constantInfoFile[NC_MAX_ATTRS];
   char infoFile[NC_MAX_ATTRS];
   nc_type var_type;                                                   /* variable type */
   int var_ndims;                                                      /* number of dims */
   int var_dimids[NC_MAX_VAR_DIMS];                                    /* dimension ids */
   int var_natts;                                                      /* number of attributes */
   void *variable;


   if (argc < 3)
    {
       fprintf(stderr,"Usage: join_nc inputName outputName\n");
       exit(0);
    }
   
   strcpy(constantInfoFile,argv[1]);
   strcpy(infoFile,argv[2]);
  
   if ((status = nc_open(infoFile, NC_WRITE, &ncID)) != NC_NOERR)
                                                handle_error(status);

   if ((status = nc_open(constantInfoFile, NC_NOWRITE, &infoID)) != NC_NOERR)
                                                       handle_error(status);

   if ((status = nc_inq(infoID, &ndims, &nvars, &ngatts, &unlimdimid)) != NC_NOERR)
                                                       handle_error(status);
// file into DEFINITION mode
   nc_redef(ncID); 
     
//  Start with adding dimensions   
     for (i = 0; i < ndims; i++) {
        status = nc_inq_dim(infoID, i, dimname, &dimlength);
        if (status == NC_NOERR) nc_def_dim(ncID, dimname, dimlength, &dimID[i]); 
      }

// adding Global Attributes

    if (ngatts > 0)  
         for (i = 0; i < ngatts; i++) {
              status = nc_inq_attname(infoID, NC_GLOBAL, i, attname);
              if (status == NC_NOERR) nc_copy_att(infoID, NC_GLOBAL, attname, ncID, NC_GLOBAL);  
         }  
     nc_enddef(ncID); 
                            
//  adding variables 
      for (i = 0; i < nvars; i++) {
        nc_redef(ncID); 

        
        status = nc_inq_var (infoID, i, varname, &var_type, &var_ndims, var_dimids, &var_natts);
        start = (size_t *) malloc(var_ndims*sizeof(size_t));
        count = (size_t *) malloc(var_ndims*sizeof(size_t));
        for (j = 0; j <  var_ndims; j++)  {                               
                status = nc_inq_dimlen(infoID, var_dimids[j], &dimlength);
                if (status == NC_NOERR) totalDimension *= dimlength;
                 start[j] = 0; 
                 count[j] = dimlength;  
                 var_dimids[j] = dimID[var_dimids[j]];
          }
        if (status == NC_NOERR) nc_def_var(ncID, varname, var_type, var_ndims, var_dimids, &varID[i]); 
        if (var_natts > 0)  
            for (j = 0; j < var_natts; j++) {    
               status = nc_inq_attname(infoID, i, j, attname);
               if (status == NC_NOERR) nc_copy_att(infoID, i, attname, ncID, varID[i]);
         } 
        nc_enddef(ncID);

         switch(var_type){
          case NC_FLOAT: {                    
                  variable = (float *) malloc(totalDimension*sizeof(float)); 
                  status = nc_get_vara_float(infoID, i, start, count, variable);
                  if (status == NC_NOERR) nc_put_vara_float(ncID, varID[i], start, count, variable);
                 break;
               }
          case NC_DOUBLE: {
                  variable = (double *) malloc(totalDimension*sizeof(double)); 
                  status = nc_get_vara_double(infoID, i, start, count, variable);
                  if (status == NC_NOERR) nc_put_vara_double(ncID, varID[i], start, count, variable);
                  break;
                }
          case NC_SHORT: {
                 variable = (short *) malloc(totalDimension*sizeof(short));
                 status = nc_get_vara_short(infoID, i, start, count, variable);
                 if (status == NC_NOERR) nc_put_vara_short(ncID, varID[i], start, count, variable);
                 break;
                }
          case NC_INT: {
                 variable = (int *) malloc(totalDimension*sizeof(int));
                 status = nc_get_vara_int(infoID, i, start, count, variable);
                 if (status == NC_NOERR) nc_put_vara_int(ncID, varID[i], start, count, variable);
                 break;
              }
          case NC_CHAR: {
                 variable = (char *) malloc(totalDimension*sizeof(char));
                 status = nc_get_vara_text(infoID, i, start, count, variable);
                 if (status == NC_NOERR) nc_put_vara_text(ncID, varID[i], start, count, variable);
               }
        }
           totalDimension = 1;
           free(variable); free(start); free(count);
       }         
   

   if ((status = nc_close(ncID)) != NC_NOERR)
                                    handle_error(status);

   if ((status = nc_close(infoID)) != NC_NOERR)
                                    handle_error(status);
}