Esempio n. 1
0
int
main(int argc, char **argv)
{/* create file that caused seg fault in ncdump */

    int  ncid;  /* netCDF id */

    /* dimension ids */
    int Time_dim;
    int X_dim;
    int Y_dim;

    /* dimension lengths */
    size_t Time_len = NC_UNLIMITED;
    size_t X_len = 4;
    size_t Y_len = 3;

    /* variable ids */
    int Time_id;
    int P_id;

    /* rank (number of dimensions) for each variable */
#   define RANK_Time 1
#   define RANK_P 3

    /* variable shapes */
    int Time_dims[RANK_Time];
    int P_dims[RANK_P];

   printf("\n*** Testing preparation of fillbug test.\n");
   printf("*** creating fillbug test file %s...", FILENAME);

    /* enter define mode */
    if (nc_create(FILENAME, NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;

    /* define dimensions */
    if (nc_def_dim(ncid, "Time", Time_len, &Time_dim)) ERR;
    if (nc_def_dim(ncid, "X", X_len, &X_dim)) ERR;
    if (nc_def_dim(ncid, "Y", Y_len, &Y_dim)) ERR;

    /* define variables */

    Time_dims[0] = Time_dim;
    if (nc_def_var(ncid, "Time", NC_DOUBLE, RANK_Time, Time_dims, &Time_id)) ERR;

    P_dims[0] = Time_dim;
    P_dims[1] = Y_dim;
    P_dims[2] = X_dim;
    if (nc_def_var(ncid, "P", NC_FLOAT, RANK_P, P_dims, &P_id)) ERR;

    /* leave define mode */
    if (nc_enddef (ncid)) ERR;

    {/* assign variable data */
    static double Time_data[1]={3.14159};
    static size_t Time_startset[1] = {0};
    static size_t Time_countset[1] = {1};
    if (nc_put_vara(ncid, Time_id, Time_startset, Time_countset, Time_data)) ERR;
    }

    if (nc_close(ncid)) ERR;

    /* Try to duplicate segfault ncdump gets by making the same calls
     * to the netCDF-4 library, in the same order.  This doesn't
     * result in the same segfault, so either we have missed a call
     * made by ncdump, or an earlier ncdump bug masks the real problem
     * until a call is made into the netCDF-4 library ...  */
    if (nc_open(FILENAME, NC_NOWRITE, &ncid)) ERR;

    {
	/* We declare local arrays with small constant sizes to avoid
	 * all the mallocs and frees used in ncdump.  For the example
	 * above, the fixed-size arrays are ample. */
	int format, ndims, nvars, ngatts, xdimid, ndims_grp, dimids_grp[3],
	    unlimids[1], d_grp, nunlim, nvars_grp, varids_grp[3], v_grp,
	    varid, varndims, vardims[3], varnatts, vartype, dimids[3], is_recvar,
	    vdims[3], id, ntypes, numgrps;
	size_t dimsize, len;
	char dimname[20], varname[20];
	if ( nc_inq_format(ncid, &format)) ERR;
	ntypes = count_udtypes(ncid);
	if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR;
	if ( nc_inq_format(ncid, &format)) ERR;
	if ( nc_inq_grps(ncid, &numgrps, NULL) ) ERR;
	if ( nc_inq_typeids(ncid, &ntypes, NULL) ) ERR;
	if ( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) ) ERR;
	if ( nc_inq_ndims(ncid, &ndims_grp) ) ERR;
	if ( nc_inq_dimids(ncid, 0, dimids_grp, 0) ) ERR;
	if ( nc_inq_unlimdims(ncid, &nunlim, NULL) ) ERR;
	if ( nc_inq_unlimdims(ncid, &nunlim, unlimids) ) ERR;
	for (d_grp = 0; d_grp < ndims_grp; d_grp++) {
	    int dimid = dimids_grp[d_grp];
	    if ( nc_inq_dim(ncid, dimid, dimname, &dimsize) ) ERR;
	}
	if ( nc_inq_format(ncid, &format) ) ERR;
	if ( nc_inq_varids(ncid, &nvars_grp, varids_grp) ) ERR;
	for (v_grp = 0; v_grp < nvars_grp; v_grp++) {
	    varid = varids_grp[v_grp];
	    if ( nc_inq_varndims(ncid, varid, &varndims) ) ERR;
	    if ( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims,
			    &varnatts) ) ERR;
	    for (id = 0; id < varndims; id++) {
		if ( nc_inq_dimname(ncid, vardims[id], dimname) ) ERR;
	    }
	}
	for (v_grp = 0; v_grp < nvars_grp; v_grp++) {
	    varid = varids_grp[v_grp];
	    if( nc_inq_varndims(ncid, varid, &varndims) ) ERR;
	    if( nc_inq_var(ncid, varid, varname, &vartype, 0, vardims,
			   &varnatts) ) ERR;
	    {
		is_recvar = 0;
		if ( nc_inq_varndims(ncid, varid, &ndims) ) ERR;
		if (ndims > 0) {
		    int nunlimdims;
		    int recdimids[3];
		    int dim, recdim;
		    if ( nc_inq_vardimid(ncid, varid, dimids) ) ERR;
		    if ( nc_inq_unlimdims(ncid, &nunlimdims, NULL) ) ERR;
		    if ( nc_inq_unlimdims(ncid, NULL, recdimids) ) ERR;
		    for (dim = 0; dim < ndims && is_recvar == 0; dim++) {
			for(recdim = 0; recdim < nunlimdims; recdim++) {
			    if(dimids[dim] == recdimids[recdim]) {
				is_recvar = 1;
				break;
			    }
			}
		    }
		}
	    }
	    for (id = 0; id < varndims; id++) {
		if( nc_inq_dimlen(ncid, vardims[id], &len) ) ERR;
		vdims[id] = len;
	    }
	    if (varid == 0) {
		/* read Time variable */
		static double Time_data;
		static size_t cor[RANK_Time] = {0};
		static size_t edg[RANK_Time] = {1};
		if (nc_get_vara(ncid, varid, cor, edg, &Time_data)) ERR;
	    } else {
		/* read data slices from P variable, should get fill values */
		static float P_data[4];
		static size_t cor[RANK_P] = {0, 0, 0};
		static size_t edg[RANK_P] = {1, 1, 4};

		/* first slice retrieved OK */
		if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR;

		/* In ncdump, reading second slice gets seg fault in
		 * nc4_open_var_grp(), but this attempt to do all the
		 * same netCDF calls as ncdump can't duplicate the
		 * error, which would seem to implicate ncdump rather
		 * than HDF5 or netCDF-4 library ... */
		cor[1] = 1;
		if (nc_get_vara(ncid, varid, cor, edg, P_data)) ERR;
	    }
	}
    }
    if (nc_close(ncid)) ERR;

   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Esempio n. 2
0
/* Has to be at the bottom because it uses many
 * other functions */
void sdatio_open_file(struct sdatio_file * sfile )  {
  /*printf("called\n");*/
  int retval;
  int ndims, nvars;
  int i, j;
  struct sdatio_dimension * sdim;
  struct sdatio_variable * svar;
  size_t lengthp;
  int nunlimdims;
  int *unlimdims;
  int is_unlimited;
  char * name_tmp;
  int * vardimids;
  char * dimension_list;
  nc_type vartype;
  int vartypeint;
  int dummy;
  int *nunlim;

  DEBUG_MESS("starting sdatio_open_file\n");

  retval = 0;

  if (sfile->is_open){
    printf("ERROR: The supplied sdatio_file struct corresponds to an already open file.\n");
    abort();
  }

  /* We make the choice to always open the file in readwrite mode*/
  sfile->mode = sfile->mode|NC_WRITE;

  DEBUG_MESS("sdatio_open_file opening file\n");
  /* Open the file*/
  if (sfile->is_parallel) {
#ifdef PARALLEL 
    if ((retval = nc_open_par(sfile->name, sfile->mode, *(sfile->communicator), MPI_INFO_NULL,  &(sfile->nc_file_id)))) ERR(retval);
#else
    printf("sdatio was built without --enable-parallel, sdatio_create_file will not work for parallel files\n");
    abort();
#endif
  }
  else {
    if ((retval = nc_open(sfile->name, sfile->mode, &(sfile->nc_file_id)))) ERR(retval);
  }
  DEBUG_MESS("sdatio_open_file opened file\n");
  /*Initialize object file data*/
  sfile->is_open = 1;
  sfile->n_dimensions = 0;
  sfile->n_variables = 0;
  sfile->data_written = 0;
  /* Get number of dimensions in the file*/
  if ((retval = nc_inq_ndims(sfile->nc_file_id, &ndims))) ERR(retval);
  /* Allocate some temp storate*/
  name_tmp = (char*)malloc(sizeof(char*)*(NC_MAX_NAME+1));
  /* Get a list of unlimited dimensions*/
  if ((retval = nc_inq_unlimdims(sfile->nc_file_id, &nunlimdims, NULL))) ERR(retval);
  unlimdims = (int*)malloc(sizeof(int*)*nunlimdims);
  if ((retval = nc_inq_unlimdims(sfile->nc_file_id, &nunlimdims, unlimdims))) ERR(retval);
  /* Add each dimension to the sfile object*/
  for (i=0; i<ndims; i++){
    if ((retval = nc_inq_dim(sfile->nc_file_id, i, name_tmp, &lengthp))) ERR(retval);
    sdim = (struct sdatio_dimension *) malloc(sizeof(struct sdatio_dimension));
    /*if ((retval = nc_def_dim(sfile->nc_file_id, dimension_name, size, &(sdim->nc_id)))) ERR(retval);*/
    /*}*/
    /*sdatio_end_definitions(sfile);*/
    is_unlimited = 0;
    for(j=0; j<nunlimdims; j++) if (unlimdims[j] == i) is_unlimited = 1;
    if (is_unlimited) {
      sdim->size = SDATIO_UNLIMITED;
      /* We choose the first write to unlimited variables to be the last
       * existing record. Users can easily move to the next by
       * calling sdatio_increment_start before writing anything */
      sdim->start = lengthp-1;
    }
    else {
      sdim->size = lengthp;
      sdim->start = 0;
    }
    if (strlen(name_tmp)>1){
      sfile->has_long_dim_names = 1;
      /*printf("Dimension names can only be one character long!\n");*/
      /*abort();*/
    }
    sdim->nc_id = i;
    sdim->name = (char *)malloc(sizeof(char)*(strlen(name_tmp)+1));
    strcpy(sdim->name, name_tmp);
    sdatio_append_dimension(sfile, sdim);
  }
  DEBUG_MESS("Finished reading dimensions\n");
  /* Get the number of variables in the file*/
  if ((retval = nc_inq_nvars(sfile->nc_file_id, &nvars))) ERR(retval);
  /* Add each variable to the sfile object*/
  for (i=0; i<nvars; i++){
    if ((retval = nc_inq_varndims(sfile->nc_file_id, i, &ndims))) ERR(retval);
    vardimids = (int*)malloc(sizeof(int)*ndims);
    if ((retval = nc_inq_var(sfile->nc_file_id, i, name_tmp, &vartype,
                            &ndims, vardimids, &dummy))) ERR(retval);
    vartypeint = vartype;
    vartypeint = sdatio_sdatio_variable_type(vartypeint);
    svar = (struct sdatio_variable *) malloc(sizeof(struct sdatio_variable));

    /*Set variable id*/
    svar->nc_id = i;

    /* Set variable name*/
    svar->name = (char *)malloc(sizeof(char)*(strlen(name_tmp)+1));
    strcpy(svar->name, name_tmp);

    /*ndims = strlen(dimension_list);*/
    svar->ndims = ndims;
    DEBUG_MESS("ndims = %d for variable %s\n", ndims, name_tmp);

    /* Set the dimension_ids*/
    svar->dimension_ids = vardimids;

    /*sdatio_get_dimension_ids(sfile, dimension_list, svar);*/
    sdatio_get_dimension_list(sfile, vardimids, svar);
    /*svar->dimension_ids = dimension_ids;*/


    DEBUG_MESS("Setting type for variable %s\n", svar->name);
    switch (vartypeint){
      case SDATIO_INT:
        svar->type_size = sizeof(int);
        break;
      case SDATIO_FLOAT:
        svar->type_size = sizeof(float);
        break;
      case SDATIO_DOUBLE:
        svar->type_size = sizeof(double);
        break;
      case SDATIO_CHAR:
        svar->type_size = sizeof(char);
        break;
      default:
        printf("Unknown type in sdatio_create_variable\n");
        abort();
    }

    
    svar->type = vartypeint;

    DEBUG_MESS("Allocating manual starts and counts for variable %s; ndims %d\n", svar->name, ndims);
    svar->manual_starts=(int*)malloc(sizeof(int)*ndims);
    svar->manual_counts=(int*)malloc(sizeof(int)*ndims);
    svar->manual_offsets=(int*)malloc(sizeof(int)*ndims);

    DEBUG_MESS("Setting manual starts and counts for variable %s\n", svar->name);
    for (j=0;j<ndims;j++){
      svar->manual_starts[j]=-1;
      svar->manual_counts[j]=-1;
      svar->manual_offsets[j]=-1;
    }

    DEBUG_MESS("Starting sdatio_append_variable\n");

    sdatio_append_variable(sfile, svar);

    DEBUG_MESS("Ending sdatio_append_variable\n");

#ifdef PARALLEL
    if (sfile->is_parallel){
      sdatio_number_of_unlimited_dimensions(sfile, svar->name, &nunlim);
      if (nunlim > 0)
        if ((retval = nc_var_par_access(sfile->nc_file_id, svar->nc_id, NC_COLLECTIVE))) ERR(retval);
    }
#endif
    /*vartypeint = */
  }
  DEBUG_MESS("Finished reading variables\n");
  
  free(unlimdims);
  free(name_tmp);
}
Esempio n. 3
0
int FileNetcdf::getNumDims(int iVar) const {
   int len;
   int status = nc_inq_varndims(mFile, iVar, &len);
   return len;
}
Esempio n. 4
0
/*! \internal */
int
cpy_var_val(int in_id,int out_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the variable data from an input netCDF file
   * to an output netCDF file. 
   */

  int *dim_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;
  size_t *dim_cnt;
  size_t *dim_sz;
  size_t *dim_srt;
  size_t var_sz=1L;
  nc_type var_type_in, var_type_out;

  void *void_ptr = NULL;

  /* Get the var_id for the requested variable from both files. */
  (void)nc_inq_varid(in_id, var_nm, &var_in_id);
  (void)nc_inq_varid(out_id,var_nm, &var_out_id);
 
  /* Get the number of dimensions for the variable. */
  (void)nc_inq_vartype( out_id, var_out_id, &var_type_out);
  (void)nc_inq_varndims(out_id, var_out_id, &nbr_dim);

  (void)nc_inq_vartype( in_id,   var_in_id, &var_type_in);
  (void)nc_inq_varndims(in_id,   var_in_id, &nbr_dim);
 
  /* Allocate space to hold the dimension IDs */
  dim_cnt = malloc(nbr_dim*sizeof(size_t));

  dim_id=malloc(nbr_dim*sizeof(int));

  dim_sz=malloc(nbr_dim*sizeof(size_t));

  dim_srt=malloc(nbr_dim*sizeof(size_t));
 
  /* Get the dimension IDs from the input file */
  (void)nc_inq_vardimid(in_id, var_in_id, dim_id);
 
  /* Get the dimension sizes and names from the input file */
  for(idx=0;idx<nbr_dim;idx++){
  /* NB: For the unlimited dimension, ncdiminq() returns the maximum
     value used so far in writing data for that dimension.
     Thus if you read the dimension sizes from the output file, then
     the ncdiminq() returns dim_sz=0 for the unlimited dimension
     until a variable has been written with that dimension. This is
     the reason for always reading the input file for the dimension
     sizes. */

    (void)nc_inq_dimlen(in_id,dim_id[idx],dim_cnt+idx);

    /* Initialize the indicial offset and stride arrays */
    dim_srt[idx]=0L;
    var_sz*=dim_cnt[idx];
  } /* end loop over dim */

  /* Allocate enough space to hold the variable */
  if (var_sz > 0)
      void_ptr=malloc(var_sz * type_size(var_type_in));

  /* Get the variable */

  /* if variable is float or double, convert if necessary */

  if(nbr_dim==0){  /* variable is a scalar */

    if (var_type_in == NC_INT && var_type_out == NC_INT) {
      nc_get_var1_int(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_int(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_INT64 && var_type_out == NC_INT64) {
      nc_get_var1_longlong(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_longlong(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_FLOAT) {
      nc_get_var1_float(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_float(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_DOUBLE) {
      nc_get_var1_double(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_double(out_id, var_out_id, 0L, void_ptr);
    }

    else if (var_type_in == NC_CHAR) {
      nc_get_var1_text(in_id,  var_in_id,  0L, void_ptr);
      nc_put_var1_text(out_id, var_out_id, 0L, void_ptr);
    }

    else {
      assert(1==0);
    }
  } else { /* variable is a vector */

    if (var_type_in == NC_INT && var_type_out == NC_INT) {
      (void)nc_get_var_int(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_int(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_INT64 && var_type_out == NC_INT64) {
      (void)nc_get_var_longlong(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_longlong(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_FLOAT) {
      (void)nc_get_var_float(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_float(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_DOUBLE) {
      (void)nc_get_var_double(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_double(out_id, var_out_id, void_ptr);
    }

    else if (var_type_in == NC_CHAR) {
      (void)nc_get_var_text(in_id,  var_in_id,  void_ptr);
      (void)nc_put_var_text(out_id, var_out_id, void_ptr);
    }

    else {
      assert(1==0);
    }
  } /* end if variable is an array */

  /* Free the space that held the dimension IDs */
  (void)free(dim_cnt);
  (void)free(dim_id);
  (void)free(dim_sz);
  (void)free(dim_srt);

  /* Free the space that held the variable */
  (void)free(void_ptr);

  return(EX_NOERR);

} /* end cpy_var_val() */
Esempio n. 5
0
int main(int argc, char** argv)
{  
   namespace po = boost::program_options;

   int ndiamonds_label=0;
   int nmpi=0;
   bool doLabels= false;

   // Declare the supported options.
   po::options_description desc("Allowed options");
   desc.add_options()
      ("help", "produce help message")
      ("label", "label all cells and vertices")
      ("ndiamonds-label", po::value<int>(&ndiamonds_label)->default_value(1),  "number of diamonds to label (-1 for all)")
      ("input-file", po::value< std::vector<std::string> >(), "input file")
      ("nmpi", po::value<int>(&nmpi)->default_value(1),  "number of mpi")
      ("ndims", po::value<int>(&nmpi)->default_value(3),  "number of dimension for the gmesh")
   ;
   
   po::positional_options_description p;
   p.add("input-file", -1);

   po::variables_map vm;
   po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
   po::notify(vm);    

   if (vm.count("help")) {
       std::cout << desc << "\n";
       return 1;
   }

   if(!vm.count("input-file"))
   { 
       std::cout << "Error: need to specify input file" << std::endl;
       std::cout << desc << std::endl;
       return 1;
   }

   const std::string ncfilename = vm["input-file"].as< std::vector<std::string> >()[0];
   
   if ( !boost::filesystem::exists( ncfilename ) )
   {
       std::cout << "Can't find netcdf file!" << std::endl;
       return 1;
   }

   unsigned int ndims = 3;
   if(vm.count("ndims"))
   {
       ndims = vm["ndims"].as<int>();
       if(ndims != 3 && ndims != 2) {
           std::cout << "Error: wrong number of dimensions" << std::endl;
           return 1;
       }
   }

   if(vm.count("label")) doLabels=true;


   int ncid;
   int ierror = nc_open(ncfilename.c_str(), NC_NOWRITE, & ncid);
   assert(ierror==NC_NOERR);

   int cell_dimid;
   ierror = nc_inq_dimid(ncid, "cell", &cell_dimid);
   assert(ierror==NC_NOERR);

   size_t cell_dimlen;
   ierror = nc_inq_dimlen(ncid, cell_dimid, &cell_dimlen);
   assert(ierror==NC_NOERR);

   assert(cell_dimlen%20==0);

   int vertex_dimid;
   ierror = nc_inq_dimid(ncid, "vertex", &vertex_dimid);
   assert(ierror==NC_NOERR);
 
   size_t vertex_dimlen;
   ierror = nc_inq_dimlen(ncid, vertex_dimid, &vertex_dimlen);
   assert(ierror==NC_NOERR);

   int cartx_vert_id, carty_vert_id, cartz_vert_id;
   ierror= nc_inq_varid(ncid, "cartesian_x_vertices", &cartx_vert_id);
   assert(ierror==NC_NOERR);
   ierror= nc_inq_varid(ncid, "cartesian_y_vertices", &carty_vert_id);
   assert(ierror==NC_NOERR);
   ierror= nc_inq_varid(ncid, "cartesian_z_vertices", &cartz_vert_id);
   assert(ierror==NC_NOERR);

   int lon_vert_id, lat_vert_id;
   ierror= nc_inq_varid(ncid, "longitude_vertices", &lon_vert_id);
   assert(ierror==NC_NOERR);
   ierror= nc_inq_varid(ncid, "latitude_vertices", &lat_vert_id);
   assert(ierror==NC_NOERR);


   int cart_vert_numdim;
   ierror = nc_inq_varndims(ncid, cartx_vert_id, &cart_vert_numdim);
   assert(ierror==NC_NOERR && cart_vert_numdim==1);
   ierror = nc_inq_varndims(ncid, carty_vert_id, &cart_vert_numdim);
   assert(ierror==NC_NOERR && cart_vert_numdim==1);
   ierror = nc_inq_varndims(ncid, cartz_vert_id, &cart_vert_numdim);
   assert(ierror==NC_NOERR && cart_vert_numdim==1);


   int cart_vert_dimids[1];
   ierror = nc_inq_vardimid(ncid, cartx_vert_id, cart_vert_dimids);
   assert(ierror==NC_NOERR && cart_vert_dimids[0] == vertex_dimid);
   ierror = nc_inq_vardimid(ncid, carty_vert_id, cart_vert_dimids);
   assert(ierror==NC_NOERR && cart_vert_dimids[0] == vertex_dimid);
   ierror = nc_inq_vardimid(ncid, cartz_vert_id, cart_vert_dimids);
   assert(ierror==NC_NOERR && cart_vert_dimids[0] == vertex_dimid);

   int vertex_cell_id;
   ierror= nc_inq_varid(ncid, "vertex_of_cell", &vertex_cell_id);
   assert(ierror==NC_NOERR);
   int vertex_cell_numdim;
   ierror = nc_inq_varndims(ncid, vertex_cell_id, &vertex_cell_numdim);
   assert(ierror==NC_NOERR && vertex_cell_numdim==2);

   int vertex_cell_dimids[2];
   size_t vertex_cell_dimlens[2];
   ierror = nc_inq_vardimid(ncid, vertex_cell_id, vertex_cell_dimids);
   assert(ierror==NC_NOERR);

   ierror = nc_inq_dimlen(ncid, vertex_cell_dimids[0], &vertex_cell_dimlens[0]);
   assert(ierror==NC_NOERR && vertex_cell_dimlens[0] == 3);
   ierror = nc_inq_dimlen(ncid, vertex_cell_dimids[1], &vertex_cell_dimlens[1]);
   assert(ierror==NC_NOERR);

   assert(vertex_cell_dimlens[1] == cell_dimlen);

   int vertices_of_vertex_id;
   ierror= nc_inq_varid(ncid, "vertices_of_vertex", &vertices_of_vertex_id);
   assert(ierror==NC_NOERR);
   int vertices_of_vertex_numdim;
   ierror = nc_inq_varndims(ncid, vertices_of_vertex_id, &vertices_of_vertex_numdim);
   assert(ierror==NC_NOERR && vertices_of_vertex_numdim==2);

   int vertices_of_vertex_dimids[2];
   size_t vertices_of_vertex_dimlens[2];
   ierror = nc_inq_vardimid(ncid, vertices_of_vertex_id, vertices_of_vertex_dimids);
   assert(ierror==NC_NOERR);

   ierror = nc_inq_dimlen(ncid, vertices_of_vertex_dimids[0], &vertices_of_vertex_dimlens[0]);
   assert(ierror==NC_NOERR);
   ierror = nc_inq_dimlen(ncid, vertices_of_vertex_dimids[1], &vertices_of_vertex_dimlens[1]);

   assert(vertex_dimlen == vertices_of_vertex_dimlens[1]);

   assert(ierror==NC_NOERR);

   // extract data from netcdf

   mesh icon_mesh(vertex_cell_dimlens[1], vertices_of_vertex_dimlens[1], vertex_cell_dimlens[0], vertices_of_vertex_dimlens[0]);

   std::vector<double> cartx_vert, carty_vert, cartz_vert;

   cartx_vert.resize( vertex_dimlen );
   carty_vert.resize( vertex_dimlen );
   cartz_vert.resize( vertex_dimlen );

   if(ndims == 3) {

       ierror = nc_get_var_double(ncid, cartx_vert_id, &cartx_vert[0]);
       assert(ierror==NC_NOERR);
       ierror= nc_get_var_double(ncid, carty_vert_id, &carty_vert[0]);
       assert(ierror==NC_NOERR);
       ierror= nc_get_var_double(ncid, cartz_vert_id, &cartz_vert[0]);
       assert(ierror==NC_NOERR);
   }
   else {
       ierror = nc_get_var_double(ncid, lon_vert_id, &cartx_vert[0]);
       assert(ierror==NC_NOERR);

       ierror = nc_get_var_double(ncid, lat_vert_id, &carty_vert[0]);
       assert(ierror==NC_NOERR);

       for(size_t i=0; i < vertex_dimlen; ++i)
           cartz_vert[i] = 0;
   }
   icon_mesh.insert_cart_vert(cartx_vert, carty_vert, cartz_vert);

   icon_mesh.fill_from_netcdf(ncid, vertex_cell_id, vertices_of_vertex_id);

   if(ndims==2) {
       icon_mesh.add_ghost_nodes();
   }

   icon_mesh.gmsh_render(doLabels, nmpi);

   nc_close(ncid);
};
Esempio n. 6
0
int
main(int argc, char **argv)
{
    size_t sizehint = 2100000;	/* default if not set on command line,
				 * exposes bug.  It turns out any
				 * value between 2091953 and 2150032
				 * triggers bug, whereas all other
				 * values work fine. */

    if (argc > 1) {
	char *endptr, *str = argv[1];
	errno = 0;
	sizehint = strtol(str, &endptr, 0);
	/* check for various possible errors */
	if ((errno == ERANGE && (sizehint == LONG_MAX || sizehint == LONG_MIN))
                   || (errno != 0 && sizehint == 0)) {
               perror("strtol");
               exit(EXIT_FAILURE);
	}
	if (endptr == str) {
	    fprintf(stderr, "No digits were found\n");
	    exit(EXIT_FAILURE);
	}
    }
   printf("\n*** Testing nofill mode.\n");
   {
       printf("*** Create file in nofill mode, writing all values...");
       if (create_file(FILE_NAME1, NC_NOFILL, &sizehint)) ERR;
       SUMMARIZE_ERR;
   }
   {
       printf("*** Create file with same data in fill mode, writing all values...");
       if (create_file(FILE_NAME2, NC_FILL, &sizehint)) ERR;
       SUMMARIZE_ERR;
   }
   {
       int ncid1, ncid2;
       int nvars1, nvars2;
       int varid;
       int badvars;

       printf("*** Compare values in nofill mode and fill mode files...");
       /* compare data in two files created with nofill mode and fill
	* mode, which should be identical if all the data were written */
       if (nc_open(FILE_NAME1, NC_NOWRITE, &ncid1)) ERR;
       if (nc_open(FILE_NAME2, NC_NOWRITE, &ncid2)) ERR;
       if (nc_inq_nvars(ncid1, &nvars1)) ERR;
       if (nc_inq_nvars(ncid2, &nvars2)) ERR;
       if (nvars1 != nvars2) ERR;
       badvars = 0;
       for(varid = 0; varid < nvars1; varid++) {
	   size_t nvals, nn;
	   int ndims, *dimids, dim;
	   nc_type vtype;
	   char varname1[NC_MAX_NAME];		   
	   char varname2[NC_MAX_NAME];
	   /* How many values in this variable to compare? */
	   if (nc_inq_varndims(ncid1, varid, &ndims)) ERR;
	   dimids = malloc((ndims + 1) * sizeof(int));
	   if (!dimids) ERR;
	   if (nc_inq_vardimid (ncid1, varid, dimids)) ERR;
	   nvals = 1;
	   for(dim = 0; dim < ndims; dim++) {
	       size_t len;
	       if (nc_inq_dimlen(ncid1, dimids[dim], &len)) ERR;
	       nvals *= len;
	   }
	   if (nc_inq_vartype(ncid1, varid, &vtype)) ERR;
	   if (nc_inq_varname(ncid1, varid, varname1)) ERR;
	   if (nc_inq_varname(ncid1, varid, varname2)) ERR;
	   
	   if (vtype != NC_CHAR) {  /* numeric data, just read in as doubles */
	       double *data1, *data2;
	       /* Allocate space to hold values in both files */
	       data1 = malloc((nvals + 1) * sizeof(double));
	       if (!data1) ERR;
	       data2 = malloc((nvals + 1) * sizeof(double));
	       if (!data2) ERR;
	       /* Read in values */
	       if (nc_get_var_double(ncid1, varid, data1)) ERR;
	       if (nc_get_var_double(ncid2, varid, data2)) ERR;
	       /* Compare values */
	       for(nn = 0; nn < nvals; nn++) {
		   if (data1[nn] != data2[nn]) {
		       badvars++;
		       fprintf(stderr, 
			       "\tFrom nofill file, %s[%d] = %.15g\tFrom fill file, %s[%d] = %.15g\n", 
			       varname1, nn, data1[nn], varname2, nn, data2[nn]);
		       break;
		   };
	       }
	       free(data1);
	       free(data2);
	   } else {		/* character data */
	       char *data1, *data2;
	       /* Allocate space to hold values in both files */
	       data1 = malloc((nvals + 1) * sizeof(char));
	       if (!data1) ERR;
	       data2 = malloc((nvals + 1) * sizeof(char));
	       if (!data2) ERR;
	       /* Read in values */
	       if (nc_get_var_text(ncid1, varid, data1)) ERR;
	       if (nc_get_var_text(ncid2, varid, data2)) ERR;
	       /* Compare values */
	       for(nn = 0; nn < nvals; nn++) {
		   if (data1[nn] != data2[nn]) {
		       badvars++;
		       fprintf(stderr, 
			       "\tFrom nofill file, %s[%d] = %d\tFrom fill file, %s[%d] = %d\n", 
			       varname1, nn, data1[nn], varname2, nn, data2[nn]);
		       break;
		   };
	       }
	       free(data1);
	       free(data2);
	   }
	   free(dimids);
       }
       if(badvars > 0) ERR;
       if (nc_close(ncid1)) ERR;
       if (nc_close(ncid2)) ERR;
       SUMMARIZE_ERR;
   }
   FINAL_RESULTS;
}
Esempio n. 7
0
OSErr NetCDFWindMoverCurv::ReadTimeData(long index,VelocityFH *velocityH, char* errmsg) 
{
	OSErr err = 0;
	long i,j;
	char path[256], outPath[256]; 
	char *velUnits=0;
	int status, ncid, numdims;
	int wind_ucmp_id, wind_vcmp_id, angle_id, uv_ndims;
	static size_t wind_index[] = {0,0,0,0}, angle_index[] = {0,0};
	static size_t wind_count[4], angle_count[2];
	size_t velunit_len;
	float *wind_uvals = 0,*wind_vvals = 0, fill_value=-1e-72, velConversion=1.;
	short *wind_uvals_Navy = 0,*wind_vvals_Navy = 0, fill_value_Navy;
	float *angle_vals = 0;
	long totalNumberOfVels = fNumRows * fNumCols;
	VelocityFH velH = 0;
	long latlength = fNumRows;
	long lonlength = fNumCols;
	float scale_factor = 1.,angle = 0.,u_grid,v_grid;
	Boolean bRotated = true, fIsNavy = false, bIsNWSSpeedDirData = false;
	
	errmsg[0]=0;
	
	strcpy(path,fPathName);
	if (!path || !path[0]) return -1;
	
	status = nc_open(path, NC_NOWRITE, &ncid);
	//if (status != NC_NOERR) {err = -1; goto done;}
	if (status != NC_NOERR)
	{
#if TARGET_API_MAC_CARBON
		err = ConvertTraditionalPathToUnixPath((const char *) path, outPath, kMaxNameLen) ;
		status = nc_open(outPath, NC_NOWRITE, &ncid);
#endif
		if (status != NC_NOERR) {err = -1; goto done;}
	}
	status = nc_inq_ndims(ncid, &numdims);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	wind_index[0] = index;	// time 
	wind_count[0] = 1;	// take one at a time
	if (numdims>=4)	// should check what the dimensions are, CO-OPS uses sigma
	{
		wind_count[1] = 1;	// depth
		wind_count[2] = latlength;
		wind_count[3] = lonlength;
	}
	else
	{
		wind_count[1] = latlength;	
		wind_count[2] = lonlength;
	}
	angle_count[0] = latlength;
	angle_count[1] = lonlength;
	
	//wind_count[0] = latlength;		// a fudge for the PWS format which has u(lat,lon) not u(time,lat,lon)
	//wind_count[1] = lonlength;
	
	if (fIsNavy)
	{
		// need to check if type is float or short, if float no scale factor?
		wind_uvals = new float[latlength*lonlength]; 
		if(!wind_uvals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		wind_vvals = new float[latlength*lonlength]; 
		if(!wind_vvals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		
		angle_vals = new float[latlength*lonlength]; 
		if(!angle_vals) {TechError("GridVel::ReadNetCDFFile()", "new[]", 0); err = memFullErr; goto done;}
		status = nc_inq_varid(ncid, "air_gridu", &wind_ucmp_id);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "air_gridv", &wind_vcmp_id);	
		if (status != NC_NOERR) {err = -1; goto done;}
		
		status = nc_get_vara_float(ncid, wind_ucmp_id, wind_index, wind_count, wind_uvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, wind_vcmp_id, wind_index, wind_count, wind_vvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "_FillValue", &fill_value);
		//if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "scale_factor", &scale_factor);
		//if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_inq_varid(ncid, "grid_orient", &angle_id);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, angle_id, angle_index, angle_count, angle_vals);
		if (status != NC_NOERR) {/*err = -1; goto done;*/bRotated = false;}
	}
	else
	{
		wind_uvals = new float[latlength*lonlength]; 
		if(!wind_uvals) {TechError("NetCDFWindMoverCurv::ReadTimeData()", "new[]", 0); err = memFullErr; goto done;}
		wind_vvals = new float[latlength*lonlength]; 
		if(!wind_vvals) {TechError("NetCDFWindMoverCurv::ReadTimeData()", "new[]", 0); err = memFullErr; goto done;}
		status = nc_inq_varid(ncid, "air_u", &wind_ucmp_id);
		if (status != NC_NOERR)
		{
			status = nc_inq_varid(ncid, "u", &wind_ucmp_id);
			if (status != NC_NOERR)
			{
				status = nc_inq_varid(ncid, "U", &wind_ucmp_id);
				if (status != NC_NOERR)
				{
					status = nc_inq_varid(ncid, "WindSpd_SFC", &wind_ucmp_id);
					if (status != NC_NOERR)
					{err = -1; goto done;}
					bIsNWSSpeedDirData = true;
				}
				//{err = -1; goto done;}
			}
			//{err = -1; goto done;}
		}
		if (bIsNWSSpeedDirData)
		{
			status = nc_inq_varid(ncid, "WindDir_SFC", &wind_vcmp_id);
			if (status != NC_NOERR)
			{err = -2; goto done;}
		}
		else
		{
			status = nc_inq_varid(ncid, "air_v", &wind_vcmp_id);
			if (status != NC_NOERR) 
			{
				status = nc_inq_varid(ncid, "v", &wind_vcmp_id);
				if (status != NC_NOERR) 
				{
					status = nc_inq_varid(ncid, "V", &wind_vcmp_id);
					if (status != NC_NOERR)
					{err = -1; goto done;}
				}
				//{err = -1; goto done;}
			}
		}
		
		status = nc_inq_varndims(ncid, wind_ucmp_id, &uv_ndims);
		if (status==NC_NOERR){if (uv_ndims < numdims && uv_ndims==3) {wind_count[1] = latlength; wind_count[2] = lonlength;}}	// could have more dimensions than are used in u,v
		
		status = nc_get_vara_float(ncid, wind_ucmp_id, wind_index, wind_count, wind_uvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_vara_float(ncid, wind_vcmp_id, wind_index, wind_count, wind_vvals);
		if (status != NC_NOERR) {err = -1; goto done;}
		status = nc_get_att_float(ncid, wind_ucmp_id, "_FillValue", &fill_value);
		if (status != NC_NOERR) 
		{
			status = nc_get_att_float(ncid, wind_ucmp_id, "Fill_Value", &fill_value);
			if (status != NC_NOERR)
			{
				status = nc_get_att_float(ncid, wind_ucmp_id, "fillValue", &fill_value);// nws 2.5km
				if (status != NC_NOERR)
				{
					status = nc_get_att_float(ncid, wind_ucmp_id, "missing_value", &fill_value);
				}
				/*if (status != NC_NOERR)*//*err = -1; goto done;*/}}	// don't require
		//if (status != NC_NOERR) {err = -1; goto done;}	// don't require
	}	
	
	status = nc_inq_attlen(ncid, wind_ucmp_id, "units", &velunit_len);
	if (status == NC_NOERR)
	{
		velUnits = new char[velunit_len+1];
		status = nc_get_att_text(ncid, wind_ucmp_id, "units", velUnits);
		if (status == NC_NOERR)
		{
			velUnits[velunit_len] = '\0'; 
			if (!strcmpnocase(velUnits,"knots"))
				velConversion = KNOTSTOMETERSPERSEC;
			else if (!strcmpnocase(velUnits,"m/s"))
				velConversion = 1.0;
		}
	}
	
	
	status = nc_close(ncid);
	if (status != NC_NOERR) {err = -1; goto done;}
	
	velH = (VelocityFH)_NewHandleClear(totalNumberOfVels * sizeof(VelocityFRec));
	if (!velH) {err = memFullErr; goto done;}
	//for (i=0;i<totalNumberOfVels;i++)
	for (i=0;i<latlength;i++)
	{
		for (j=0;j<lonlength;j++)
		{
			if (wind_uvals[(latlength-i-1)*lonlength+j]==fill_value)
				wind_uvals[(latlength-i-1)*lonlength+j]=0.;
			if (wind_vvals[(latlength-i-1)*lonlength+j]==fill_value)
				wind_vvals[(latlength-i-1)*lonlength+j]=0.;
			if (isnan(wind_uvals[(latlength-i-1)*lonlength+j])) 
				wind_uvals[(latlength-i-1)*lonlength+j]=0.;
			if (isnan(wind_vvals[(latlength-i-1)*lonlength+j])) 
				wind_vvals[(latlength-i-1)*lonlength+j]=0.;

			if (fIsNavy)
			{
				u_grid = (float)wind_uvals[(latlength-i-1)*lonlength+j];
				v_grid = (float)wind_vvals[(latlength-i-1)*lonlength+j];
				if (bRotated) angle = angle_vals[(latlength-i-1)*lonlength+j];
				INDEXH(velH,i*lonlength+j).u = u_grid*cos(angle*PI/180.)-v_grid*sin(angle*PI/180.);
				INDEXH(velH,i*lonlength+j).v = u_grid*sin(angle*PI/180.)+v_grid*cos(angle*PI/180.);
			}
			else if (bIsNWSSpeedDirData)
			{
				//INDEXH(velH,i*lonlength+j).u = KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				//INDEXH(velH,i*lonlength+j).v = KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
				// since direction is from rather than to need to switch the sign
				//INDEXH(velH,i*lonlength+j).u = -1. * KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				//INDEXH(velH,i*lonlength+j).v = -1. * KNOTSTOMETERSPERSEC * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
				INDEXH(velH,i*lonlength+j).u = -1. * velConversion * wind_uvals[(latlength-i-1)*lonlength+j] * sin ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);	// need units
				INDEXH(velH,i*lonlength+j).v = -1. * velConversion * wind_uvals[(latlength-i-1)*lonlength+j] * cos ((PI/180.) * wind_vvals[(latlength-i-1)*lonlength+j]);
			}
			else
			{
				// Look for a land mask, but do this if don't find one - float mask(lat,lon) - 1,0 which is which?
				//if (wind_uvals[(latlength-i-1)*lonlength+j]==0. && wind_vvals[(latlength-i-1)*lonlength+j]==0.)
				//wind_uvals[(latlength-i-1)*lonlength+j] = wind_vvals[(latlength-i-1)*lonlength+j] = 1e-06;
				
				// just leave fillValue as velocity for new algorithm - comment following lines out
				// should eliminate the above problem, assuming fill_value is a land mask
				// leave for now since not using a map...use the entire grid
				/////////////////////////////////////////////////
				
				INDEXH(velH,i*lonlength+j).u = /*KNOTSTOMETERSPERSEC**/velConversion*wind_uvals[(latlength-i-1)*lonlength+j];	// need units
				INDEXH(velH,i*lonlength+j).v = /*KNOTSTOMETERSPERSEC**/velConversion*wind_vvals[(latlength-i-1)*lonlength+j];
			}
		}
	}
	*velocityH = velH;
	fFillValue = fill_value;
	
	fWindScale = scale_factor;	// hmm, this forces a reset of scale factor each time, overriding any set by hand
	
done:
	if (err)
	{
		if (err==-2)
			strcpy(errmsg,"Error reading wind data from NetCDF file");
		else
			strcpy(errmsg,"Error reading wind direction data from NetCDF file");
		// We don't want to put up an error message here because it can lead to an infinite loop of messages.
		//printNote("Error opening NetCDF file");
		if(velH) {DisposeHandle((Handle)velH); velH = 0;}
	}
	if (wind_uvals) {delete [] wind_uvals; wind_uvals = 0;}
	if (wind_vvals) {delete [] wind_vvals; wind_vvals = 0;}
	if (angle_vals) {delete [] angle_vals; angle_vals = 0;}
	return err;
}
Esempio n. 8
0
int
main()
{
    printf("\n*** Creating file with datasets & attributes that have scalar dataspaces...");
    {
	hid_t fileid;
        hid_t fcplid;
	hid_t dsetid;
        hid_t dcplid;
	hid_t scalar_spaceid;
        hid_t vlstr_typeid, fixstr_typeid;
	hid_t attid;

        /* Create scalar dataspace */
	if ((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;

        /* Set creation ordering for file, so we can revise its contents later */
        if ((fcplid = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
        if (H5Pset_link_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
        if (H5Pset_attr_creation_order(fcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;
	
	/* Create new file, using default properties */
	if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcplid, H5P_DEFAULT)) < 0) ERR;
	
        /* Close file creation property list */
        if (H5Pclose(fcplid) < 0) ERR;


        /* Create variable-length string datatype */
        if ((vlstr_typeid = H5Tcreate(H5T_STRING, (size_t)H5T_VARIABLE)) < 0) ERR;

        /* Create fixed-length string datatype */
        if ((fixstr_typeid = H5Tcreate(H5T_STRING, (size_t)10)) < 0) ERR;


        /* Set creation ordering for dataset, so we can revise its contents later */
        if ((dcplid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
        if (H5Pset_attr_creation_order(dcplid, H5P_CRT_ORDER_TRACKED) < 0) ERR;

	
        /* Create scalar dataset with VL string datatype */
        if ((dsetid = H5Dcreate2(fileid, VSTR_VAR1_NAME, vlstr_typeid, scalar_spaceid, H5P_DEFAULT, dcplid, H5P_DEFAULT)) < 0) ERR;

        /* Add attributes to dataset */
        if (add_attrs(dsetid) < 0) ERR;

        /* Close VL string dataset */
        if (H5Dclose(dsetid) < 0) ERR;


        /* Create scalar dataset with fixed-length string datatype */
        if ((dsetid = H5Dcreate2(fileid, FSTR_VAR_NAME, fixstr_typeid, scalar_spaceid, H5P_DEFAULT, dcplid, H5P_DEFAULT)) < 0) ERR;

        /* Add attributes to dataset */
        if (add_attrs(dsetid) < 0) ERR;

        /* Close fixed-length string dataset */
        if (H5Dclose(dsetid) < 0) ERR;


        /* Create scalar dataset with native integer datatype */
        if ((dsetid = H5Dcreate2(fileid, INT_VAR_NAME, H5T_NATIVE_INT, scalar_spaceid, H5P_DEFAULT, dcplid, H5P_DEFAULT)) < 0) ERR;

        /* Add attributes to dataset */
        if (add_attrs(dsetid) < 0) ERR;

        /* Close native integer dataset */
        if (H5Dclose(dsetid) < 0) ERR;


        /* Add attributes to root group */
        if (add_attrs(fileid) < 0) ERR;


        /* Close dataset creation property list */
        if (H5Pclose(dcplid) < 0) ERR;

        /* Close string datatypes */
        if (H5Tclose(vlstr_typeid) < 0) ERR;
        if (H5Tclose(fixstr_typeid) < 0) ERR;


        /* Close rest */
	if (H5Sclose(scalar_spaceid) < 0) ERR;
	if (H5Fclose(fileid) < 0) ERR;
    }
    SUMMARIZE_ERR;

    printf("*** Checking accessing file through netCDF-4 API...");
    {
	int ncid, varid;
        size_t len;
        nc_type type;
        int ndims;
        char *vlstr;
        int x;

	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

        /* Check the global attributes are OK */
        if (check_attrs(ncid, NC_GLOBAL) < 0) ERR;

        /* Verify that the VL string dataset is present and OK */
	if (nc_inq_varid(ncid, VSTR_VAR1_NAME, &varid)) ERR;
        if (varid != 0) ERR;
	if (nc_inq_vartype(ncid, varid, &type)) ERR;
	if (type != NC_STRING) ERR;
        if (nc_inq_varndims(ncid, varid, &ndims)) ERR;
        if (ndims != 0) ERR;
        vlstr = NULL;
        if (nc_get_var(ncid, varid, &vlstr)) ERR;
        if (NULL != vlstr) ERR;

        /* Check the variable's attributes are OK */
        if (check_attrs(ncid, varid) < 0) ERR;

        /* Verify that the fixed-length string dataset is present and OK */
	if (nc_inq_varid(ncid, FSTR_VAR_NAME, &varid)) ERR;
        if (varid != 1) ERR;
	if (nc_inq_vartype(ncid, varid, &type)) ERR;
	if (type != NC_STRING) ERR;
        if (nc_inq_varndims(ncid, varid, &ndims)) ERR;
        if (ndims != 0) ERR;
        vlstr = NULL;
        if (nc_get_var(ncid, varid, &vlstr)) ERR;
        if ('\0' != *vlstr) ERR;
        free(vlstr);

        /* Check the variable's attributes are OK */
        if (check_attrs(ncid, varid) < 0) ERR;

        /* Verify that the integer dataset is present and OK */
	if (nc_inq_varid(ncid, INT_VAR_NAME, &varid)) ERR;
        if (varid != 2) ERR;
	if (nc_inq_vartype(ncid, varid, &type)) ERR;
	if (type != NC_INT) ERR;
        if (nc_inq_varndims(ncid, varid, &ndims)) ERR;
        if (ndims != 0) ERR;
        x = -1;
        if (nc_get_var(ncid, varid, &x)) ERR;
        if (0 != x) ERR;

        /* Check the variable's attributes are OK */
        if (check_attrs(ncid, varid) < 0) ERR;

	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;

    printf("*** Checking revising file through netCDF-4 API...");
    {
	int ncid, varid;
        char *vlstr;

	if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
        
        /* Write to the VL string variable */
	if (nc_inq_varid(ncid, VSTR_VAR1_NAME, &varid)) ERR;
        vlstr = NULL;
        if (nc_put_var(ncid, varid, &vlstr)) ERR;

        vlstr = malloc(10);
        *vlstr = '\0';
        if (nc_put_var(ncid, varid, &vlstr)) ERR;

        strcpy(vlstr, "foo");
        if (nc_put_var(ncid, varid, &vlstr)) ERR;
        free(vlstr);


        /* Write to a VL string attribute */
        vlstr = NULL;
        if (nc_put_att(ncid, varid, VSTR_ATT1_NAME, NC_STRING, 1, &vlstr)) ERR;

        vlstr = malloc(10);
        *vlstr = '\0';
        if (nc_put_att(ncid, varid, VSTR_ATT1_NAME, NC_STRING, 1, &vlstr)) ERR;

        strcpy(vlstr, "foo");
        if (nc_put_att(ncid, varid, VSTR_ATT1_NAME, NC_STRING, 1, &vlstr)) ERR;
        free(vlstr);


        /* Define a new VL string variable */
        if (nc_def_var(ncid, VSTR_VAR2_NAME , NC_STRING, 0, NULL, &varid)) ERR;

        /* Write to the variable's fill-value */
        vlstr = NULL;
        if (nc_put_att(ncid, varid, _FillValue, NC_STRING, 1, &vlstr)) ERR;

        vlstr = malloc(10);
        *vlstr = '\0';
        if (nc_put_att(ncid, varid, _FillValue, NC_STRING, 1, &vlstr)) ERR;

        strcpy(vlstr, "foo");
        if (nc_put_att(ncid, varid, _FillValue, NC_STRING, 1, &vlstr)) ERR;
        free(vlstr);


	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;

    FINAL_RESULTS;
}
Esempio n. 9
0
/*********************************************************************************
 * Read vlen strings given the numeric varid, start, and count to use
 */
SEXP R_nc4_get_vara_string( SEXP sx_nc, SEXP sx_varid, SEXP sx_start, SEXP sx_count ) 
{
	SEXP	sx_retval, sx_retnames, sx_retstrings, sx_reterror;
	int	i, ierr, varid, ncid, ndims, count_int[MAX_NC_DIMS], start_int[MAX_NC_DIMS], len_count, len_start; 
	size_t	count[MAX_NC_DIMS], start[MAX_NC_DIMS], tot_count, isz;
	char 	**ss;

	/* Convert passed parameters (which are in R format) into C format */
	ncid  = INTEGER(sx_nc   )[0];
	varid = INTEGER(sx_varid)[0];

	len_start = length(sx_start);
	for( i=0; i<len_start; i++ ) {
		start_int[i] = INTEGER(sx_start)[i];
		start    [i] = (size_t)(start_int[i]);
		}

	len_count = length(sx_count);
	for( i=0; i<len_count; i++ ) {
		count_int[i] = INTEGER(sx_count)[i];
		count    [i] = (size_t)(count_int[i]);
		}

	PROTECT( sx_retval   = allocVector( VECSXP, 2 ));       /* 2 elements in the returned list: $error, $strings */

	/* Set the names for the returned list */
	PROTECT( sx_retnames = allocVector( STRSXP, 2 ));       /* 2 elements in the returned list */
	SET_STRING_ELT( sx_retnames, 0, mkChar("error") );
	SET_STRING_ELT( sx_retnames, 1, mkChar("data") );
	setAttrib( sx_retval, R_NamesSymbol, sx_retnames );
	UNPROTECT(1); 

	/* Set the return error code */
	PROTECT( sx_reterror = allocVector( INTSXP, 1 ));
	INTEGER( sx_reterror)[0] = 0;

	/* Get number of dims in the var */
	nc_inq_varndims( ncid, varid, &ndims );

	/*--------------------------------------------------------------
	 * At this point we have all the C values we need:
	 *  	ncid
	 *	varid (numeric)
	 *	ndims
	 *	start
	 *	count
	 *---------------------------------------------------------------*/
	tot_count = 1L;
	for( i=0; i<ndims; i++ ) 
	 	tot_count *= count[i]; // NOTE ndims <= MAX_NC_DIMS, so count[i] is always non-garbage

	ss = (char **)malloc( sizeof( char *) * tot_count );
	if( ss == NULL ) {
		INTEGER( sx_reterror)[0] = -1;
		error("Error trying to allocate space to read the vlen strings: total count of strings requested: %ld\n", tot_count );
		}

	if( (ierr = nc_get_vara_string( ncid, varid, start, count, ss )) != 0 ) {
		INTEGER( sx_reterror)[0] = -2;
		//WCC fprintf( stderr, "Error reading vlen strings: %s\n", nc_strerror(ierr) );
		REprintf("Error reading vlen strings: %s\n", nc_strerror(ierr) );
		error("Error reading vlen strings\n" );
		}

	PROTECT( sx_retstrings = allocVector( STRSXP, tot_count ));
	for( isz=0L; isz<tot_count; isz++ ) {
		SET_STRING_ELT( sx_retstrings, isz, mkChar(ss[isz]) );
		}

	SET_VECTOR_ELT( sx_retval, 0, sx_reterror   );
	SET_VECTOR_ELT( sx_retval, 1, sx_retstrings );

	UNPROTECT(3);	

	/* Free netcdf string storage */
	nc_free_string( tot_count, ss );
	if (ss) free(ss);

	return( sx_retval );
}
Esempio n. 10
0
int read_field(int fn, int lev, char var_name[], double **array,
               size_t *nlay, size_t *nx, size_t *ny, double st[2]) {
  static int ncid;
  size_t start[MAX_VAR_DIMS] = {0}, count[MAX_VAR_DIMS];
  int i, varid, ndims, dimids[MAX_VAR_DIMS], recdim, status;
  
  ncid = ncInid[fn];
  if (ncid < 0) {
    printf("ERROR: Required file (%d) for reading %s is not open.\n",fn,var_name);
    exit(-1);
  }

  // printf("Inquire unlimdim of %s - id %d.\n",in_file,ncid);
  status = nc_inq_unlimdim(ncid,&recdim);
  if (status != NC_NOERR) handle_error(status,var_name,status);
  // printf("Done opening %s.\n",in_file);

  status = nc_inq_varid(ncid,var_name,&varid);
  if (status != NC_NOERR) handle_error(status,var_name,status);
  status = nc_inq_varndims(ncid,varid,&ndims);
  if (status != NC_NOERR) handle_error(status,var_name,status);
  status = nc_inq_vardimid(ncid,varid,dimids);
  if (status != NC_NOERR) handle_error(status,var_name,status);
  // printf("Get %d dim lengths %s.\n",ndims,in_file);
  for (i=0;i<ndims;i++) {
    status = nc_inq_dimlen(ncid,dimids[i],&count[i]);
    if (status != NC_NOERR) handle_error(status,var_name,i);
  }
  if (dimids[0] == recdim) {
    if (count[0] < lev+1) return -1;
    start[0] = lev; count[0] = 1;
  } else if (lev > 0) return -1;
  
  for (i=ndims-2;i<ndims;i++) {
    char dimname[NC_MAX_NAME];
    int varid;
    size_t index = 0;
    status = nc_inq_dimname(ncid,dimids[i],dimname);
    if (status != NC_NOERR) handle_error(status,var_name,i);
    status = nc_inq_varid(ncid, dimname, &varid);
    if (status != NC_NOERR) handle_error(status,dimname,status);
    status = nc_get_var1_double(ncid, varid, &index, &st[i-ndims+2]);
    if (status != NC_NOERR) handle_error(status,dimname,status);
  }
  
  // printf("Done getting info about %s.\n",var_name);
  
  if (*array == NULL) {
    size_t sz = 1;
    for (i=0;i<ndims;i++) if (count[i] > 1) sz *= count[i]+1;
    // printf("Attempting to allocate array of size %ld.\n",(long) sz);
    *array = (double *) calloc(sz, sizeof(double));
    if (*array == NULL) printf("Unable to allocate array of size %ld for %s.\n",(long) sz,var_name);
  }
  
  *nlay = count[ndims-3];
  *nx = count[ndims-1];
  *ny = count[ndims-2];

  {
    size_t sz = 1;
    for (i=0;i<ndims;i++) if (count[i] > 1) sz *= count[i];
    // printf("Attempting to read array of size %ld.\n",(long) sz);
  }
  status = nc_get_vara_double(ncid,varid,start,count,*array);
  
  if (status != NC_NOERR) return -1;

  return 0;
}
Esempio n. 11
0
/***************************************************************************************
 * Given a numeric varid, this reads the data from the file.
 * Does not return on errors.
 */
SEXP R_nc4_get_vara_numvarid( SEXP sx_nc, SEXP sx_varid, SEXP sx_start, SEXP sx_count ) 
{
	int 	varid, ncid, ndims, len_start, len_count, i, j, ierr,
		start_arg[MAX_NC_DIMS], count_arg[MAX_NC_DIMS],
		*data_addr_i, missval_i, ndims_cgt1;
	SEXP 	rv_data, sx_dim;
	size_t	start[MAX_NC_DIMS], count[MAX_NC_DIMS], varsize[MAX_NC_DIMS], tot_var_size,
		i_szt;
	double	*data_addr_d, missval_d, missval_tol;
	nc_type	vartype;

	/*--------------------------------------------------------------------------- 
	 * On entry, the following are guaranteed to be integers:
	 *	varid
	 *	*start
	 *	*count
	 *
	 * Note that varid, start, and/or count could be a single '-1' if the user
	 * has not specified the start and count to use.
	 * 'sx_nc' is guaranteed to be the full object of class 'ncdf'.
	 *----------------------------------------------------------------------------*/


	varid = INTEGER(sx_varid)[0];
	ncid  = INTEGER(R_ncu4_getListElement( sx_nc, "id" ))[0];
	R_ncu4_getListElement( sx_nc, "var" );

	/*-----------------------------------------------------------------------
	 * Copy passed start and count to local vars so we can modify them safely
	 *----------------------------------------------------------------------*/
	len_start = length(sx_start);
	for( i=0; i<len_start; i++ )
		start_arg[i] = INTEGER(sx_start)[i];
	len_count = length(sx_count);
	for( i=0; i<len_count; i++ )
		count_arg[i] = INTEGER(sx_count)[i];
	
	/*-----------------------------------------
	 * Get varid to use, if passed value is -1.
	 *----------------------------------------*/
	if( varid == -1 ) {
		/*----------------------------------------------------
		 * Get how many vars are in this file ... if only one,
		 * use that one.  Otherwise, signal error.
		 *---------------------------------------------------*/
		varid = R_ncu4_varid_onlyvar( ncid );
		if( varid == -1 ) 
			error( "Error: no var specified, and the file has more than one valid var!" );
		}
	else
		varid--;	/* go from R to C indexing */
	
	/*--------------------------------------------------------
	 * Get # of dims for this var, as a check to make sure any
	 * passed 'start' and 'count' are correct.
	 *-------------------------------------------------------*/
	ierr = nc_inq_varndims( ncid, varid, &ndims );
	if( ierr != NC_NOERR )
		error( "Internal error in ncdf package, routine R_nc4_get_vara_numvarid: failed to get ndims for var!\n" );

	/*------------------------------------------------------
	 * Get our variable's size, and the start & count to use
	 *-----------------------------------------------------*/
	R_ncu4_get_varsize( ncid, varid, ndims, varsize );
	R_ncu4_calc_start_count( ncid, varid, start_arg, len_start, count_arg, len_count, 
			varsize, ndims, start, count );

	/*------------------------------------------------------------
	 * Allocate space for data, depending on the type of var it is
	 *-----------------------------------------------------------*/
	ierr = nc_inq_vartype( ncid, varid, &vartype );
	if( ierr != NC_NOERR )
		error( "Internal error in ncdf package, routine R_nc4_get_vara_numvarid: failed to get type for var!\n" );

	tot_var_size = 1L;
	for( i=0; i<ndims; i++ ) {
		tot_var_size *= count[i];
		}

	switch( vartype ) {
		case NC_CHAR:
			error( "chars not handled yet, use old interface" );
			break;

		case NC_BYTE:
		case NC_SHORT:
		case NC_INT:
			/*---------------
			 * Allocate space
			 *--------------*/
			PROTECT( rv_data = allocVector( INTSXP, tot_var_size ));
			data_addr_i = &(INTEGER(rv_data)[0]);	/* Is this guaranteed to work?  Dunno. */

			/*--------------
			 * Read the data
			 *-------------*/
			ierr        = nc_get_vara_int( ncid, varid, start, count, data_addr_i );
			if( ierr != NC_NOERR )
				error( "Error while trying to read int data from file!" );

			/*---------------------
			 * Handle missing value
			 *--------------------*/
			ierr = nc_get_att_int( ncid, varid, "missing_value", &missval_i );
			if( ierr != NC_NOERR )
				/* No missing value attribute found, use default value */
				missval_i = NC_FILL_INT;
			for( i_szt=0L; i_szt<tot_var_size; i_szt++ ) 
				if( data_addr_i[i_szt] == missval_i )
					data_addr_i[i_szt] = NA_INTEGER;
			break;

		case NC_FLOAT:
		case NC_DOUBLE:
			/*---------------
			 * Allocate space
			 *--------------*/
			PROTECT( rv_data = allocVector( REALSXP, tot_var_size ));
			data_addr_d = &(REAL(rv_data)[0]);	/* Is this guaranteed to work?  Dunno. */

			/*--------------
			 * Read the data
			 *-------------*/
			ierr        = nc_get_vara_double( ncid, varid, start, count, data_addr_d );
			if( ierr != NC_NOERR )
				error( "Error while trying to read real data from file!" );

			/*---------------------
			 * Handle missing value
			 *--------------------*/
			ierr = nc_get_att_double( ncid, varid, "missing_value", &missval_d );
			if( ierr != NC_NOERR )
				/* No missing value attribute found, use default value */
				missval_d = 1.e30;
			missval_tol = 1.e-5*fabs(missval_d);
			for( i_szt=0L; i_szt<tot_var_size; i_szt++ ) 
				if( fabs(data_addr_d[i_szt] - missval_d) < missval_tol )
					data_addr_d[i_szt] = NA_REAL;
			break;

		default:
			error( "unhandled var type when allocating var space in R_nc4_get_vara_numvarid");
		}

	/*-----------------------------------------
	 * Set our dims (note: non-degenerate only)
	 *----------------------------------------*/
	ndims_cgt1 = 0;  
	for( i=0; i<ndims; i++ )
		if( count[i] > 1 )
			ndims_cgt1++;
	if( ndims_cgt1 == 0 ) {
		PROTECT( sx_dim = allocVector( INTSXP, 1 ));
		INTEGER(sx_dim)[0] = 1;
		}
	else
		{
		PROTECT( sx_dim = allocVector( INTSXP, ndims_cgt1 ));
		j = 0;
		for( i=0; i<ndims; i++ )
			if( count[i] > 1 ) {
				INTEGER(sx_dim)[ndims_cgt1-j-1] = count[i];
				j++;
				}
		}
	setAttrib( rv_data, R_DimSymbol, sx_dim );

	UNPROTECT(2);
	return(rv_data);
}
Esempio n. 12
0
/***********************************************************************
 *
 * HANDLE_NC_DEF_VAR_CHUNKING:
 *
 * code for handling the nc_def_var_chunking routine.
 *
 * status = mexnc('def_var_chunking',ncid,varid,storage,chunksize);
 *
 **********************************************************************/
void handle_nc_def_var_chunking 
( 
    int            nlhs, 
    mxArray       *plhs[], 
    int            nrhs, 
    const mxArray *prhs[], 
    op            *nc_op 
) 
{

    int ncid;
    int varid;
    int storage;
	size_t chunksize[NC_MAX_DIMS];
	

    /*
     * Pointer shortcut to matrix data.
     * */
    double *pr;


    /* 
     * Return status from netcdf operation.  
     * */
    int      status;


    /*
     * Loop index
     * */
    int j;

	/*
	 * Number of dimensions (inferred from length of chunk argument)
	 * */
	int ndims;


	/*
	 * number of elements in chunking parameter.
	 * */
	mwSize nelts;


    /*
     * Make sure that the inputs are the right type.
     * */
    check_numeric_argument_type ( prhs, nc_op->opname, 1 );
    check_numeric_argument_type ( prhs, nc_op->opname, 2 );

    if ( !((mxIsChar(prhs[3]) == false) || (mxIsDouble(prhs[3]) == false )) ) {
        sprintf ( error_message, 
                "datatype argument must be matlab native double precision (<== that one, please) or character, operation \"%s\", line %d file \"%s\"\n", 
                nc_op->opname, __LINE__, __FILE__ );
            mexErrMsgTxt ( error_message );
            return;
    }

    check_numeric_argument_type ( prhs, nc_op->opname, 4 );
    
    
    pr = mxGetData ( prhs[1] );
    ncid = (int)(pr[0]);
    pr = mxGetData ( prhs[2] );
    varid = (int)(pr[0]);

    if ( mxIsChar ( prhs[3] ) ) {

        /*
         * This one is for backwards compatibility.  I really 
         * wish people would not do this...
         * */
        storage = interpret_char_parameter  ( prhs[3] );

    } else {
        pr = mxGetData ( prhs[3] );
        storage = (int) (pr[0]);
    }


	status = nc_inq_varndims(ncid,varid,&ndims);
	if ( status != NC_NOERR ) {
        sprintf ( error_message, 
                 "Internal call to nc_inq_varndims failed, operation \"%s\", line %d file \"%s\"\n", 
                  nc_op->opname, __LINE__, __FILE__ );
        mexErrMsgTxt ( error_message );
        return;
	}

	nelts = mxGetNumberOfElements(prhs[4]);


    /*
     * Make sure the user didn't do something really stupid like give too many dimensions.
     * */
    if ( nelts > NC_MAX_VAR_DIMS ) {
            sprintf ( error_message, 
                "given number of chunk elements (%d) exceeds preset maximum of %d, operation \"%s\", line %d file \"%s\"\n", 
                nelts, NC_MAX_VAR_DIMS, nc_op->opname, __LINE__, __FILE__ );
            mexErrMsgTxt ( error_message );
            return;
    }


	/*
	 * Tell the user not to provide a chunksize argument for contiguous storage.
	 * */
	
	if ( ( storage == NC_CONTIGUOUS ) && (nelts > 0) ) {
        sprintf ( error_message, 
                "If the storage type is NC_CONTIGUOUS, then the chunksize parameter must be [], line %d file \"%s\"",
                __LINE__, __FILE__ );
        mexErrMsgTxt ( error_message );
        return;
	}


    pr = mxGetData ( prhs[4] );
	for ( j = 0; j < nelts; ++j ) {
		chunksize[j] = pr[j];
	}

    status = nc_def_var_chunking ( ncid, varid, storage, chunksize );
    plhs[0] = mexncCreateDoubleScalar ( status );


    return;

}
Esempio n. 13
0
/***********************************************************************
 *
 * HANDLE_NC_INQ_VAR_CHUNKING:
 *
 * code for handling the nc_inq_var_chunking routine.
 *
 * [storage,chunksize,status] = mexnc('inq_var_chunking',ncid,varid);
 *
 **********************************************************************/
void handle_nc_inq_var_chunking 
( 
    int            nlhs, 
    mxArray       *plhs[], 
    int            nrhs, 
    const mxArray *prhs[], 
    op            *nc_op 
) 
{

    int ncid;
    int varid;
    int storage;
	size_t chunksize[NC_MAX_DIMS];
	

    /*
     * Pointer shortcut to matrix data.
     * */
    double *pr;

	/*
	 * Size of chunking matrix.
	 * */
	mwSize mxsize[2];

    /* 
     * Return status from netcdf operation.  
     * */
    int      status;


    /*
     * Loop index
     * */
    int j;

	/*
	 * Number of dimensions (inferred from length of chunk argument)
	 * */
	int ndims;


    /*
     * Make sure that the inputs are the right type.
     * */
    check_numeric_argument_type ( prhs, nc_op->opname, 1 );
    check_numeric_argument_type ( prhs, nc_op->opname, 2 );

    pr = mxGetData ( prhs[1] );
    ncid = (int)(pr[0]);
    pr = mxGetData ( prhs[2] );
    varid = (int)(pr[0]);

	status = nc_inq_varndims(ncid,varid,&ndims);
	if ( status != NC_NOERR ) {
        sprintf ( error_message, 
                 "Internal call to nc_inq_varndims failed, operation \"%s\", line %d file \"%s\"\n", 
                  nc_op->opname, __LINE__, __FILE__ );
        mexErrMsgTxt ( error_message );
        return;
	}

    status = nc_inq_var_chunking ( ncid, varid, &storage, chunksize );
    plhs[2] = mexncCreateDoubleScalar ( status );

	if ( storage == NC_CONTIGUOUS ) {
		plhs[0] = mxCreateString ( "contiguous" );

		/*
		 * Return [] for the chunksize
		 * */
		mxsize[0] = 0;
		mxsize[1] = 0;
		plhs[1] = mxCreateNumericArray ( 2, mxsize, mxDOUBLE_CLASS, mxREAL );

		return;
	}

	plhs[0] = mxCreateString ( "chunked" );

	mxsize[0] = 1;
	mxsize[1] = ndims;
	plhs[1] = mxCreateNumericArray ( 2, mxsize, mxDOUBLE_CLASS, mxREAL );
	pr = mxGetData ( plhs[1] );
	for ( j = 0; j < ndims; ++j ) {
		pr[j] = chunksize[j];
	}



    return;

}
Esempio n. 14
0
/** \internal
\ingroup variables
*/
int
NCDEFAULT_put_vars(int ncid, int varid, const size_t * start,
	    const size_t * edges, const ptrdiff_t * stride,
	    const void *value0, nc_type memtype)
{
#ifdef VARS_USES_VARM
   NC* ncp;
   int stat = NC_check_id(ncid, &ncp);

   if(stat != NC_NOERR) return stat;
   return ncp->dispatch->put_varm(ncid,varid,start,edges,stride,NULL,value0,memtype);
#else
  /* Rebuilt put_vars code to simplify and avoid use of put_varm */

   int status = NC_NOERR;
   int i,isstride1,isrecvar;
   int rank;
   struct PUTodometer odom;
   nc_type vartype = NC_NAT;
   NC* ncp;
   size_t vartypelen;
   int memtypelen;
   const char* value = (const char*)value0;
   size_t numrecs;
   int nrecdims;                /* number of record dims for a variable */
   int is_recdim[NC_MAX_VAR_DIMS]; /* for variable's dimensions */
   size_t varshape[NC_MAX_VAR_DIMS];
   size_t mystart[NC_MAX_VAR_DIMS];
   size_t myedges[NC_MAX_VAR_DIMS];
   ptrdiff_t mystride[NC_MAX_VAR_DIMS];
   const char* memptr = value;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) memtype = vartype;

   /* compute the variable type size */
   status = nc_inq_type(ncid,vartype,NULL,&vartypelen);
   if(status != NC_NOERR) return status;

   if(memtype > NC_MAX_ATOMIC_TYPE)
	memtypelen = (int)vartypelen;
    else
	memtypelen = nctypelen(memtype);

   /* Check gross internal/external type compatibility */
   if(vartype != memtype) {
      /* If !atomic, the two types must be the same */
      if(vartype > NC_MAX_ATOMIC_TYPE
         || memtype > NC_MAX_ATOMIC_TYPE)
	 return NC_EBADTYPE;
      /* ok, the types differ but both are atomic */
      if(memtype == NC_CHAR || vartype == NC_CHAR)
	 return NC_ECHAR;
   }

   /* Get the variable rank */
   status = nc_inq_varndims(ncid, varid, &rank);
   if(status != NC_NOERR) return status;

   /* Get variable dimension sizes */
#if 0
   isrecvar = NC_is_recvar(ncid,varid,&numrecs);
#endif
   status = NC_inq_recvar(ncid,varid,&nrecdims,is_recdim);
   if(status != NC_NOERR) return status;
   isrecvar = (nrecdims > 0);
   NC_getshape(ncid,varid,rank,varshape);

   /* Optimize out using various checks */
   if (rank == 0) {
      /*
       * The variable is a scalar; consequently,
       * there is only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_put_vara(ncid, varid, start, edge1, value0, memtype);
   }

   /* Do various checks and fixups on start/edges/stride */
   isstride1 = 1; /* assume so */
   for(i=0;i<rank;i++) {
	size_t dimlen;
	mystart[i] = (start == NULL ? 0 : start[i]);
	if(edges == NULL) {
#if 0
	   if(i == 0 && isrecvar)
  	      myedges[i] = numrecs - start[i];
#else
	   if(is_recdim[i] && isrecvar)
  	      myedges[i] = varshape[i] - start[i];
#endif
	   else
	      myedges[i] = varshape[i] - mystart[i];
	} else
	    myedges[i] = edges[i];
	if(myedges[i] == 0)
	    return NC_NOERR; /* cannot write anything */
	mystride[i] = (stride == NULL ? 1 : stride[i]);
	if(mystride[i] <= 0
	   /* cast needed for braindead systems with signed size_t */
           || ((unsigned long) mystride[i] >= X_INT_MAX))
           return NC_ESTRIDE;
  	if(mystride[i] != 1) isstride1 = 0;
        /* illegal value checks */
#if 0
	dimlen = (i == 0 && isrecvar ? numrecs : varshape[i]);
	if(i == 0 && isrecvar) {/*do nothing*/}
#else
	dimlen = varshape[i];
	if(is_recdim[i]) {/*do nothing*/}
#endif
        else {
	  /* mystart is unsigned, will never be < 0 */
	  if(mystart[i] > dimlen)
	    return NC_EINVALCOORDS;
          /* myediges is unsigned, will never be < 0 */
	  if(mystart[i] + myedges[i] > dimlen)
	    return NC_EEDGE;
       }
   }
   if(isstride1) {
      return NC_put_vara(ncid, varid, mystart, myedges, value, memtype);
   }

   /* Initial version uses and odometer to walk the variable
      and read each value one at a time. This can later be optimized
      to read larger chunks at a time.
    */


   odom_init(&odom,rank,mystart,myedges,mystride);

   /* walk the odometer to extract values */
   while(odom_more(&odom)) {
      int localstatus = NC_NOERR;
      /* Write a single value */
      localstatus = NC_put_vara(ncid,varid,odom.index,nc_sizevector1,memptr,memtype);
      /* So it turns out that when get_varm is used, all errors are
         delayed and ERANGE will be overwritten by more serious errors.
      */
      if(localstatus != NC_NOERR) {
	    if(status == NC_NOERR || localstatus != NC_ERANGE)
	       status = localstatus;
      }
      memptr += memtypelen;
      odom_next(&odom);
   }
   return status;
#endif
}
Esempio n. 15
0
int main(int argc,char *argv[]) {
  struct DataMap *ptr;
  struct DataMapScalar *sx,*sy;
  struct DataMapArray *ax,*ay;
  size_t index[256];
  size_t start[256];
  size_t count[256];

  int s;
  unsigned char vbflg=0;
  unsigned char help=0;
  unsigned char option=0;
  unsigned char zflg=0;

  FILE *fp=NULL;
  gzFile zfp=0;

  FILE *mapfp;
  int n,c,x;
  int ncid;
  int block=0;
 
  int varid;
  
  int strsze;
  char **strptr;
  char *tmpbuf=NULL;

  OptionAdd(&opt,"-help",'x',&help);
  OptionAdd(&opt,"-option",'x',&option);
  OptionAdd(&opt,"vb",'x',&vbflg);
  OptionAdd(&opt,"z",'x',&zflg);


  if (argc>1) {
    arg=OptionProcess(1,argc,argv,&opt,NULL); 
    if (help==1) {
      OptionPrintInfo(stdout,hlpstr);
      exit(0);
    }
    if (option==1) {
      OptionDump(stdout,&opt);
      exit(0);
    }

    if (zflg) {
      zfp=gzopen(argv[arg],"r");
      if (zfp==0) {
        fprintf(stderr,"File not found.\n");
        exit(-1);
      }
    } else {
      fp=fopen(argv[arg],"r");
      if (fp==NULL) {
        fprintf(stderr,"File not found.\n");
        exit(-1);
      }
    }  

  } else {
    OptionPrintInfo(stdout,errstr);
    exit(-1);
  }


  /* load the map */

  mapfp=fopen(argv[arg+1],"r");
  loadmap(mapfp);
  fclose(mapfp);

 

  s=nc_open(argv[arg+2],NC_WRITE,&ncid);
  if (s !=NC_NOERR) {
    fprintf(stderr,"Error opening CDF file.\n");
    exit(-1);
  }


   


  block=0;
  while (1) {

    if (zflg) ptr=DataMapReadZ(zfp);
    else ptr=DataMapFread(fp);

    if (ptr==NULL) break;

    for (c=0;c<ptr->snum;c++) {
      sx=ptr->scl[c];
      for (n=0;n<snum;n++) {
        sy=sptr[n];
        if (strcmp(sx->name,sy->name) !=0) continue;
        if (sx->type !=sy->type) continue;
        break;
      }
      if (n !=snum) { /* mapped variable */
        s=nc_inq_varid(ncid,cdfsname[n],&varid);
        if (s !=NC_NOERR) {
          fprintf(stderr,"Error accessing CDF file.\n");
          exit(-1);
        }
        index[0]=block;
        switch (sx->type) {
        case DATACHAR:
          s=nc_put_var1_text(ncid,varid,index,sx->data.cptr);
          break;
        case DATASHORT:
          s=nc_put_var1_short(ncid,varid,index,sx->data.sptr);
          break;
        case DATAINT:
          s=nc_put_var1_long(ncid,varid,index,(long *) sx->data.iptr);
          break;
        case DATAFLOAT:
          s=nc_put_var1_float(ncid,varid,index,sx->data.fptr);
          break;
        case DATADOUBLE:
          s=nc_put_var1_double(ncid,varid,index,sx->data.dptr);
          break;
        case DATASTRING:
          start[0]=block;
          start[1]=0;
          count[0]=1;
          count[1]=strlen(*((char **) sx->data.vptr))+1;
          s=nc_put_vara_text(ncid,varid,start,count,
                             *((char **) sx->data.vptr));
          break;
	}
        if (s !=NC_NOERR) {
          fprintf(stderr,"Error writing CDF file (%d).\n",s);
          exit(-1);
        }
       
      }
    }

    for (c=0;c<ptr->anum;c++) {
      ax=ptr->arr[c];
      for (n=0;n<anum;n++) {
        ay=aptr[n];
      
        if (strcmp(ax->name,ay->name) !=0) continue;
        if (ax->type !=ay->type) continue;
        if (ax->dim !=ay->dim) continue;
        break;
      }
      if (n !=anum) { /* mapped variable */
      
        s=nc_inq_varid(ncid,cdfaname[n],&varid);
        if (s !=NC_NOERR) {
          fprintf(stderr,"Error accessing CDF file.\n");
          exit(-1);
        }
        start[0]=block;
        count[0]=1;
        n=1;
        for (x=0;x<ax->dim;x++) {
          start[1+x]=0;
          count[1+x]=ax->rng[x];
          n=n*ax->rng[x];
	}

        if (ax->type==DATASTRING) {
          int ndims;
          int dimids[NC_MAX_VAR_DIMS];
          size_t dimlen;
          s=nc_inq_varndims(ncid,varid,&ndims);
          if (s !=NC_NOERR) {
            fprintf(stderr,"Error accessing CDF file.\n");
            exit(-1);
          }
          s=nc_inq_vardimid(ncid,varid,dimids);
          if (s !=NC_NOERR) {
            fprintf(stderr,"Error accessing CDF file.\n");
            exit(-1);
          }
          if (ndims-2!=ax->dim) {
            fprintf(stderr,"Error matching dimensions.\n");
            exit(-1);
	  }
          
          s=nc_inq_dimlen(ncid,dimids[ndims-1],&dimlen);
          if (s !=NC_NOERR) {
            fprintf(stderr,"Error accessing CDF file.\n");
            exit(-1);
          }
          strsze=dimlen;
          tmpbuf=malloc(n*strsze);
          if (tmpbuf==NULL) {
            fprintf(stderr,"Failed to allocate buffer.\n");
            exit(-1);
	  }
          memset(tmpbuf,0,n*strsze);
          start[1+ax->dim]=0;
          count[1+ax->dim]=strsze;
          strptr=(char **) ax->data.vptr;
          for (x=0;x<n;x++) strncpy(tmpbuf+x*strsze,strptr[x],strsze);
	}               

        switch (ax->type) { 
        case DATACHAR:
           s=nc_put_vara_text(ncid,varid,start,count,ax->data.cptr);
           break;
        case DATASHORT:
           s=nc_put_vara_short(ncid,varid,start,count,ax->data.sptr);
           break;
        case DATAINT:
	  s=nc_put_vara_long(ncid,varid,start,count,(long *) ax->data.iptr);
           break;
        case DATAFLOAT:
           s=nc_put_vara_float(ncid,varid,start,count,ax->data.fptr);
           break;
        case DATADOUBLE:
           s=nc_put_vara_double(ncid,varid,start,count,ax->data.dptr);
           break;
        case DATASTRING:
           s=nc_put_vara_text(ncid,varid,start,count,tmpbuf);
	   break;
	}
        if (tmpbuf !=NULL) {
	  free(tmpbuf);
          tmpbuf=NULL;
	}

        if (s !=NC_NOERR) {
          fprintf(stderr,"Error writing CDF file (%d).\n",s);
          exit(-1);
        }
 
      }
    }
  

    DataMapFree(ptr);
    block++;
  }
  nc_close(ncid);
  if (zflg) gzclose(zfp);
  else fclose(fp);
  return 0;
}
Esempio n. 16
0
/** \internal
\ingroup variables
*/
int
NCDEFAULT_put_varm(
   int ncid,
   int varid,
   const size_t * start,
   const size_t * edges,
   const ptrdiff_t * stride,
   const ptrdiff_t * imapp,
   const void *value0,
   nc_type memtype)
{
   int status = NC_NOERR;
   nc_type vartype = NC_NAT;
   int varndims = 0;
   int maxidim = 0;
   NC* ncp;
   int memtypelen;
   const char* value = (char*)value0;

   status = NC_check_id (ncid, &ncp);
   if(status != NC_NOERR) return status;

/*
  if(NC_indef(ncp)) return NC_EINDEFINE;
  if(NC_readonly (ncp)) return NC_EPERM;
*/

   /* mid body */
   status = nc_inq_vartype(ncid, varid, &vartype);
   if(status != NC_NOERR) return status;
   /* Check that this is an atomic type */
   if(vartype > NC_MAX_ATOMIC_TYPE)
	return NC_EMAPTYPE;

   status = nc_inq_varndims(ncid, varid, &varndims);
   if(status != NC_NOERR) return status;

   if(memtype == NC_NAT) {
      memtype = vartype;
   }

   if(memtype == NC_CHAR && vartype != NC_CHAR)
      return NC_ECHAR;
   else if(memtype != NC_CHAR && vartype == NC_CHAR)
      return NC_ECHAR;

   memtypelen = nctypelen(memtype);

   maxidim = (int) varndims - 1;

   if (maxidim < 0)
   {
      /*
       * The variable is a scalar; consequently,
       * there s only one thing to get and only one place to put it.
       * (Why was I called?)
       */
      size_t edge1[1] = {1};
      return NC_put_vara(ncid, varid, start, edge1, value, memtype);
   }

   /*
    * else
    * The variable is an array.
    */
   {
      int idim;
      size_t *mystart = NULL;
      size_t *myedges = 0;
      size_t *iocount= 0;    /* count vector */
      size_t *stop = 0;   /* stop indexes */
      size_t *length = 0; /* edge lengths in bytes */
      ptrdiff_t *mystride = 0;
      ptrdiff_t *mymap= 0;
      size_t varshape[NC_MAX_VAR_DIMS];
      int isrecvar;
      size_t numrecs;
      int stride1; /* is stride all ones? */

      /*
       * Verify stride argument.
       */
      stride1 = 1;		/*  assume ok; */
      if(stride != NULL) {
	 for (idim = 0; idim <= maxidim; ++idim) {
            if ((stride[idim] == 0)
		/* cast needed for braindead systems with signed size_t */
                || ((unsigned long) stride[idim] >= X_INT_MAX))
	    {
	       return NC_ESTRIDE;
            }
	    if(stride[idim] != 1) stride1 = 0;
	 }
      }

      /* If stride1 is true, and there is no imap, then call get_vara
         directly
      */
      if(stride1 && imapp == NULL) {
	 return NC_put_vara(ncid, varid, start, edges, value, memtype);
      }

      /* Compute some dimension related values */
      isrecvar = NC_is_recvar(ncid,varid,&numrecs);
      NC_getshape(ncid,varid,varndims,varshape);

      /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */
      mystart = (size_t *)calloc((size_t)(varndims * 7), sizeof(ptrdiff_t));
      if(mystart == NULL) return NC_ENOMEM;
      myedges = mystart + varndims;
      iocount = myedges + varndims;
      stop = iocount + varndims;
      length = stop + varndims;
      mystride = (ptrdiff_t *)(length + varndims);
      mymap = mystride + varndims;

      /*
       * Initialize I/O parameters.
       */
      for (idim = maxidim; idim >= 0; --idim)
      {
	 mystart[idim] = start != NULL
	    ? start[idim]
	    : 0;

	 if (edges != NULL && edges[idim] == 0)
	 {
	    status = NC_NOERR;    /* read/write no data */
	    goto done;
	 }

	 myedges[idim] = edges != NULL
	    ? edges[idim]
	    : idim == 0 && isrecvar
    	        ? numrecs - mystart[idim]
	        : varshape[idim] - mystart[idim];
	 mystride[idim] = stride != NULL
	    ? stride[idim]
	    : 1;
	 mymap[idim] = imapp != NULL
	    ? imapp[idim]
	    : idim == maxidim
	        ? 1
	        : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1];

	 iocount[idim] = 1;
	 length[idim] = ((size_t)mymap[idim]) * myedges[idim];
	 stop[idim] = mystart[idim] + myedges[idim] * (size_t)mystride[idim];
      }

      /*
       * Check start, edges
       */
      for (idim = isrecvar; idim < maxidim; ++idim)
      {
	 if (mystart[idim] > varshape[idim])
	 {
	    status = NC_EINVALCOORDS;
	    goto done;
	 }
	 if (mystart[idim] + myedges[idim] > varshape[idim])
	 {
	    status = NC_EEDGE;
	    goto done;
	 }
      }

      /* Lower body */
      /*
       * As an optimization, adjust I/O parameters when the fastest
       * dimension has unity stride both externally and internally.
       * In this case, the user could have called a simpler routine
       * (i.e. ncvar$1()
       */
      if (mystride[maxidim] == 1
	  && mymap[maxidim] == 1)
      {
	 iocount[maxidim] = myedges[maxidim];
	 mystride[maxidim] = (ptrdiff_t) myedges[maxidim];
	 mymap[maxidim] = (ptrdiff_t) length[maxidim];
      }

      /*
       * Perform I/O.  Exit when done.
       */
      for (;;)
      {
	 /* TODO: */
	 int lstatus = NC_put_vara(ncid, varid, mystart, iocount,
				   value, memtype);
	 if (lstatus != NC_NOERR) {
	    if(status == NC_NOERR || lstatus != NC_ERANGE)
	       status = lstatus;
	 }

	 /*
	  * The following code permutes through the variable s
	  * external start-index space and it s internal address
	  * space.  At the UPC, this algorithm is commonly
	  * called "odometer code".
	  */
	 idim = maxidim;
        carry:
	 value += (mymap[idim] * memtypelen);
	 mystart[idim] += (size_t)mystride[idim];
	 if (mystart[idim] == stop[idim])
	 {
	    size_t l = (length[idim] * (size_t)memtypelen);
	    value -= l;
	    mystart[idim] = start[idim];
	    if (--idim < 0)
	       break; /* normal return */
	    goto carry;
	 }
      } /* I/O loop */
     done:
      free(mystart);
   } /* variable is array */
   return status;
}
Esempio n. 17
0
File: ncdf.c Progetto: cran/ncdf
void R_nc_put_vara_text( int *ncid, int *varid, int *start,
	int *count, char **data, int *retval )
{
	int	ndims, err, idx_string, idx_char;
	size_t 	s_start[MAX_NC_DIMS], s_count[MAX_NC_DIMS], slen, slen2use;
	long	i, j, k, stridx, nstrings, nj, nk;

	/* Get # of dims for this var */
	err = nc_inq_varndims( *ncid, *varid, &ndims );
	if( err != NC_NOERR )
		REprintf("Error on nc_inq_varndims call in R_nc_put_vara_int: %s\n", 
			nc_strerror(*retval) );

	/* Copy over from ints to size_t.  Remember things are in C style at
	 * this point, so the rightmost dim is the number of characters
	 */
	for( i=0; i<ndims; i++ ) {
		s_start[i] = (size_t)start[i];
		s_count[i] = (size_t)count[i];
		}

	/* Chars are an unusually difficult because R seems to store
	 * them as an array of character pointers, while netcdf stores
	 * them as a monolithic block (like any other var type).  We
	 * must convert between these representations.
	 */
	slen = s_count[ndims-1];
	if( ndims == 1 ) {
		*retval = nc_put_vara_text(*ncid, *varid, s_start, s_count, data[0] );
		if( *retval != NC_NOERR ) 
			REprintf("Error in R_nc_put_vara_int: %s\n", 
				nc_strerror(*retval) );
		}

	else if( ndims == 2 ) {
		idx_string = 0;
		idx_char   = 1;
		nstrings = s_count[idx_string];  /* number of character strings */
		for( i=0L; i<nstrings; i++ ) {
			slen2use = ((slen < strlen(data[i])) ? slen : strlen(data[i]));
			s_count[idx_string] = 1L;
			s_count[idx_char  ] = slen2use;
			s_start[idx_string] = i + start[idx_string];
			s_start[idx_char  ] = 0L;
			*retval = nc_put_vara_text(*ncid, *varid, s_start, s_count, data[i] );
			if( *retval != NC_NOERR ) {
				REprintf("Error in R_nc_put_vara_text: %s\n", 
					nc_strerror(*retval) );
				return;
				}
			}
		}
	else if( ndims == 3 ) {
		stridx = 0L;
		nj = s_count[0];
		nstrings = s_count[1];
		for( j=0L; j<nj; j++ )
		for( i=0L; i<nstrings; i++ ) {
			slen2use = ((slen < strlen(data[i])) ? slen : strlen(data[stridx]));
			s_count[0] = 1L;
			s_count[1] = 1L;
			s_count[2] = slen2use;
			s_start[0] = j;
			s_start[1] = i;
			s_start[2] = 0L;
			*retval = nc_put_vara_text(*ncid, *varid, s_start, s_count, data[stridx++] );
			if( *retval != NC_NOERR ) {
				REprintf("Error in R_nc_put_vara_text: %s\n", 
					nc_strerror(*retval) );
				return;
				}
			}
		}
	else if( ndims == 4 ) {
		stridx = 0L;
		nk = s_count[0];
		nj = s_count[1];
		nstrings = s_count[2];
		for( k=0L; k<nk; k++ )
		for( j=0L; j<nj; j++ )
		for( i=0L; i<nstrings; i++ ) {
			slen2use = ((slen < strlen(data[i])) ? slen : strlen(data[stridx]));
			s_count[0] = 1L;
			s_count[1] = 1L;
			s_count[2] = 1L;
			s_count[3] = slen2use;
			s_start[0] = k;
			s_start[1] = j;
			s_start[2] = i;
			s_start[3] = 0L;
			*retval = nc_put_vara_text(*ncid, *varid, s_start, s_count, data[stridx++] );
			if( *retval != NC_NOERR ) {
				REprintf("Error in R_nc_put_vara_text: %s\n", 
					nc_strerror(*retval) );
				return;
				}
			}
		}
	else
		{
		*retval = -1;
		REprintf("Error in R_nc_put_vara_text: unhandled case.  I only handle char dims with # of dims up to 4.  Was passed # dims = %d\n", ndims );
		return;
		}
}
Esempio n. 18
0
int main(int argc, char **argv) {
	if(argc < 4) {
		printf("Usage: nc32bin varname nc3file binfile\n");
		exit(1);
	}

	int status, i, ndims;
	int ncfile_id, ncvar_id;
	int dimids[DIM_LEN];
	size_t size, nelmts, buflen;
	size_t dimlens[DIM_LEN];
	nc_type vartype;
	void *buf = NULL;

	/*
	 * read nc file
	 */
	status = nc_open(argv[2], NC_NOWRITE, &ncfile_id);
	NC_ASSERT(status);

	status = nc_inq_varid(ncfile_id, argv[1], &ncvar_id);
	NC_ASSERT(status);
	
	nc_inq_varndims(ncfile_id, ncvar_id, &ndims);
	nc_inq_vartype(ncfile_id, ncvar_id, &vartype);
	nc_inq_vardimid(ncfile_id, ncvar_id, dimids);
	for(i = 0; i < ndims; i++)
		nc_inq_dimlen(ncfile_id, dimids[i], &(dimlens[i]));

	size = get_type_size(vartype);
	nelmts = 1;
	for(i = 0; i < ndims; i++)
		nelmts *= dimlens[i];
	buflen = size * nelmts;
	buf = malloc(buflen);
	MEMORY_CHECK(buf);
	
	if(NC_SHORT == vartype)
		status = nc_get_var_short(ncfile_id, ncvar_id, (short *)buf);
	else if(NC_USHORT == vartype)
		status = nc_get_var_ushort(ncfile_id, ncvar_id, (unsigned short *)buf);
	else if(NC_INT == vartype)
		status = nc_get_var_int(ncfile_id, ncvar_id, (int *)buf);
	else if(NC_UINT == vartype)
		status = nc_get_var_uint(ncfile_id, ncvar_id, (unsigned int *)buf);
	else if(NC_INT64 == vartype)
		status = nc_get_var_longlong(ncfile_id, ncvar_id, (long long *)buf);
	else if(NC_UINT64 == vartype)
		status = nc_get_var_ulonglong(ncfile_id, ncvar_id, (unsigned long long *)buf);
	else if(NC_FLOAT == vartype)
		status = nc_get_var_float(ncfile_id, ncvar_id, (float *)buf);
	else if(NC_DOUBLE == vartype)
		status = nc_get_var_double(ncfile_id, ncvar_id, (double *)buf);
	
	NC_ASSERT(status);
	nc_close(ncfile_id);

	
	/*
	 * write binary
	 */
	FILE *fp = NULL;
	fp = fopen(argv[3], "wb");
	assert(fp != NULL);
	fwrite(buf, size, nelmts, fp);
	fclose(fp);

	return 0;
}
Esempio n. 19
0
int 
nccf_get_vara(int ncid, int varid, float *lat_range, int *nlat, float *lon_range, 
	      int *nlon, int lvl_index, int timestep, void *data)
{
   nc_type xtype[NDIMS];
   char name[NDIMS][NC_MAX_NAME];
   int did[NDIMS], vid[NDIMS];
   size_t len[NDIMS];
   size_t start[NDIMS], end[NDIMS];
   int ndims, dimids[MAX_DIMS];
   size_t dstart[NDIMS], dcount[NDIMS];
   int num[NDIMS];
   int found_lvl = 0, found_time = 0;
   int d;
   int ret;

   /* Get information about each coordinate axis. */
   if ((ret = nccf_inq_latitude(ncid, &len[LAT], &xtype[LAT], &did[LAT], &vid[LAT])))
      return ret;
   if ((ret = nccf_inq_longitude(ncid, &len[LON], &xtype[LON], &did[LON], &vid[LON])))
      return ret;

   /* Get the vertical level info, if there is one. */
   ret = nccf_inq_lvl(ncid, name[LVL], &len[LVL], &xtype[LVL], NULL, NULL, NULL, 
		      &did[LVL], &vid[LVL]);
   if (ret && ret != CF_ENOTFOUND)
      return ret;
   else if (ret == CF_NOERR)
      found_lvl++;

   /* Get the time info, if there is a time axis. */
   ret = nccf_inq_time(ncid, name[TIME], &len[TIME], &xtype[TIME], &did[TIME], 
		       &vid[TIME]);
   if (ret && ret != CF_ENOTFOUND)
      return ret;
   else if (ret == CF_NOERR)
      found_time++;

   /* Find the indixies along the latitude coordinate values to subset
    * along this dimension. */
   if ((ret = find_coord_idx(ncid, vid[LAT], len[LAT], lat_range, &num[LAT], 
			     &start[LAT], &end[LAT])))
      return ret;
   if (nlat)
      *nlat = num[LAT];

   /* Find the indixies along the longitude coordinate values to subset
    * along this dimension. */
   if ((ret = find_coord_idx(ncid, vid[LON], len[LON], lon_range, &num[LON], 
			     &start[LON], &end[LON])))
      return ret;
   if (nlon)
      *nlon = num[LON];

   /* If level indicies are not provided, take all levels. */
/*    if (!lvl_index) */
/*       num[LVL] = len[LVL]; */
/*    else */
/*       num[LVL] = 1; */
/*    if (nlvl) */
/*       *nlvl = num[LVL]; */

   if (found_time && timestep >= len[TIME])
      return CF_ERECTOOLARGE;

   /* If the user wants the data, get it for him. */
   if (lat_range && lon_range && data && num[LAT] && num[LON])
   {
      /* Find out about the dimensions of this data variable. */
      if ((ret = nc_inq_varndims(ncid, varid, &ndims)))
	 return ret;
      if (ndims > MAX_DIMS)
	 return CF_ENDIMS;
      if ((ret = nc_inq_vardimid(ncid, varid, dimids)))
	 return ret;

      /* Set the lat info. */
      for (d = 0; d < ndims; d++)
	 if (dimids[d] == did[LAT])
	    break;
      if (d == ndims)
	 return CF_ENODIM;
      dstart[d] = start[LAT];
      dcount[d] = num[LAT];

      /* Set the lon info. */
      for (d = 0; d < ndims; d++)
	 if (dimids[d] == did[LON])
	    break;
      if (d == ndims)
	 return CF_ENODIM;
      dstart[d] = start[LON];
      dcount[d] = num[LON];

      /* Set the level info. */
      if (found_lvl)
      {
	 for (d = 0; d < ndims; d++)
	    if (dimids[d] == did[LVL])
	       break;
	 if (d != ndims)
	 {
	    dstart[d] = lvl_index;
	    dcount[d] = 1;
	 }
      }

      /* Set the time info. */
      if (found_time)
      {
	 for (d = 0; d < ndims; d++)
	    if (dimids[d] == did[TIME])
	       break;
	 if (d != ndims)
	 {
	    dstart[d] = timestep;
	    dcount[d] = 1;
	 }
      }

      /* Now I've got everything needed to read a record of this data! */
      if ((ret = nc_get_vara(ncid, varid, dstart, dcount, data)))
	 return ret;
   }

   return CF_NOERR;
}
Esempio n. 20
0
/**
 * @ingroup PIO_inq_var
 * Inquire about chunksizes for a variable.
 *
 * This function only applies to netCDF-4 files. When used with netCDF
 * classic files, the error PIO_ENOTNC4 will be returned.
 *
 * See the <a
 * href="http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html">netCDF
 * variable documentation</a> for details about the operation of this
 * function.
 * 
 * @param ncid the ncid of the open file.
 * @param varid the ID of the variable to set chunksizes for.
 * @param storagep pointer to int which will be set to either
 * NC_CONTIGUOUS or NC_CHUNKED.
 * @param chunksizep pointer to memory where chunksizes will be
 * set. There are the same number of chunksizes as there are
 * dimensions.
 * 
 * @return PIO_NOERR for success, otherwise an error code.
 */
int PIOc_inq_var_chunking(int ncid, int varid, int *storagep, PIO_Offset *chunksizesp)
{
    int ierr;
    int msg;
    int mpierr;
    iosystem_desc_t *ios;
    file_desc_t *file;
    char *errstr;
    int ndims;

    errstr = NULL;
    ierr = PIO_NOERR;

    if (!(file = pio_get_file_from_id(ncid)))
	return PIO_EBADID;
    ios = file->iosystem;
    msg = PIO_MSG_INQ_VAR_CHUNKING;

    if (ios->async_interface && ! ios->ioproc)
    {
	if (ios->compmaster) 
	    mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm);
	mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm);
    }

    if (ios->ioproc)
    {
	switch (file->iotype)
	{
#ifdef _NETCDF
#ifdef _NETCDF4
	case PIO_IOTYPE_NETCDF4P:
	    ierr = nc_inq_var_chunking(file->fh, varid, storagep, chunksizesp);
	    break;
	case PIO_IOTYPE_NETCDF4C:
	    if (ios->io_rank == 0)
	    {
		if ((ierr = nc_inq_var_chunking(file->fh, varid, storagep, chunksizesp)))
		    return ierr;
		if ((ierr = nc_inq_varndims(file->fh, varid, &ndims)))
		    return ierr;
	    }
	    break;
#endif
	case PIO_IOTYPE_NETCDF:
	    return PIO_ENOTNC4;
	    break;
#endif
#ifdef _PNETCDF
	case PIO_IOTYPE_PNETCDF:
	    return PIO_ENOTNC4;
	    break;
#endif
	default:
	    ierr = iotype_error(file->iotype,__FILE__,__LINE__);
	}
    }

    /* If there is an error, allocate space for the error string. */
    if (ierr != PIO_NOERR)
    {
	errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char));
	sprintf(errstr,"in file %s",__FILE__);
    }

    /* Check the netCDF return code, and broadcast it to all tasks. */
    ierr = check_netcdf(file, ierr, errstr,__LINE__);

    /* Free the error stringif it was allocated. */
    if (errstr != NULL)
	free(errstr);

    /* Broadcast results to all tasks. */
    ierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->ioroot, ios->my_comm);
    if (storagep)
	ierr = MPI_Bcast(storagep, 1, MPI_INT, ios->ioroot, ios->my_comm);
    if (chunksizesp)
	ierr = MPI_Bcast(chunksizesp, ndims, MPI_OFFSET, ios->ioroot, ios->my_comm);

    return ierr;
}
Esempio n. 21
0
bool NCaxisInitialize (int ncid, NCaxis_p axis, NCaxisType axisType, ut_system *utSystem) {
	int status;
	int varid;
	int ndims;
	size_t attlen, i;
	char text [NC_MAX_NAME + 1];
	double interval;
	bool doUnits = true;

	switch (axis->AxisType = axisType) {
	case NCaxisX:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"x")) == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"X")) == CMfailed)) {
			CMmsgPrint (CMmsgAppError, "Missing x axis variable in NetCDF file!\n");
			return (false);
		}
		break;
	case NCaxisY:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"y")) == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"Y")) == CMfailed)) {
			CMmsgPrint (CMmsgAppError, "Missing y axis variable in NetCDF file!\n");
			return (false);
		}
		break;
	case NCaxisZ:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"z")) == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"Z")) == CMfailed)) {
			axis->Dimid = 0;
			if (((axis->Data   = (double *) malloc (sizeof (double)))     == (double *) NULL) ||
				((axis->Bounds = (double *) malloc (sizeof (double) * 2)) == (double *) NULL)) {
				CMmsgPrint (CMmsgSysError, "Memory allocation error in %s:%d!\n",__FILE__,__LINE__);
				return (false);
			}
			axis->N     = 1;
			axis->Dimid = CMfailed;
			axis->Data [0] = axis->Bounds [0] = axis->Bounds [1] = 0.0;
			return (true);
		}
		break;
	case NCaxisTime:
		if (((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"t"))    == CMfailed) &&
		    ((varid = NCfindVariableByAttribute (ncid,1,NCaxisStr,"time")) == CMfailed)) {
			CMmsgPrint (CMmsgAppError, "Missing time axis variable in NetCDF file!\n");
			return (false);
		}
		break;
	}
	if (((status = nc_inq_varndims (ncid,varid,&ndims))           != NC_NOERR) || (ndims != 1) ||
		((status = nc_inq_vardimid (ncid,varid,&(axis->Dimid)))   != NC_NOERR) ||
	    ((status = nc_inq_dimlen   (ncid,axis->Dimid,&(axis->N))) != NC_NOERR)) {
		CMmsgPrint (CMmsgAppError,"NetCDF variable dimension inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
		return (false);
	}
	if ((status = nc_inq_attlen   (ncid,varid,NCaxisStr,&attlen)) == NC_NOERR) {
		if ((axis->Axis = (char *) malloc (attlen + 1)) == (char *) NULL) {
			CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_att_text (ncid,varid,NCaxisStr,axis->Axis)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else axis->Axis [attlen] = '\0';
	}
	if ((status = nc_inq_attlen   (ncid,varid,NClongNameStr,&attlen)) == NC_NOERR) {
		if ((axis->LongName = (char *) malloc (attlen + 1)) == (char *) NULL) {
			CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_att_text (ncid,varid,NClongNameStr,axis->LongName)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else axis->LongName [attlen] = '\0';
	}
	if ((status = nc_inq_attlen   (ncid,varid,NCstandardNameStr,&attlen)) == NC_NOERR) {
		if ((axis->StandardName = (char *) malloc (attlen + 1)) == (char *) NULL) {
			CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_att_text (ncid,varid,NCstandardNameStr,axis->StandardName)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else axis->StandardName [attlen] = '\0';
	}
	if (doUnits) {
		if ((status = nc_inq_attlen   (ncid,varid,NCunitsStr,&attlen)) == NC_NOERR) {
			if (attlen > 0) {
				if ((status = nc_get_att_text (ncid,varid,NCunitsStr,text)) != NC_NOERR) {
					CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
					return (false);
				}
				else text [attlen] = '\0';
				if ((axis->Unit = ut_parse (utSystem, ut_trim (text, UT_ASCII), UT_ASCII)) == (ut_unit *) NULL) {
					switch (ut_get_status ()) {
					case UT_BAD_ARG: CMmsgPrint (CMmsgAppError, "System or string is NULL!\n");               break;
					case UT_SYNTAX:  CMmsgPrint (CMmsgAppError, "String contained a syntax error!n");         break;
					case UT_UNKNOWN: CMmsgPrint (CMmsgAppError, "String contained an unknown identifier!\n"); break;
					default:         CMmsgPrint (CMmsgSysError, "System error in %s:%d!n",__FILE__,__LINE__);
					}
				}
			}
		}
	}
	if (((status = nc_inq_attlen   (ncid,varid,NCpositiveStr,&attlen)) == NC_NOERR) && (attlen < NC_MAX_NAME)) {
		if ((status = nc_get_att_text (ncid,varid,NCpositiveStr,text)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else text [attlen] = '\0';
		axis->Direction = strcmp (text,NCpositiveUpStr) == 0 ? NCdirUp : NCdirDown;
	}
	else axis->Direction = NCdirUp;
	if (((axis->Data   = (double *) malloc (axis->N * sizeof (double)))     == (double *) NULL) ||
	    ((axis->Bounds = (double *) malloc (axis->N * sizeof (double) * 2)) == (double *) NULL)) {
		CMmsgPrint (CMmsgSysError,"Memory allocation error in: %s:%d!\n",__FILE__,__LINE__);
		return (false);
	}
	if ((status = nc_get_var_double (ncid,varid,axis->Data)) != NC_NOERR) {
		CMmsgPrint (CMmsgAppError,"NetCDF %s axis data loading error \"%s\" in %s:%d!\n",_NCaxisGetTypeString (axis->AxisType),nc_strerror (status),__FILE__,__LINE__);
		return (false);
	}
	if (((status = nc_inq_attlen (ncid,varid,NCboundsStr, &attlen)) == NC_NOERR) && (attlen < NC_MAX_NAME)) {
		if ((status = nc_get_att_text (ncid,varid,NCboundsStr,text)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF bounds attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		else text [attlen] = '\0';
		if ((status = nc_inq_varid (ncid,text,&varid)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF bounds variable inquery error \"%s\" in %s:%d!\n",   nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		if ((status = nc_get_var_double (ncid,varid,axis->Bounds)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF %s axis bounds loading error \"%s\" in %s:%d!\n",_NCaxisGetTypeString (axis->AxisType),nc_strerror (status),__FILE__,__LINE__);
			return (false);
		}
		
	}
	else {
		for (i = 1;i < axis->N - 1; ++i) {
			axis->Bounds [i * 2]     = (axis->Data [i]     + axis->Data [i - 1]) / 2.0;
			axis->Bounds [i * 2 + 1] = (axis->Data [i + 1] + axis->Data [i])     / 2.0;
		}
		axis->Bounds [1]         = axis->Bounds [2];
		axis->Bounds [0]         = axis->Data [0] - (axis->Bounds [1] - axis->Data [0]);
		axis->Bounds [i * 2]     = axis->Bounds [(i - 1) * 2 + 1];
		axis->Bounds [i * 2 + 1] = axis->Data [i] + (axis->Data [i]   - axis->Bounds [i * 2]);
	}
	axis->IntervalMin = axis->Bounds [i * 2 + 1] - axis->Bounds [0];
	axis->IntervalMax = 0.0;
	for (i = 0;i < axis->N; ++i) {
		interval = axis->Bounds [i * 2 + 1] - axis->Bounds [i * 2];
		axis->IntervalMin = CMmathMinimum (axis->IntervalMin,interval);
		axis->IntervalMax = CMmathMaximum (axis->IntervalMax,interval);
	}
	axis->Regular = axis->N > 1 ? CMmathEqualValues (axis->IntervalMin,axis->IntervalMax) : true;
	return (true);
}
Esempio n. 22
0
/**
 * Convert a Version 2 Fortran IMAP vector into a Version 3 C imap vector.
 */
static ptrdiff_t*
f2c_v2imap(int ncid, int varid, const int* fimap, ptrdiff_t* cimap)
{
    int		rank;
    nc_type	datatype;

    if (nc_inq_vartype(ncid, varid, &datatype) ||
	nc_inq_varndims(ncid, varid, &rank) || rank <= 0)
    {
	return NULL;
    }

    /* else */
    if (fimap[0] == 0)
    {
	/*
	 * Special Fortran version 2 semantics: use external netCDF variable 
	 * structure.
	 */
	int		dimids[NC_MAX_VAR_DIMS];
	int		idim;
	size_t	total;

	if (nc_inq_vardimid(ncid, varid, dimids) != NC_NOERR)
	    return NULL;

	for (total = 1, idim = rank - 1; idim >= 0; --idim)
	{
	    size_t	length;

	    cimap[idim] = total;

	    if (nc_inq_dimlen(ncid, dimids[idim], &length) != NC_NOERR)
		return NULL;

	    total *= length;
	}
    }
    else
    {
	/*
	 * Regular Fortran version 2 semantics: convert byte counts to
	 * element counts.
	 */
	int	idim;
	size_t	size;

	switch (datatype)
	{

	    case NC_CHAR:
		size = sizeof(char);
		break;
	    case NC_BYTE:
#		if NF_INT1_IS_C_SIGNED_CHAR
		    size = sizeof(signed char);
#		elif NF_INT1_IS_C_SHORT
		    size = sizeof(short);
#		elif NF_INT1_IS_C_INT
		    size = sizeof(int);
#		elif NF_INT1_IS_C_LONG
		    size = sizeof(long);
#		endif
		break;
	    case NC_SHORT:
#		if NF_INT2_IS_C_SHORT
		    size = sizeof(short);
#		elif NF_INT2_IS_C_INT
		    size = sizeof(int);
#		elif NF_INT2_IS_C_LONG
		    size = sizeof(long);
#		endif
		break;
	    case NC_INT:
#		if NF_INT_IS_C_INT
		    size = sizeof(int);
#		elif NF_INT_IS_C_LONG
		    size = sizeof(long);
#		endif
		break;
	    case NC_FLOAT:
#		if NF_REAL_IS_C_FLOAT
		    size = sizeof(float);
#		elif NF_REAL_IS_C_DOUBLE
		    size = sizeof(double);
#		endif
		break;
	    case NC_DOUBLE:
#		if NF_DOUBLEPRECISION_IS_C_FLOAT
		    size = sizeof(float);
#		elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		    size = sizeof(double);
#		endif
		break;
	    default:
		return NULL;
	}

	for (idim = 0; idim < rank; ++idim)
	    cimap[idim] = fimap[rank - 1 - idim] / size;
    }

    return cimap;
}
Esempio n. 23
0
int
main()
{
    char *vs    = "variable-length string";
    char fsdata[]   = "fixed-length string";
    char *v1ddata[DIM1] = {"strings","of","variable","length"};
    int i;

    printf("\n*** Creating file for checking fix to bugs in accessing strings from HDF5 non-netcdf-4 file.\n");
    {
	hid_t fileid, scalar_spaceid, vstypeid, fstypeid, vsattid, fsattid, vsdsetid, fsdsetid;
	size_t type_size = FSTR_LEN;
	hid_t v1ddsetid;
	hid_t v1dspaceid;
	hsize_t dims[1] = {DIM1};

	if ((scalar_spaceid = H5Screate(H5S_SCALAR)) < 0) ERR;
	if ((v1dspaceid = H5Screate_simple(RANK, dims, NULL)) < 0) ERR;
	
	/* Create variable-length and fixed-length string types. */
	if ((vstypeid =  H5Tcopy(H5T_C_S1)) < 0) ERR;
	if (H5Tset_size(vstypeid, H5T_VARIABLE) < 0) ERR;
	
	if ((fstypeid =  H5Tcopy(H5T_C_S1)) < 0) ERR;
	if (H5Tset_size(fstypeid, type_size) < 0) ERR;

	/* Create new file, using default properties. */
	if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR;
	
	/* Create scalar datasets of variable- and fixed-length strings. */
	if ((vsdsetid = H5Dcreate (fileid, VS_VAR_NAME, vstypeid, scalar_spaceid, 
				   H5P_DEFAULT)) < 0) ERR;
	if (H5Dwrite (vsdsetid, vstypeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &vs)) ERR;
	if ((fsdsetid = H5Dcreate (fileid, FS_VAR_NAME, fstypeid, scalar_spaceid, 
				   H5P_DEFAULT)) < 0) ERR;
	if (H5Dwrite (fsdsetid, fstypeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &fsdata)) ERR;

	/* Create 1D dataset of variable-length strings. */
	if ((v1ddsetid = H5Dcreate (fileid, V1D_VAR_NAME, vstypeid, v1dspaceid, 
				   H5P_DEFAULT)) < 0) ERR;
	if (H5Dwrite (v1ddsetid, vstypeid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &v1ddata)) ERR;
	
	/* Write scalar global attributes of these types. */
	if ((vsattid = H5Acreate(fileid, VS_ATT_NAME, vstypeid, scalar_spaceid, 
				 H5P_DEFAULT)) < 0) ERR;
	if (H5Awrite(vsattid, vstypeid, &vs) < 0) ERR;
	if ((fsattid = H5Acreate(fileid, FS_ATT_NAME, fstypeid, scalar_spaceid, 
				 H5P_DEFAULT)) < 0) ERR;
	if (H5Awrite(fsattid, fstypeid, &fsdata) < 0) ERR;
	
	/* Close up. */
	if (H5Aclose(vsattid) < 0) ERR;
	if (H5Aclose(fsattid) < 0) ERR;
	if (H5Sclose(scalar_spaceid) < 0) ERR;
	if (H5Sclose(v1dspaceid) < 0) ERR;
	if (H5Tclose(vstypeid) < 0) ERR;
	if (H5Tclose(fstypeid) < 0) ERR;
	if (H5Dclose(vsdsetid) < 0) ERR;
	if (H5Dclose(fsdsetid) < 0) ERR;
	if (H5Dclose(v1ddsetid) < 0) ERR;
	if (H5Fclose(fileid) < 0) ERR;
    }

    printf("*** Checking reading variable-length HDF5 string var through netCDF-4 API...");
    {
	int ncid, varid, ndims;
	nc_type type;
	char *data_in;
	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	if (nc_inq_varid(ncid, VS_VAR_NAME, &varid)) ERR;
	if (nc_inq_vartype(ncid, varid, &type)) ERR;
	if (type != NC_STRING) ERR;
	if (nc_inq_varndims(ncid, varid, &ndims )) ERR;
	if (ndims != 0) ERR;
	if (nc_get_var_string(ncid, varid, &data_in)) ERR;
	if (strcmp(vs, data_in)) ERR;
	if (nc_free_string(1, &data_in)) ERR;
	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;

    printf("*** Checking reading fixed-length HDF5 string var through netCDF-4 API...");
    {
    	int ncid, varid, ndims;
    	nc_type type;
    	char *data_in;
    	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
    	if (nc_inq_varid(ncid, FS_VAR_NAME, &varid)) ERR;
    	if (nc_inq_vartype(ncid, varid, &type)) ERR;
    	if (type != NC_STRING) ERR;
    	if (nc_inq_varndims(ncid, varid, &ndims )) ERR;
    	if (ndims != 0) ERR;
    	if (nc_get_var_string(ncid, varid, &data_in)) ERR;
    	if (strcmp(fsdata, data_in)) ERR;
	if (nc_free_string(1, &data_in)) ERR;
    	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;

    printf("*** Checking reading variable-length HDF5 string att through netCDF-4 API...");
    {
	int ncid;
	nc_type type;
	size_t len;
	char *data_in;
	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	if (nc_inq_att(ncid, NC_GLOBAL, VS_ATT_NAME, &type, &len)) ERR;
	if (type != NC_STRING) ERR;
	if (len != 1) ERR;
        if (nc_get_att_string(ncid, NC_GLOBAL, VS_ATT_NAME, &data_in)) ERR;
	if (strcmp(vs, data_in)) ERR;
	if (nc_free_string(1, &data_in)) ERR;
	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;

    printf("*** Checking reading fixed-length HDF5 string att through netCDF-4 API...");
    {
	int ncid;
	nc_type type;
	size_t len;
	char *data_in;
	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	if (nc_inq_att(ncid, NC_GLOBAL, FS_ATT_NAME, &type, &len)) ERR;
	if (type != NC_CHAR) ERR;
	if (len != FSTR_LEN) ERR;
	if (!(data_in = malloc(len))) ERR;
        /* if (nc_get_att_string(ncid, NC_GLOBAL, FS_ATT_NAME, &data_in)) ERR; */
        if (nc_get_att_text(ncid, NC_GLOBAL, FS_ATT_NAME, data_in)) ERR;
	if (strcmp(fsdata, data_in)) ERR;
	free(data_in);
	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;

    printf("*** Checking reading variable-length HDF5 strings var through netCDF-4 API...");
    {
    	int ncid, varid, ndims;
    	nc_type type;
	int *dimids;
	size_t nstrings;
    	char **data_in;
    	if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
    	if (nc_inq_varid(ncid, V1D_VAR_NAME, &varid)) ERR;
    	if (nc_inq_vartype(ncid, varid, &type)) ERR;
    	if (type != NC_STRING) ERR;
    	if (nc_inq_varndims(ncid, varid, &ndims )) ERR;
    	if (ndims != RANK) ERR;
	if (!(dimids = malloc(ndims * sizeof(int)))) ERR;
    	if (nc_inq_vardimid(ncid, varid, dimids)) ERR;
	if (nc_inq_dimlen(ncid, dimids[0], &nstrings)) ERR;
	if (!(data_in = (char **)malloc(nstrings * sizeof(char *)))) ERR;
    	if (nc_get_var_string(ncid, varid, data_in)) ERR;
	for (i = 0; i < nstrings; i++) {
	    if(strcmp(v1ddata[i], data_in[i])) ERR;
	}
    	if (nc_free_string(nstrings, data_in)) ERR;
	free(data_in);
	free(dimids);
    	if (nc_close(ncid)) ERR;
    }
    SUMMARIZE_ERR;
    FINAL_RESULTS;
}
Esempio n. 24
0
/*! \internal */
int cpy_var_def(int in_id,int out_id,int rec_dim_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int rec_dim_id: input input-file record dimension ID
   char *var_nm: input variable name
   int cpy_var_def(): output output-file variable ID
 */
{
  /* Routine to copy the variable metadata from an input netCDF file
   * to an output netCDF file. 
   */

  int status;
  int *dim_in_id;
  int *dim_out_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;

  nc_type var_type;

  /* See if the requested variable is already in the output file. */
  status = nc_inq_varid(out_id, var_nm, &var_out_id);
  if(status == NC_NOERR)
    return var_out_id;

  /* See if the requested variable is in the input file. */
  (void)nc_inq_varid(in_id, var_nm, &var_in_id);

  /* Get the type of the variable and the number of dimensions. */
  (void)nc_inq_vartype (in_id, var_in_id, &var_type);
  (void)nc_inq_varndims(in_id, var_in_id, &nbr_dim);

  /* Recall:
     1. The dimensions must be defined before the variable.
     2. The variable must be defined before the attributes. */

  /* Allocate space to hold the dimension IDs */
  dim_in_id=malloc(nbr_dim*sizeof(int)); 
  dim_out_id=malloc(nbr_dim*sizeof(int));

  /* Get the dimension IDs */
  (void)nc_inq_vardimid(in_id, var_in_id, dim_in_id);

  /* Get the dimension sizes and names */
  for(idx=0;idx<nbr_dim;idx++){
    char dim_nm[NC_MAX_NAME];
    size_t dim_sz;

    (void)nc_inq_dim(in_id, dim_in_id[idx], dim_nm, &dim_sz);

    /* See if the dimension has already been defined */
    status = nc_inq_dimid(out_id, dim_nm, &dim_out_id[idx]);

    /* If the dimension hasn't been defined, copy it */
    if (status != NC_NOERR) {
      if (dim_in_id[idx] != rec_dim_id) {
        (void)nc_def_dim(out_id, dim_nm, dim_sz, &dim_out_id[idx]);
      } else {
        (void)nc_def_dim(out_id, dim_nm, NC_UNLIMITED, &dim_out_id[idx]);
      } 
    } 
  } 

  /* Define the variable in the output file */

  /* If variable is float or double, define it according to the EXODUS
     file's IO_word_size */

  if ((var_type == NC_FLOAT) || (var_type == NC_DOUBLE)) {
    (void)nc_def_var(out_id, var_nm, nc_flt_code(out_id), nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 2);
  } else {
    (void)nc_def_var(out_id, var_nm, var_type,            nbr_dim, dim_out_id, &var_out_id);
    ex_compress_variable(out_id, var_out_id, 1);
  }

  /* Free the space holding the dimension IDs */
  (void)free(dim_in_id);
  (void)free(dim_out_id);

  return var_out_id;
} /* end cpy_var_def() */
Esempio n. 25
0
int Read_NetCDF_METARS_Header( char *filename, irregular_v5dstruct *ir)
{
   int temp, c, i, j, k, t, *times, tnid, status;
   int offset, numuniquetimes;
   int nc_id, numrecsid;
   int id, year, day, hour, minute, second;
   nc_type type;
   size_t sizea, sized, numrecs;
   int ntimes[MAXTIMES], uniquetimes[MAXTIMES];
   char vname[1000];
   char tdim[1000];
   size_t num_cloud_layers;
   int numdims;
   int dimids[10];
   size_t stringsize;
   int cloud_layer_id;
   int latid, lonid, hgtid;

   status = nc_open( filename, NC_NOWRITE, &nc_id);
   if(status != NC_NOERR){
      return -1;
   }

   /****************/
   /* get filename */
   /****************/
   strncpy(ir->filename, filename, 1000);


   /******************/
   /* get file title */
   /******************/
   status = nc_get_att_text(nc_id, NC_GLOBAL, "title", ir->filetitle);
   if(status != NC_NOERR){
      return -1;
   }

   /*************************/
   /* get number of records */
   /*************************/
   status = nc_inq_dimid(nc_id, "recNum", &numrecsid);
   if(status != NC_NOERR){
      return -1;
   }
   status = nc_inq_dimlen(nc_id, numrecsid, &numrecs);
   if(status != NC_NOERR){
      return -1;
   }

   /****************/
   /* get numtimes */
   /****************/   
   for (i = 0; i < MAXTIMES; i++){
      uniquetimes[i] = -1;
   }

   status = nc_inq_varid( nc_id, "time_nominal", &tnid);
   if(status != NC_NOERR){
      return -1;
   }

   times = (int *) malloc(sizeof(int)*numrecs);
   if (!times){
      return -1;
   }

   status = nc_get_var_int( nc_id, tnid, times);
   if(status != NC_NOERR){   
      free(times);
      return -1;   
   }   
   
   numuniquetimes = 1;
   uniquetimes[0] = times[0];
   ntimes[0] = 1;
   for (i = 1; i < numrecs; i++){
      for (j = 0; j < numuniquetimes; j++){
         if (times[i] == uniquetimes[j]){
            ntimes[j]++;

            break;
         }
      }
      if (j == numuniquetimes){
         uniquetimes[j] = times[i];
         ntimes[j] = 1;
         numuniquetimes++;
      }
   }   
   ir->numtimes = numuniquetimes;

   /* bubble sort unique times */
   for (i = 0; i < numuniquetimes; i++){
      for (j = 0; j < numuniquetimes-1-i; j++){
         if (times[j+1] > times[j]){
            temp = uniquetimes[j];
            uniquetimes[j] = uniquetimes[j+1];
            uniquetimes[j+1] = temp;
            temp = ntimes[j];
            ntimes[j] = ntimes[j+1];
            ntimes[j+1] = temp;
         }
      }
   }
   ir->numrecs = 0;
   for (i = 0; i < ir->numtimes; i++){
      if (ntimes[i] > ir->numrecs){
         ir->numrecs = ntimes[i];
      }
   }
   
   /***********************/
   /* get day/time stamps */
   /***********************/         
   for (i=0; i < ir->numtimes; i++){
      t = times[i];
      day = t/86400;
      t -= 86400 * day;
      if (day > 730){
         day  -= 730;
         year  = (4*day)/1461;
         day   = day - (365*year+(year-1)/4);
         year += 72;
      }
      else{
         year  = day / 365;
         day   = day - (365*year);
      }
      hour = t/3600;
      t -= 3600*hour;
      minute = t/60;
      t -= 60*minute;
      second = t;
      ir->timestamp[i] = 10000*hour+100*minute+second;
      ir->daystamp[i] = 1000*year+day;
   }

   /*********************/
   /* get variable info */
   /*********************/
   status = nc_inq_nvars( nc_id, &ir->numvars);
   if(status != NC_NOERR){
      free(times);
      return -1;
   }

   /* check to make sure lat, lon and hgt are there */ 
   /* and subtract 3 from the total number of variables */
   status = nc_inq_varid( nc_id, METAR_LAT, &latid);
   if(status != NC_NOERR){
      free(times);
      return -1;
   }
   status = nc_inq_varid( nc_id, METAR_LON, &lonid);
   if(status != NC_NOERR){
      free(times);
      return -1;
   }
   status = nc_inq_varid( nc_id, METAR_HGT, &hgtid);
   if(status != NC_NOERR){
      free(times);
      return -1;
   }

/* useless!
   for (i = 0; i < numrecs; i++){
      size_t theindex[3];
      theindex[0] = i;
      theindex[1] = 0;
      for (j = 0; j < 4; j++){
         theindex[2] = j;   
         nc_get_var1_text(nc_id, 20, theindex, &tdim[j]);
      }
      tdim[4] = 0;
   }
*/

 
   offset = 0;


   /* get cloud layers */
   status = nc_inq_dimid(nc_id, METAR_CLOUD_LAYERS, &cloud_layer_id);
   if(status != NC_NOERR){
      printf("no cloud_layers dimension\n");
      free(times);
      return -1;
   }
   status = nc_inq_dimlen(nc_id, cloud_layer_id, &num_cloud_layers);
   if(status != NC_NOERR){
      printf("no cloud_layers dimension\n");
      free(times);
      return -1;
   }
   if (num_cloud_layers < 1 ||
       num_cloud_layers > 9){
      printf("number of cloud layers must be between 1..9\n");
      free(times);
      return -1;
   }
    


   for (i = 0; i < ir->numvars; i++){
      k = i - offset;
      status = nc_inq_varname( nc_id, i, vname);
      if(status != NC_NOERR){
         free(times);
         return -1;
      }
      status = nc_inq_vartype( nc_id, i, &type);
      if(status != NC_NOERR){
         free(times);
         return -1;
      }
      if (strncmp(METAR_LAT, vname, strlen(METAR_LAT)) != 0 &&
         strncmp(METAR_LON, vname, strlen(METAR_LON)) != 0 &&
         strncmp(METAR_HGT, vname, strlen(METAR_HGT)) != 0){
         if (strlen(vname) < MAX_VAR_LENGTH){
            strncpy(ir->VarName[k], vname, MAX_VAR_LENGTH);
            status = nc_inq_varndims( nc_id, i, &numdims);
            if(status != NC_NOERR){
               printf("error getting numdims\n");
               free(times);
               return -1;
            }
            status = nc_inq_vardimid( nc_id, i, dimids);
            if(status != NC_NOERR){
               printf("error getting dimids\n");
               free(times);
               return -1;
            }
            if (type == NC_CHAR){
               if (numdims == 3){
                  /* cloud layers so get max num of layers */
                  /* and create vars to correspond to cl layers */ 
                  ir->VarName[k][strlen(ir->VarName[k])] = '0';
                  for (c = 1; c < num_cloud_layers; c++){
                     strncpy(ir->VarName[k+c], vname, MAX_VAR_LENGTH);
                     ir->VarName[k+c][strlen(ir->VarName[k+c])] = c + '0';
                     offset--;
                  }
                  status = nc_inq_dimlen( nc_id, dimids[2], &stringsize);
                  if(status != NC_NOERR){
                     printf("error getting stringsize\n");
                     free(times);
                     return -1;
                  }
                  for (c = 0; c < num_cloud_layers; c++){
                     ir->CharVarLength[k+c] = stringsize+1;
                     ir->VarType[k] = 1;
                  }   
               }
               else if (numdims == 2){
                  status = nc_inq_dimlen( nc_id, dimids[1], &stringsize);
                  if(status != NC_NOERR){
                     printf("error getting stringsize\n");
                     free(times);
                     return -1;
                  }
                  ir->CharVarLength[k] = stringsize+1;
               }
               else{
                  printf("don't know what to do with four dimensional var\n");
                  free(times);
                  return -1;
               }
               ir->VarType[k] = 1;
               ir->CharVarLength[k] = stringsize+1;
            }   
            else{
               if (numdims == 2){
                  if (dimids[1] != cloud_layer_id){
                     printf("error with var second demension\n");
                     free(times);
                     return -1;
                  }
                  ir->VarName[k][strlen(ir->VarName[k])] = '0';
                  for (c = 1; c < num_cloud_layers; c++){
                     strncpy(ir->VarName[k+c], vname, MAX_VAR_LENGTH);
                     ir->VarName[k+c][strlen(ir->VarName[k+c])] = c + '0';
                     offset--;
                     ir->CharVarLength[k+c] = 0;
                     ir->VarType[k+c] = 0;
                  }
               }
               ir->VarType[k] = 0;
               ir->CharVarLength[k+c] = 0;
            }
         }
         else{
            /* don't include this var becuase */
            /* wont be able to access it by its */
            /* full variable name later         */
            offset++;
         }
      }
      else{
         offset++;
      }
   }
   ir->numvars -= offset;

/*    for (c = 0; c < ir->numvars; c++){
      printf("var = %d name = %s\n", c, ir->VarName[c]);
   }
*/

   free(times);

   /*  get bounds */
   ir->NorthBound = 0.0;
   ir->SouthBound = 0.0;
   ir->WestBound =  0.0;
   ir->EastBound =  0.0;
   ir->BottomBound =0.0;
   ir->TopBound =   0.0;
   
   {
      float *latdata, *londata, *hgtdata;
      
      latdata = (float *) malloc(numrecs * sizeof(float));
      if (!latdata){
         printf("couldn't allocate enough memory\n");
         return -1;
      }
      londata = (float *) malloc(numrecs * sizeof(float));
      if (!londata){
         printf("couldn't allocate enough memory\n");
         free(latdata);
         return -1;
      }
      hgtdata = (float *) malloc(numrecs * sizeof(float));
      if (!hgtdata){
         printf("couldn't allocate enough memory\n");
         free(latdata);         
         free(londata);         
         return -1;
      }
      status = nc_get_var_float( nc_id, latid, latdata);
      if(status != NC_NOERR){
         printf("error getting bounds\n");
         free(latdata);
         free(londata);
         free(hgtdata);
         return -1;
      }
      status = nc_get_var_float( nc_id, lonid, londata);
      if(status != NC_NOERR){
         printf("error getting bounds\n");
         free(latdata);         
         free(londata);         
         free(hgtdata);
         return -1;
      }           
      status = nc_get_var_float( nc_id, hgtid, hgtdata);
      if(status != NC_NOERR){
         printf("error getting bounds\n");
         free(latdata);         
         free(londata);         
         free(hgtdata);
         return -1;
      }
      for (i = 0; i < numrecs; i++){
         if (latdata[i] != -99999.0){
            if (latdata[i] > ir->NorthBound){
               ir->NorthBound = latdata[i];
            }
            else if (latdata[i] < ir->SouthBound){
               ir->SouthBound = latdata[i];
            }
         }
      }
      for (i = 0; i < numrecs; i++){
         if (londata[i] != -99999.0){
            if (londata[i] < ir->EastBound){
               ir->EastBound = londata[i];
            }
            else if (londata[i] > ir->WestBound){
               ir->WestBound = londata[i];
            }
         }
      }
      for (i = 0; i < numrecs; i++){
         if (hgtdata[i] != -99999.0){
            if (hgtdata[i] > ir->TopBound){
               ir->TopBound = hgtdata[i];
            }
            else if (hgtdata[i] < ir->BottomBound){
               ir->BottomBound = hgtdata[i];
            }
         }
      }
      printf("n = %f s = %f w = %f e = %f t = %f b = %f\n", ir->NorthBound, ir->SouthBound, ir->WestBound, ir->EastBound, ir->TopBound, ir->BottomBound);
   }






   return 0;
}
Esempio n. 26
0
/*
 * Read a generalized hypercube of numeric values from a netCDF variable of an 
 * open netCDF file.
 */
extern void
c_ncvgtg (
    int			ncid,	/* netCDF ID */
    int			varid,	/* variable ID */
    const size_t*	start,	/* multidimensional index of hypercube corner */
    const size_t*	count,	/* multidimensional hypercube edge lengths */
    const ptrdiff_t*	strides,/* netCDF variable access strides */
    const ptrdiff_t*	imap,	/* memory values access basis vector */
    void*		value,	/* block of data values to be read */
    int*		rcode	/* returned error code */
)
{
    int		status;
    int		rank;
    nc_type	datatype;

    if ((status = nc_inq_vartype(ncid, varid, &datatype)) == 0 &&
	(status = nc_inq_varndims(ncid, varid, &rank)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = NC_ECHAR;
	    break;
	case NC_BYTE:
#	    if NF_INT1_IS_C_SIGNED_CHAR
		status = nc_get_varm_schar(ncid, varid, start, count,
					   strides, imap,
					   (signed char*)value);
#	    elif NF_INT1_IS_C_SHORT
		status = nc_get_varm_short(ncid, varid, start, count,
					   strides, imap,
					   (short*)value);
#	    elif NF_INT1_IS_C_INT
		status = nc_get_varm_int(ncid, varid, start, count,
					   strides, imap,
					   (int*)value);
#	    elif NF_INT1_IS_C_LONG
		status = nc_get_varm_long(ncid, varid, start, count,
					   strides, imap,
					   (long*)value);
#	    endif
	    break;
	case NC_SHORT:
#	    if NF_INT2_IS_C_SHORT
		status = nc_get_varm_short(ncid, varid, start, count,
					   strides, imap,
					   (short*)value);
#	    elif NF_INT2_IS_C_INT
		status = nc_get_varm_int(ncid, varid, start, count,
					   strides, imap,
					   (int*)value);
#	    elif NF_INT2_IS_C_LONG
		status = nc_get_varm_long(ncid, varid, start, count,
					   strides, imap,
					   (long*)value);
#	    endif
	    break;
	case NC_INT:
#	    if NF_INT_IS_C_INT
		status = nc_get_varm_int(ncid, varid, start, count,
					   strides, imap,
					   (int*)value);
#	    elif NF_INT_IS_C_LONG
		status = nc_get_varm_long(ncid, varid, start, count,
					   strides, imap,
					   (long*)value);
#	    endif
	    break;
	case NC_FLOAT:
#	    if NF_REAL_IS_C_FLOAT
		status = nc_get_varm_float(ncid, varid, start, count,
					   strides, imap,
					   (float*)value);
#	    elif NF_REAL_IS_C_DOUBLE
		status = nc_get_varm_double(ncid, varid, start, count,
					   strides, imap,
					   (double*)value);
#	    endif
	    break;
	case NC_DOUBLE:
#	    if NF_DOUBLEPRECISION_IS_C_FLOAT
		status = nc_get_varm_float(ncid, varid, start, count,
					   strides, imap,
					   (float*)value);
#	    elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		status = nc_get_varm_double(ncid, varid, start, count,
					   strides, imap,
					   (double*)value);
#	    endif
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCVGTG", status, "");
	*rcode = ncerr;
    }
}
Esempio n. 27
0
int NC::Init(const char *fname) {
  FILE *F;
  int   jj,rc;
  int   ncid, ndims, dimids[128];
  int   nvars, varids[128], vardim;
  size_t alen, len[128];

  F=fopen(fname,"r");
  if ( !F ) {
    fprintf(stderr, "Bummer: unable to open %s to read. \n", fname);
    return (-1);
  }
  fclose(F);

  /* read the netCDF file  */
  if ( (rc = nc_open(fname, NC_NOWRITE, &ncid)) != NC_NOERR) NETCDF_ERR(rc);

  
  if ( (rc = nc_inq_dimids(ncid, &ndims, dimids,0)) != NC_NOERR) NETCDF_ERR(rc);
#if PRT
  int kk,where;
  printf("dim = %d\n", ndims);
#endif
  for (jj=0; jj<ndims;jj++) { 
    if ( (rc = nc_inq_dimlen(ncid, dimids[jj],&alen)) != NC_NOERR) NETCDF_ERR(rc);
    len[jj] = alen;

#if PRT
    printf("The %d th dimension's length is: %d \n", dimids[jj], (unsigned int)alen);
#endif
  }

  _num_comid = (int)len[0];
  _num_time = (int)len[1];
  
  if ( (rc = nc_inq_varids(ncid, &nvars, varids)) != NC_NOERR) NETCDF_ERR(rc);
#if PRT
  printf("var = %d\n", nvars);
#endif

  _num_vars = nvars;

  for (jj=0; jj<nvars;jj++) {
    if ( (rc = nc_inq_varndims(ncid, varids[jj],&vardim)) != NC_NOERR) NETCDF_ERR(rc);
#if PRT
    printf("%d %d\n", varids[jj], vardim);
#endif
  }

#if PRT
  printf("%d\n", (unsigned int)len[0]);
#endif



  _comids = (int*)malloc( len[0] *sizeof(int) ); //allocate memory for comids
  _runoff = (float*)malloc( len[0]*len[1] * sizeof(float));  //assign memory for runoff



  if (!_comids) return (-1);
  //assign comid to memory
  if ( ( rc = nc_get_var_int(ncid, varids[0], _comids)) != NC_NOERR) NETCDF_ERR(rc);
  
  if ( !_runoff ) return (-1);

  if ( (rc=nc_get_var_float(ncid, varids[1], _runoff)) != NC_NOERR) NETCDF_ERR(rc);

  if (nvars == 3)
  {
    _upstream_hg = (float*)malloc( len[0]*len[1] * sizeof(float));

    if ( (rc=nc_get_var_float(ncid, varids[2], _upstream_hg)) != NC_NOERR) NETCDF_ERR(rc);
  }

  if ( (rc=nc_close(ncid)) != NC_NOERR ) NETCDF_ERR(rc);

//printf("dimensions : %d , %d \n", len[0],len[1]);
//for (int kk = 0; kk<_num_comid; kk++){printf("%i \n", _comids[kk]);}

#if PRT  
  for (kk=0; kk< len[0]; kk++) {
    where = _search_index(_comids[kk]);
    if ( where >= 0 ) {
      printf("%d: ", _comids[kk]);
      for ( jj=0; jj<len[1]; jj++) {
	printf("%g ", _runoff[jj*len[0]+where]); 
      }
      printf("\n");
      
    } else {
      printf("%d not found\n", _comids[kk]);
    }
  }
#endif

#if 0
  *e_comids = comids;
  *e_sgs = bgs;
  *e_ss = ss;
#endif

  return rc;

}