예제 #1
0
파일: harp-netcdf.c 프로젝트: stcorp/harp
static int read_numeric_attribute(int ncid, int varid, const char *name, harp_data_type *data_type, harp_scalar *data)
{
    nc_type netcdf_data_type;
    size_t netcdf_num_elements;
    int result;

    result = nc_inq_att(ncid, varid, name, &netcdf_data_type, &netcdf_num_elements);
    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    if (netcdf_num_elements != 1)
    {
        harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid format", name);
        return -1;
    }

    if (get_harp_type(netcdf_data_type, data_type) != 0)
    {
        harp_add_error_message(" (attribute '%s')", name);
        return -1;
    }

    switch (netcdf_data_type)
    {
        case NC_BYTE:
            result = nc_get_att_schar(ncid, varid, name, &data->int8_data);
            break;
        case NC_SHORT:
            result = nc_get_att_short(ncid, varid, name, &data->int16_data);
            break;
        case NC_INT:
            result = nc_get_att_int(ncid, varid, name, &data->int32_data);
            break;
        case NC_FLOAT:
            result = nc_get_att_float(ncid, varid, name, &data->float_data);
            break;
        case NC_DOUBLE:
            result = nc_get_att_double(ncid, varid, name, &data->double_data);
            break;
        default:
            harp_set_error(HARP_ERROR_IMPORT, "attribute '%s' has invalid type", name);
            return -1;
    }

    if (result != NC_NOERR)
    {
        harp_set_error(HARP_ERROR_NETCDF, "%s", nc_strerror(result));
        return -1;
    }

    return 0;
}
예제 #2
0
파일: netcdf.cpp 프로젝트: mmase/wgrib2
NcValues* NcAtt::values( void ) const
{
    NcValues* valp = get_space();
    int status;
    switch (type()) {
    case ncFloat:
	status = NcError::set_err(
				  nc_get_att_float(the_file->id(), the_variable->id(), the_name,
				   (float *)valp->base())
				  );
	break;
    case ncDouble:
	status = NcError::set_err(
				  nc_get_att_double(the_file->id(), the_variable->id(), the_name,
				   (double *)valp->base())
				  );
	break;
    case ncInt:
	status = NcError::set_err(
				  nc_get_att_int(the_file->id(), the_variable->id(), the_name,
				(int *)valp->base())
				  );
	break;
    case ncShort:
	status = NcError::set_err(
				  nc_get_att_short(the_file->id(), the_variable->id(), the_name,
				  (short *)valp->base())
				  );
	break;
    case ncByte:
	status = NcError::set_err(
				  nc_get_att_schar(the_file->id(), the_variable->id(), the_name,
				  (signed char *)valp->base())
				  );
	break;
    case ncChar:
	status = NcError::set_err(
				  nc_get_att_text(the_file->id(), the_variable->id(), the_name,
				  (char *)valp->base())
				  );
	break;
    case ncNoType:
    default:
	return 0;
    }
    if (status != NC_NOERR) {
	delete valp;
	return 0;
    }
    return valp;
}
예제 #3
0
static void
pr_att(
    int ncid,
    int varid,
    const char *varname,
    int ia
    )
{
    struct ncatt att;		/* attribute */
	    
    NC_CHECK( nc_inq_attname(ncid, varid, ia, att.name) );

    Printf ("\t\t%s:%s = ", varname, att.name);

    NC_CHECK( nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );

    if (att.len == 0) {	/* show 0-length attributes as empty strings */
	att.type = NC_CHAR;
	att.len = 1;
    }
    switch (att.type) {
    case NC_CHAR:
	att.string = (char *) malloc(att.len);
	if (!att.string) {
	    error("Out of memory!");
	    NC_CHECK( nc_close(ncid) );
	    return;
	}
	NC_CHECK( nc_get_att_text(ncid, varid, att.name, att.string ) );
	pr_att_string(att.len, att.string);
	free(att.string);
	break;
    default:
	att.vals = (double *) malloc(att.len * sizeof(double));
	if (!att.vals) {
	    error("Out of memory!");
	    NC_CHECK( nc_close(ncid) );
	    return;
	}
	NC_CHECK( nc_get_att_double(ncid, varid, att.name, att.vals ) );
	pr_att_vals(att.type, att.len, att.vals);
	free(att.vals);
	break;
    }
    Printf (" ;\n");
}
예제 #4
0
파일: mpp_io.c 프로젝트: djibi2/AM3
/*******************************************************************
 void mpp_get_var_att_double(int fid, int vid, const char *name, double *val)
 get the attribute value of vid from file fid.
 ******************************************************************/
void mpp_get_var_att_double(int fid, int vid, const char *name, double *val)
{
  int status;
  char errmsg[512];
  nc_type type;
  short sval;
  int   ival;
  
  if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_var_att): invalid fid number, fid should be "
				    "a nonnegative integer that less than nfiles");
  if(vid<0 || vid >=files[fid].nvar) mpp_error("mpp_io(mpp_get_var_att): invalid vid number, vid should be "
				    "a nonnegative integer that less than nvar");

  status = nc_inq_atttype(files[fid].ncid, files[fid].var[vid].fldid, name, &type);
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_var_att): Error in getting type of attribute %s of field %s in file %s ",
	    name, files[fid].var[vid].name, files[fid].name );
    netcdf_error(errmsg, status);
  }
  
  switch(type) {
  case NC_DOUBLE:case NC_FLOAT:
    status = nc_get_att_double(files[fid].ncid, files[fid].var[vid].fldid, name, val);
    break;
  case NC_INT:
    status = nc_get_att_int(files[fid].ncid, files[fid].var[vid].fldid, name, &ival);
    *val = ival;
    break;      
  case NC_SHORT:
    status = nc_get_att_short(files[fid].ncid, files[fid].var[vid].fldid, name, &sval);
    *val = sval;
    break;
  default:
    sprintf(errmsg, "mpp_io(mpp_get_var_att): attribute %s of field %s in file %s has an invalid type, "
	    "the type should be NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT or NC_CHAR",
	    name, files[fid].var[vid].name, files[fid].name );
    mpp_error(errmsg);
  }
  
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_var_att): Error in getting value of attribute %s of variable %s from file %s",
	    name, files[fid].var[vid].name, files[fid].name );
    netcdf_error(errmsg, status);
  }
}
예제 #5
0
파일: mpp_io.c 프로젝트: djibi2/AM3
/*******************************************************************
 void mpp_get_global_att(int fid, const char *name, void *val)
 get the global attribute from file fid.
 ******************************************************************/
void mpp_get_global_att(int fid, const char *name, void *val)
{
  int status;
  char errmsg[512];
  nc_type type;
  
  if(fid<0 || fid >=nfiles) mpp_error("mpp_io(mpp_get_global_att): invalid fid number, fid should be "
				    "a nonnegative integer that less than nfiles");
  status = nc_inq_atttype(files[fid].ncid, NC_GLOBAL, name, &type);
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_global_att): Error in getting type of global attribute %s in file %s ",
	    name, files[fid].name );
    netcdf_error(errmsg, status);
  }
  
  switch(type) {
  case NC_DOUBLE:case NC_FLOAT:
    status = nc_get_att_double(files[fid].ncid, NC_GLOBAL, name, val);
    break;
  case NC_INT:
    status = nc_get_att_int(files[fid].ncid, NC_GLOBAL, name, val);
    break;
  case NC_SHORT:
    status = nc_get_att_short(files[fid].ncid, NC_GLOBAL, name, val);
    break;  
  case NC_CHAR:
    status = nc_get_att_text(files[fid].ncid, NC_GLOBAL, name, val);
    break;  
  default:
    sprintf(errmsg, "mpp_io(mpp_get_global_att): global attribute %s in file %s has an invalid type, "
	    "the type should be NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT or NC_CHAR", name, files[fid].name );
    mpp_error(errmsg);
  }
  
  if(status != NC_NOERR) {
    sprintf(errmsg, "mpp_io(mpp_get_global_att): Error in getting value of global attribute %s from file %s",
	    name, files[fid].name );
    netcdf_error(errmsg, status);
  }

}
float *
avtNETCDFReaderBase::ReadTimeAttribute()
{
    float *times_array = 0;

    //
    // See if the global attribute time exists. If it does and is
    // either a float or double, then return the first value of it
    // as the time array.
    //
    int     status;
    nc_type atttype;
    size_t  attsize;
    if((status = nc_inq_att(fileObject->GetFileHandle(), NC_GLOBAL,
        "Time", &atttype, &attsize)) == NC_NOERR)
    {
        if (atttype == NC_FLOAT)
        {
            times_array = new float[1];
            float *value = new float[attsize];
            nc_get_att_float(fileObject->GetFileHandle(), NC_GLOBAL,
                "Time", value); 
            times_array[0] = value[0];
            delete [] value;
        }
        else if (atttype == NC_DOUBLE)
        {
            times_array = new float[1];
            double *value = new double[attsize];
            nc_get_att_double(fileObject->GetFileHandle(), NC_GLOBAL,
                "Time", value); 
            times_array[0] = value[0];
            delete [] value;
        }
    }

    return times_array;
}
예제 #7
0
파일: NCtable.c 프로젝트: amiara/RGIS
NCtable_t *NCtableOpen(int ncid, char *tablename)
{
	int status, *dimids, dimid, i = 0, j = 0;
	int ndims, nvars;
	size_t nrecords;
	size_t len;
	char varname [NC_MAX_NAME];
	nc_type type;
	NCfield_t *field = (NCfield_t *) NULL;
	NCtable_t *tbl   = (NCtable_t *) NULL;

	if((status = nc_inq_dimid  (ncid,tablename,&dimid)) != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if((status = nc_inq_dimlen (ncid,dimid,&nrecords))  != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if((status = nc_inq_nvars  (ncid,&nvars))           != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if(nc_inq_ndims(ncid,&ndims) != NC_NOERR)
	{ NCprintNCError (status,"NCtableOpen"); return ((NCtable_t *) NULL); }
	if ((dimids = (int *) malloc(sizeof(int) * ndims)) == (int *) NULL)
	{ CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); return (NCtable_t *) NULL; }

	if ((tbl = (NCtable_t *) malloc(sizeof(NCtable_t))) == (NCtable_t *) NULL)
	{ CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); free (dimids); return ((NCtable_t *) NULL); }
	if ((tbl->Name = (char *) malloc (strlen(tablename) + 1)) == (char *) NULL)
	{ CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); free (dimids); free (tbl); return ((NCtable_t *) NULL); }
	strcpy(tbl->Name,tablename);
	tbl->NFields  = 0;
	tbl->Fields   = (NCfield_t *) NULL;

	for(i = 0; i < nvars; i++)
	{
		if ((status = nc_inq_vartype(ncid,i,&type)) != NC_NOERR)
		{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
		if ((len = _NCtableVarLen(ncid,i,dimid,dimids)) == NCfailed) continue;
		if ((type != NC_CHAR) && (len > 1)) continue;

		if((status = nc_inq_varname(ncid,i,varname)) != NC_NOERR)
		{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }

		if ((tbl->Fields = (NCfield_t *) realloc (tbl->Fields, sizeof (NCfield_t) * (tbl->NFields + 1))) == (NCfield_t *) NULL)
		{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
		field = tbl->Fields + tbl->NFields;
		tbl->NFields += 1;
		field->NRecords = nrecords;
		field->Data = (void *) NULL;
		field->Name = (char *) NULL;
		field->Type = type;
		field->Len  = len;

		if ((field->Name = malloc (strlen (varname) + 1)) == (char *) NULL)
		{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
		strcpy (field->Name,varname);

		if (nc_get_att_double (ncid,i,NCnameVAScaleFactor,&field->Scale)      != NC_NOERR) field->Scale      = 1.0;
		if (nc_get_att_double (ncid,i,NCnameVAAddOffset,  &field->Offset)     != NC_NOERR) field->Offset     = 0.0;

		switch(field->Type)
		{
			case NC_CHAR:
				if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (char)))   == (void *) NULL)
				{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if((status = nc_get_var_text(ncid,i,(char *) (field->Data))) != NC_NOERR)
				{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				break;
			case NC_BYTE:
			case NC_SHORT:
			case NC_INT:
				if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (int)))   == (void *) NULL)
				{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if((status = nc_get_var_int(ncid,i,(int *) (field->Data))) != NC_NOERR)
				{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if (nc_get_att_int    (ncid,i,NCnameVAFillValue,  &field->FillValue.Int)  != NC_NOERR) field->FillValue.Int  = INT_NOVALUE;
				if (nc_get_att_double (ncid,i,NCnameVAMissingVal, &field->MissingVal)     != NC_NOERR) field->MissingVal     = FLOAT_NOVALUE;
				break;
			case NC_FLOAT:
			case NC_DOUBLE:
				if ((field->Data = (void *) malloc(field->NRecords * field->Len * sizeof (double))) == (void *) NULL)
				{ CMmsgPrint (CMmsgSysError, "Error allocating memory in: %s %d",__FILE__,__LINE__); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if((status = nc_get_var_double(ncid,i,(double *) (field->Data))) != NC_NOERR)
				{ NCprintNCError (status,"NCtableOpen"); free (dimids); NCtableClose (tbl); return ((NCtable_t *) NULL); }
				if (nc_get_att_double (ncid,i,NCnameVAFillValue,  &field->FillValue.Float)  != NC_NOERR) field->FillValue.Float = FLOAT_NOVALUE;
				if (nc_get_att_double (ncid,i,NCnameVAMissingVal, &field->MissingVal)       != NC_NOERR) field->MissingVal      = FLOAT_NOVALUE;
				break;
			default:        field->Data = (void *) NULL; break;
		}
		if(GetDebug()) CMmsgPrint (CMmsgUsrError, "Loaded: %s(dimid: %d)\n",field->Name,dimid);
	}

	if(GetDebug())
	{
		CMmsgPrint (CMmsgUsrError, "Dim: %d Name: %s Cols: %d Rows: %d\n",dimid,tbl->Name,tbl->NFields,field->NRecords);
		for(i = 0; i < tbl->NFields; i++)
		{
			field = tbl->Fields + i;
			CMmsgPrint (CMmsgUsrError, "\tField: %d Name: %s ",i,field->Name);
			switch(field->Type)
			{
				case NC_CHAR:
					if(field->Len == 1)
					{
						CMmsgPrint (CMmsgUsrError, "Type: char\n");
						for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %c\n",j,((char *) (field->Data)) [j]);
					}
					else
					{
						CMmsgPrint (CMmsgUsrError, "Type: string\n");
						for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %s\n",j,((char *) (field->Data)) + j * field->Len);
					}
					break;
				case NC_BYTE:
				case NC_SHORT:
				case NC_INT:
					CMmsgPrint (CMmsgUsrError, "Type: int\n");
					for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %i\n",j,((int *)    (field->Data)) [j]);
					break;
				case NC_FLOAT:
				case NC_DOUBLE:
					CMmsgPrint (CMmsgUsrError, "Type: double\n");
					for(j = 0; j < 5; j++) CMmsgPrint (CMmsgUsrError, "\t\t%d %f\n",j,((double *) (field->Data)) [j]);
					break;
				default: break;
			}
		}
	}
	return (tbl);
}
예제 #8
0
/*
 * Get the value of a netCDF attribute given its variable ID and name.
 */
static void
c_ncagt(
    int		ncid,		/* netCDF ID */
    int		varid,		/* variable ID */
    const char*	attname,	/* attribute name */
    void*	value,		/* pointer to data values */
    int*	rcode		/* returned error code */
)
{
    int		status;
    nc_type	datatype;

    if ((status = nc_inq_atttype(ncid, varid, attname, &datatype)) == 0)
    {
	switch (datatype)
	{
	case NC_CHAR:
	    status = NC_ECHAR;
	    break;
	case NC_BYTE:
#    	if NF_INT1_IS_C_SIGNED_CHAR
		status = nc_get_att_schar(ncid, varid, attname, 
					   (signed char*)value);
#    	elif NF_INT1_IS_C_SHORT
		status = nc_get_att_short(ncid, varid, attname, 
					   (short*)value);
#    	elif NF_INT1_IS_C_INT
		status = nc_get_att_int(ncid, varid, attname, 
					   (int*)value);
#    	elif NF_INT1_IS_C_LONG
		status = nc_get_att_long(ncid, varid, attname, 
					   (long*)value);
#    	endif
	    break;
	case NC_SHORT:
#    	if NF_INT2_IS_C_SHORT
		status = nc_get_att_short(ncid, varid, attname, 
					   (short*)value);
#    	elif NF_INT2_IS_C_INT
		status = nc_get_att_int(ncid, varid, attname, 
					   (int*)value);
#    	elif NF_INT2_IS_C_LONG
		status = nc_get_att_long(ncid, varid, attname, 
					   (long*)value);
#    	endif
	    break;
	case NC_INT:
#	    if NF_INT_IS_C_INT
		status = nc_get_att_int(ncid, varid, attname, 
					   (int*)value);
#	    elif NF_INT_IS_C_LONG
		status = nc_get_att_long(ncid, varid, attname, 
					   (long*)value);
#	    endif
	    break;
	case NC_FLOAT:
#    	if NF_REAL_IS_C_FLOAT
		status = nc_get_att_float(ncid, varid, attname, 
					   (float*)value);
#    	elif NF_REAL_IS_C_DOUBLE
		status = nc_get_att_double(ncid, varid, attname, 
					   (double*)value);
#    	endif
	    break;
	case NC_DOUBLE:
#    	if NF_DOUBLEPRECISION_IS_C_FLOAT
		status = nc_get_att_float(ncid, varid, attname, 
					   (float*)value);
#    	elif NF_DOUBLEPRECISION_IS_C_DOUBLE
		status = nc_get_att_double(ncid, varid, attname, 
					   (double*)value);
#    	endif
	    break;
	}
    }

    if (status == 0)
	*rcode = 0;
    else
    {
	nc_advise("NCAGT", status, "");
	*rcode = ncerr;
    }
}
예제 #9
0
void write_output(char out_file[], char in_file[][FILE_NAME_SZ], char depth_file[],
     size_t nz, char var_names[MAX_VARS][NC_MAX_NAME], char time_names[2][NC_MAX_NAME], 
     char depth_names[2][NC_MAX_NAME], int *num_var,
     char arglist[]) {
  int i, j, v;
  int ncid, nc_den_id, status, ndims, ndim, nvariables, ngatt, recdim;
  int use_dim[NC_MAX_DIMS];
  int dv_id[NC_MAX_DIMS], dim2id[NC_MAX_DIMS], dim2vid[NC_MAX_DIMS];
  int dimids[NC_MAX_VAR_DIMS], dd2id[2];
  int ddvid[2], dd2vid[2];
  int num_att;
  int use_file[MAX_FILES], max_file;
  char dim_name[10][NC_MAX_NAME];
  char att_name[NC_MAX_NAME];
  nc_type xtype;

  size_t dim_len[NC_MAX_DIMS], ddim_len[2], max_dim_len = 0;
    
  status = nc_open(in_file[0],NC_NOWRITE, &ncid);
  if (status != NC_NOERR) handle_error(status,in_file[0],status);
  ncInid[0] = ncid; use_file[0] = 1;

  status = nc_inq(ncid,&ndims,&nvariables,&ngatt,&recdim);
  if (status != NC_NOERR) handle_error(status,in_file[0],status);
  strcpy(master_in_file,in_file[0]);

  for (i=1;i<MAX_FILES;i++) { ncInid[i] = -1; use_file[i] = 0;}
  for (i=0;i<MAX_FILES;i++) if (strlen(in_file[i]) == 0) break;
  max_file = i;

/* Determine which dimensions need to be created. */
  for (i=0;i<ndims;i++) use_dim[i] = 0.0;
  for (v=0;v<*num_var;v++) {
    int vin_id, fn = 0, id;
    for (fn=0;fn<max_file;fn++) {
      if (ncInid[fn] < 0) {
        status = nc_open(in_file[fn],NC_NOWRITE, &ncInid[fn]);
        if (status != NC_NOERR) handle_error(status,in_file[fn],status);
      }
      status = nc_inq_varid(ncInid[fn], var_names[v], &vin_id);
      if (status == NC_NOERR) break;
    }
    if (fn==max_file) {
      printf("ERROR: Unable to find variable %s in any of %d files.\n",var_names[v],max_file);
      handle_error(status, var_names[v], v);
    }
    id = ncInid[fn];
    status = nc_inq_var(id, vin_id, att_name, &xtype, &ndim, dimids, &num_att);
    if (status != NC_NOERR) handle_error(status, var_names[v], v);

    if (ndim < 2) printf("Variable %s has only 2 dimensions and will be excluded.\n", var_names[v]);
    else {
      use_dim[find_dimid(id,dimids[ndim-1],ncid)] = 1;
      use_dim[find_dimid(id,dimids[ndim-2],ncid)] = 1;
      if (ndim > 4) {
        printf("ERROR: Variable %s has %d dimensions. This program only works with up to 4 dimensions.\n",
                var_names[v],ndim);
        exit(-1);
      }
      if (ndim == 4) {
        int frecdim; status = nc_inq_unlimdim(id,&frecdim);
        if (status != NC_NOERR) handle_error(status,"Finding record dimid",status);
        if (dimids[0] = frecdim) use_dim[recdim] = 1;
        else {
          printf("ERROR: Variable %s has 4 non-record dimensions. This program only works with 3 such dimensions.\n",
                  var_names[v]);
          exit(-1);
        }
      }
      
      var_file[v] = fn;
      use_file[fn] = 1;
    }
  }

  // Close any unneeded files.
  for (i=1;i<max_file;i++) if ((use_file[i] == 0) && (ncInid[i] >= 0)) {
    nc_close(ncInid[i]); ncInid[i] = -1;
  }
  
  status = nc_create(out_file, 0, &ncOutid);
  if (status != NC_NOERR) handle_error(status,out_file,status);
  status = nc_set_fill(ncOutid,NC_NOFILL,&j);
  if (status != NC_NOERR) handle_error(status,out_file,status);

  // printf("Created file %s with id %d.\n",out_file,ncOutid);
    
  // Copy all of the global attributes over.
  for (j=0;j<ngatt;j++) {
    status = nc_inq_attname (ncid, NC_GLOBAL, j, att_name);
    if (status != NC_NOERR) handle_error(status,"Global",j);    
    status = nc_copy_att(ncid, NC_GLOBAL, att_name, ncOutid, NC_GLOBAL);
    if (status != NC_NOERR) handle_error(status,att_name,j);
  }
  {
    char hist[1000];
    status = nc_get_att_text(ncid, NC_GLOBAL,"history",hist);
    if (status == NC_NOERR) {strcat(hist,"\n"); strcat(hist,arglist);}
    else strcpy(hist,arglist);
    status = nc_put_att_text(ncOutid, NC_GLOBAL,"history",strlen(hist),hist);
  }
  
  // Copy all appropriate dimensions over.
  for (i=0;i<ndims;i++) if (use_dim[i]) {
    status = nc_inq_dim(ncid, i, dim_name[i], &dim_len[i]);
    if (status != NC_NOERR) handle_error(status, "", i);
    if (dim_len[i] > max_dim_len) max_dim_len = dim_len[i];

    if (i==recdim)
      status = nc_def_dim(ncOutid, dim_name[i], NC_UNLIMITED, &dim2id[i]);
    else
      status = nc_def_dim(ncOutid, dim_name[i], dim_len[i], &dim2id[i]);
    if (status != NC_NOERR) handle_error(status,dim_name[i],i);

    // Get information about the coordinate variable.
    status = nc_inq_varid (ncid, dim_name[i], &dv_id[i]);
    if (status != NC_NOERR) handle_error(status, dim_name[i], i);
    status = nc_inq_vartype(ncid, dv_id[i], &xtype);
    if (status != NC_NOERR) handle_error(status, dim_name[i], i);
    status = nc_inq_varnatts(ncid, dv_id[i], &num_att);
    if (status != NC_NOERR) handle_error(status,dim_name[i],i);

    // Create the coordinate variables.
    status = nc_def_var (ncOutid, dim_name[i], xtype, 1, &dim2id[i], &dim2vid[i]);
    if (status != NC_NOERR) handle_error(status, dim_name[i],i);    
    // Copy all of the attributes over.
    for (j=0;j<num_att;j++) {
      status = nc_inq_attname (ncid, dv_id[i], j, att_name);
      if (status != NC_NOERR) handle_error(status,att_name,j);
      status = nc_copy_att(ncid, dv_id[i], att_name, ncOutid, dim2vid[i]);
      if (status != NC_NOERR) handle_error(status,att_name,j);
    }
  }
  
  // Copy the vertical dimensions over from depth_file.
  //    if (strlen(depth_file) > 1)
  status = nc_open(depth_file,NC_NOWRITE, &nc_den_id);
  if (status != NC_NOERR) handle_error(status,depth_file,status);

  for (i=0;i<2;i++) {
    int ddid;
    status = nc_inq_dimid (nc_den_id, depth_names[i], &ddid);
    if (status != NC_NOERR) handle_error(status,depth_names[i],0);
    status = nc_inq_dimlen(nc_den_id, ddid, &ddim_len[i]);
    if (status != NC_NOERR) handle_error(status,depth_names[i], i);

    status = nc_def_dim(ncOutid, depth_names[i], ddim_len[i], &dd2id[i]);
    if (status != NC_NOERR) handle_error(status,depth_names[i],i);

    // Get information about the coordinate variable.
    status = nc_inq_varid (nc_den_id, depth_names[i], &ddvid[i]);
    if (status != NC_NOERR) handle_error(status, depth_names[i], i);
    status = nc_inq_vartype(nc_den_id, ddvid[i], &xtype);
    if (status != NC_NOERR) handle_error(status, depth_names[i], i);
    status = nc_inq_varnatts(nc_den_id, ddvid[i], &num_att);
    if (status != NC_NOERR) handle_error(status,depth_names[i],i);

    // Create the coordinate variables.
    status = nc_def_var (ncOutid, depth_names[i], xtype, 1, &dd2id[i], &dd2vid[i]);
    if (status != NC_NOERR) handle_error(status, depth_names[i],i);    
    // Copy all of the attributes over.
    for (j=0;j<num_att;j++) {
      status = nc_inq_attname (nc_den_id, ddvid[i], j, att_name);
      if (status != NC_NOERR) handle_error(status,att_name,j);
      status = nc_copy_att(nc_den_id, ddvid[i], att_name, ncOutid, dd2vid[i]);
      if (status != NC_NOERR) handle_error(status,att_name,j);
    }
  }


  // Create the auxiliary time variable (if it exists) and store the time indices.
  if (recdim != -1) {
    // If there is a record dimension, it must be one of the two named
    // time dimensions.  If none are named, the name of the record
    // dimension is copied into it.
    if ((strcmp(dim_name[recdim],time_names[0]) != 0) &&
        (strcmp(dim_name[recdim],time_names[1]) != 0)) {
      if (strlen(time_names[0]) == 0) strcpy(time_names[0],dim_name[recdim]);
      else if (strlen(time_names[1]) == 0) strcpy(time_names[1],dim_name[recdim]);
      else {
        printf("ERROR: The specified time variables %s and %s do not agree\n"
               "\twith the record variable, %s.\n",time_names[0],time_names[1],
               dim_name[recdim]);
        exit(-1);
      }
    }
  }
  for (v=0;v<2;v++) {
    status = nc_inq_varid(ncOutid, time_names[v], &time_out_id[v]);
    if (status != NC_NOERR) {
      if (strlen(time_names[v]) > 0)  {
        int out_dim;
        status = nc_inq_varid(ncid, time_names[v], &time_in_id[v]);
        if (status != NC_NOERR) handle_error(status, time_names[v], v);
        status = nc_inq_var(ncid, time_in_id[v], att_name, &xtype, &ndim,
                            dimids, &num_att);
        if (status != NC_NOERR) handle_error(status, time_names[v], v);
        if (ndim > 1) {
          printf("ERROR: Time variable %s has %d dimensions in %s.\n",time_names[v],ndim,in_file[0]);
          exit(-1);
        }
        out_dim = dim2id[dimids[0]];

        status = nc_def_var(ncOutid, time_names[v], xtype, ndim, &out_dim, &time_out_id[v]);
        if (status != NC_NOERR) handle_error(status, time_names[v],v);
        // Copy all of the attributes over.
        for (j=0;j<num_att;j++) {
          status = nc_inq_attname(ncid, time_in_id[v], j, att_name);
          if (status != NC_NOERR) handle_error(status,att_name,j);
          status = nc_copy_att(ncid, time_in_id[v], att_name, ncOutid, time_out_id[v]);
          if (status != NC_NOERR) handle_error(status,att_name,j);
        }
      }
    } else {
      status = nc_inq_varid(ncid, time_names[v], &time_in_id[v]);
      if (status != NC_NOERR) handle_error(status, time_names[v], v);
    }
  }

  // Create the output variables, while checking the validity of the list.
  for (v=0;v<*num_var;v++) {
    int id, vin_id, frecdim, valid = 1;
    for (i=0;i<2;i++) if (strcmp(var_names[v],time_names[i])==0) valid = 0;
    for (i=0;i<ndims;i++) if (strcmp(var_names[v],dim_name[i])==0) valid = 0;
    for (i=0;i<2;i++) if (strcmp(var_names[v],depth_names[i])==0) valid = 0;
    
    if (valid) {
      id = ncInid[var_file[v]];
      
      if (var_file[v] == 0) frecdim = recdim;
      else {
        status = nc_inq_unlimdim(id,&frecdim);
        if (status != NC_NOERR) handle_error(status,"Finding record dimid",status);
      }

      status = nc_inq_varid(id, var_names[v], &vin_id);
      if (status != NC_NOERR) handle_error(status, var_names[v], v);
      status = nc_inq_var(id, vin_id, att_name, &xtype, &ndim,
                          dimids, &num_att);
      if (status != NC_NOERR) handle_error(status, var_names[v], v);

      if (ndim <= 2) {
        printf("Variable %s has only 2 dimensions and will be excluded.\n", var_names[v]);
        valid = 0;
      } else if ((ndim == 3) && (dimids[0] == frecdim)) {
        printf("Variable %s uses the record dimension as 3rd dimension and will be excluded.\n", var_names[v]);
        valid = 0;
      }
    }

    if (valid) {
      // Get information about the variable.
      int out_dimids[4];
      if (dimids[0] != frecdim) {
        out_dimids[0] = dd2id[0]; var_count[v][0] = ddim_len[0];
        static_var[v] = 1; i = 1;
      } else {
        out_dimids[0] = dim2id[recdim]; out_dimids[1] = dd2id[0];
        var_count[v][0] = 1; var_count[v][1] = ddim_len[0];
        static_var[v] = 0; i = 2;
      }
      var_size[v] = ddim_len[0];
      for (;i<ndim;i++) {
        int did;
        did = find_dimid(id,dimids[i],ncid);
        out_dimids[i] = dim2id[did];
        var_count[v][i] = dim_len[did];
        var_size[v] *= var_count[v][i];
      }

      status = nc_def_var(ncOutid, var_names[v], xtype, ndim, out_dimids, &var_id[v]);
      if (status != NC_NOERR) handle_error(status, var_names[v],v);
      // Copy all of the attributes over.
      for (j=0;j<num_att;j++) {
        status = nc_inq_attname(id, vin_id, j, att_name);
        if (status != NC_NOERR) handle_error(status,att_name,j);
        status = nc_copy_att(id, vin_id, att_name, ncOutid, var_id[v]);
        if (status != NC_NOERR) handle_error(status,att_name,j);
      }
      status = nc_get_att_double(id, vin_id,"missing_value",&missing_val[v]);
      if (status != NC_NOERR) {
        missing_val[v] = -1.0e34;
        status = nc_put_att_double(ncOutid,var_id[v],"missing_value",xtype,1,&missing_val[v]);
        if (status != NC_NOERR) handle_error(status,"missing_value",v);
      }
    } else {
      for (i=v;i<*num_var-1;i++) strcpy(var_names[i],var_names[i+1]);
      (*num_var)--; v--;
    }
  }

  status = nc_enddef(ncOutid);
  if (status != NC_NOERR) handle_error(status,out_file,status);
  // printf("Finished define mode for %s.\n",out_file);
    
    
    
    
/*
    // Create the vertical coordinates. //
    status = nc_def_dim(ncOutid, zc_name, nz, &layerid);
    if (status != NC_NOERR) handle_error(status,zc_name,0);
    status = nc_def_var (ncOutid, zc_name, NC_DOUBLE, 1, &layerid, &layervid);
    if (status != NC_NOERR) handle_error(status,zc_name,0);

    status = nc_def_dim(ncOutid, ze_name, (size_t) (nz+1), &intid);
    if (status != NC_NOERR) handle_error(status,ze_name,0);
    status = nc_def_var (ncOutid, ze_name, NC_DOUBLE, 1, &intid, &intvid);
    if (status != NC_NOERR) handle_error(status,ze_name,0);
    status = nc_put_att_text(ncOutid, intvid, "units", 2, "m");
    if (status != NC_NOERR) handle_error(status,"Units Interface",0);

    dims[0] = layervid;
    {
      strcpy(att[0][0],"long_name"); strcpy(att[0][1],"Depth of Layer Center");
//      strcpy(att[1][0],"units"); strcpy(att[1][1],"m");
      strcpy(att[1][0],"units"); strcpy(att[1][1],"cm");
      strcpy(att[2][0],"positive"); strcpy(att[2][1],"down");
      strcpy(att[3][0],"edges"); strcpy(att[2][1],ze_name);
      for (j=0;j<=2;j++) {
        status = nc_put_att_text(ncOutid, layervid, att[j][0],
            strlen(att[j][1]), att[j][1]);
        if (status != NC_NOERR) handle_error(status,att[j][0],j);
      }
    
      strcpy(att[0][0],"long_name"); strcpy(att[0][1],"Depth of edges");
//      strcpy(att[1][0],"units"); strcpy(att[1][1],"m");
      strcpy(att[1][0],"units"); strcpy(att[1][1],"cm");
      strcpy(att[2][0],"positive"); strcpy(att[2][1],"down");
      for (j=0;j<=2;j++) {
        status = nc_put_att_text(ncOutid, intvid, att[j][0],
            strlen(att[j][1]), att[j][1]);
        if (status != NC_NOERR) handle_error(status,att[j][0],j);    
      }
    }
*/
     
    // Copy the axis values from the first file.
  {
    double *coord_array;
    coord_array = malloc(sizeof(double)*(max_dim_len));
    for (i=0;i<ndims;i++) if (use_dim[i] && (i!=recdim)) {
      status = nc_get_var_double(ncid,dv_id[i],coord_array);
      if (status != NC_NOERR) handle_error(status,"Read Coordinate Variable",i);
      
      status = nc_put_var_double(ncOutid,dim2vid[i],coord_array);
      if (status != NC_NOERR) handle_error(status,"Write Coordinate Variable",i);
    }
    
    // Copy the vertical axis values from the depth file.
    for (i=0;i<2;i++) {
      status = nc_get_var_double(nc_den_id,ddvid[i],coord_array);
      if (status != NC_NOERR) handle_error(status,"Read Coordinate Variable",i);
      
      status = nc_put_var_double(ncOutid,dd2vid[i],coord_array);
      if (status != NC_NOERR) handle_error(status,"Write Coordinate Variable",i);
    }

    free(coord_array);
  }

    /*
    {
      double *z;
      z = (double *) calloc((size_t) (nz+1), sizeof(double));
      for (i=0;i<=nz;i++) z[i] = (-100.0)*int_depth[i];
      status = nc_put_var_double(ncOutid,intid,z);
      if (status != NC_NOERR) handle_error(status,"Interface Coordinate",0);

      for (i=0;i<nz;i++) z[i] = (-100.0)*lay_depth[i];
      status = nc_put_var_double(ncOutid,layerid,z);
      if (status != NC_NOERR) handle_error(status,"Layer Coordinate",0);
    }
    */

  nc_close(nc_den_id);
}
예제 #10
0
파일: tst_nans.c 프로젝트: mmase/wgrib2
int
main(int argc, char **argv)
{
    int ncid, dimid, fvarid, dvarid;
    int dimids[NDIMS];
    float fvals[NVALS], fvals_in[NVALS];
    double dvals[NVALS], dvals_in[NVALS];

    float fnan = 0.f/0.f;
    double dnan = 0.0/0.0;
    float fpinf = 1.0f/0.0f;
    float fninf = -fpinf;
    double dpinf = 1.0/0.0;
    double dninf = -dpinf;
    nc_type att_type;
    size_t att_len;
    float att_fvals[NVALS];
    double att_dvals[NVALS];

#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif
    printf("*** creating NaN test file %s...", FILE8_NAME);
    if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR;
    
    if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR;
    dimids[0] = dimid;
    
    if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, NULL, &fvarid)) ERR;
    if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, NULL, &dvarid)) ERR;

    fvals[0] = fninf;
    fvals[1] = fnan;
    fvals[2] = fpinf;
    dvals[0] = dninf;
    dvals[1] = dnan;
    dvals[2] = dpinf;
    
    /* Create float and double attributes */
    if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR;
    if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR;
    if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR;
    if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR;
    
    if (nc_enddef(ncid)) ERR;
   
    /* Write float and double data */
   if (nc_put_var_float(ncid, fvarid, fvals)) ERR;
   if (nc_put_var_double(ncid, dvarid, dvals)) ERR;
   
   if (nc_close(ncid)) ERR;
   
   /* Check it out. */
   
   /* Reopen the file. */
   if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR;
   if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR;
   /* Check the values of the float attributes */
   if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR;
   if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR;
   if (!isnan(att_fvals[0])) ERR;
   if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR;
   if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR;
   if (!isnan(att_fvals[1])) ERR;
   if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR;
   /* Check the values of double attributes */
   if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR;
   if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR;
   if (!isnan(att_dvals[0])) ERR;
   if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR;
   if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR;
   if (!isnan(att_dvals[1])) ERR;
   if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR;
   /* Check values of float data */
   if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR;
   if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR;
   if (!isnan(fvals_in[1])) ERR;
   if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR;
   /* Check values of double data */
   if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR;
   if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR;
   if (!isnan(dvals_in[1])) ERR;
   if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR;

   if (nc_close(ncid)) ERR;
   
   SUMMARIZE_ERR;
   FINAL_RESULTS;
#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   

   printf("*** SUCCESS writing example file tst_nans.nc!\n");
   return 0;
}
예제 #11
0
int
main(int argc, char **argv)
{
    int ncid, dimid, fvarid, dvarid;
    float fvals[NVALS], fvals_in[NVALS];
    double dvals[NVALS], dvals_in[NVALS];


    float fnan = NC_FNAN;//(NC_INFINITE-NC_INFINITE);//0.f/0.f;
    double dnan = NC_DNAN;//(NC_INFINITE-NC_INFINITE);//0.0/0.0;
    float fpinf = NC_FPINF;//NC_INFINITE;//1.0f/0.0f;
    float fninf = -fpinf;
    double dpinf = NC_DPINF;//NC_INFINITE;//1.0/0.0;
    double dninf = -dpinf;
    nc_type att_type;
    size_t att_len;
    float att_fvals[NVALS];
    double att_dvals[NVALS];

    printf("\n*** Testing NaN\n");
    printf("*** creating NaN test file %s...", FILE8_NAME);
    if (nc_create(FILE8_NAME, NC_CLOBBER, &ncid)) ERR;

    if (nc_def_dim(ncid, DIM_NAME, NVALS, &dimid)) ERR;

    if (nc_def_var(ncid, F_NAME, NC_FLOAT, NDIMS, &dimid, &fvarid)) ERR;
    if (nc_def_var(ncid, D_NAME, NC_DOUBLE, NDIMS, &dimid, &dvarid)) ERR;

    fvals[0] = fninf;
    fvals[1] = fnan;
    fvals[2] = fpinf;
    dvals[0] = dninf;
    dvals[1] = dnan;
    dvals[2] = dpinf;

    /* Create float and double attributes */
    if (nc_put_att_float(ncid, fvarid, FV_NAME, NC_FLOAT, FV_NVALS, &fnan)) ERR;
    if (nc_put_att_float(ncid, fvarid, ATT_NAME, NC_FLOAT, NVALS, fvals)) ERR;
    if (nc_put_att_double(ncid, dvarid, FV_NAME, NC_DOUBLE, FV_NVALS, &dnan)) ERR;
    if (nc_put_att_double(ncid, dvarid, ATT_NAME, NC_DOUBLE, NVALS, dvals)) ERR;

    if (nc_enddef(ncid)) ERR;

    /* Write float and double data */
   if (nc_put_var_float(ncid, fvarid, fvals)) ERR;
   if (nc_put_var_double(ncid, dvarid, dvals)) ERR;

   if (nc_close(ncid)) ERR;

   /* Check it out. */

   /* Reopen the file. */
   if (nc_open(FILE8_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_inq_varid(ncid, F_NAME, &fvarid)) ERR;
   if (nc_inq_varid(ncid, D_NAME, &dvarid)) ERR;
   /* Check the values of the float attributes */
   if (nc_inq_att(ncid, fvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_FLOAT || att_len != FV_NVALS) ERR;
   if (nc_get_att_float(ncid, fvarid, FV_NAME, att_fvals)) ERR;
   if (!isnan(att_fvals[0])) ERR;
   if (nc_get_att_float(ncid, fvarid, ATT_NAME, att_fvals)) ERR;
   if (!(isinf(att_fvals[0]) && att_fvals[0] < 0)) ERR;
   if (!isnan(att_fvals[1])) ERR;
   if (!(isinf(att_fvals[2]) && att_fvals[2] > 0)) ERR;
   /* Check the values of double attributes */
   if (nc_inq_att(ncid, dvarid, FV_NAME, &att_type, &att_len)) ERR;
   if (att_type != NC_DOUBLE || att_len != FV_NVALS) ERR;
   if (nc_get_att_double(ncid, dvarid, FV_NAME, att_dvals)) ERR;
   if (!isnan(att_dvals[0])) ERR;
   if (nc_get_att_double(ncid, dvarid, ATT_NAME, att_dvals)) ERR;
   if (!(isinf(att_dvals[0]) && att_dvals[0] < 0)) ERR;
   if (!isnan(att_dvals[1])) ERR;
   if (!(isinf(att_dvals[2]) && att_dvals[2] > 0)) ERR;
   /* Check values of float data */
   if (nc_get_var_float(ncid, fvarid, fvals_in)) ERR;
   if (!(isinf(fvals_in[0]) && fvals_in[0] < 0)) ERR;
   if (!isnan(fvals_in[1])) ERR;
   if (!(isinf(fvals_in[2]) && fvals_in[2] > 0)) ERR;
   /* Check values of double data */
   if (nc_get_var_double(ncid, dvarid, dvals_in)) ERR;
   if (!(isinf(dvals_in[0]) && dvals_in[0] < 0)) ERR;
   if (!isnan(dvals_in[1])) ERR;
   if (!(isinf(dvals_in[2]) && dvals_in[2] > 0)) ERR;

   if (nc_close(ncid)) ERR;

   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
예제 #12
0
int
main(int argc, char **argv)
{
   char *valid[] = {
       /* pressure in 23 languages */
       "\xd8\xa7\xd9\x84\xd8\xb6\xd8\xba\xd8\xb7",
       "\xd0\xbd\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xb3\xd0\xb0\xd0\xbd\xd0\xb5",
       "\xe5\x8e\x8b\xe5\x8a\x9b",
       "\xe5\xa3\x93\xe5\x8a\x9b",
       "pritisak",
       "tlaku",
       "pres",
       "druk",
       "pressure",
       "paine",
       "pression",
       "Druck",
       "\xcf\x80\xce\xaf\xce\xb5\xcf\x83\xce\xb7",
       "\xe0\xa4\xa6\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb5",
       "pressione",
       "\xe5\x9c\xa7\xe5\x8a\x9b",
       "\xec\x95\x95\xeb\xa0\xa5",
       "press",
       "ci\xc5\x9bnienie",
       "Press\xc3\xa3o",
       "presiune",
       "\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5",
       "presi\xc3\xb3n",
       /* special characters in names, numeric characters at the start of names */
       "has blank",
       "has:colon",
       "a",
       "A",
       "0leading_numeric_char",
       "1",
       "0x123"
   };
   char *notvalid[] = {
       "-leading_special_char",
       "trailing_space ",
       "trailing_tab\t",
       "trailing_newline\n",
       "has_control_char_\a_in_name",
       "has ascii_del_\x7f_in name",
       /* Invalid UTF-8 of various sorts, thanks to Markus Kuhn */
       "\xA0\xB0\xC0\xD0",
       "xyz\x80", 		/* unexpected continuation bytes */
       "\x80xyz",
       "xyz\xBF",
       "\xBFxyz",
       "\xC0xyz",		/* lonely start characters */
       "x\xC0yz",
       "xy\xC0z",
       "xyz\xC0",
       "\xDFxyz",
       "x\xDFyz",
       "xy\xDFz",
       "xyz\xDF",
       "\xE0xyz",
       "x\xE0yz",
       "xy\xE0z",
       "xyz\xE0",
       "\xE0\xBFxy",
       "x\xE0\xBFy",
       "xy\xE0\xBF",
       "\xEFxyz",
       "x\xEFyz",
       "xy\xEFz",
       "xyz\xEF",
       "\xEF\x80xy",
       "x\xEF\x80y",
       "xy\xEF\x80",
       "\xF0xyz",
       "x\xF0yz",
       "xy\xF0z",
       "xyz\xF0",
       "\xF7xyz",
       "x\xF7yz",
       "xy\xF7z",
       "xyz\xF7",
       "\xF8xyz",
       "x\xF8yz",
       "xy\xF8z",
       "xyz\xF8",
       "\xFBxyz",
       "x\xFByz",
       "xy\xFBz",
       "xyz\xFB",
       "\xFCxyz",
       "x\xFCyz",
       "xy\xFCz",
       "xyz\xFC",
       "\xFDxyz",
       "x\xFDyz",
       "xy\xFDz",
       "xyz\xFD",
       "\xC0\xC0xy",		/* last continuation byte missing */
       "x\xC0\xC0y",
       "xy\xC0\xC0",
       "\xDF\xDFxy",
       "x\xDF\xDFy",
       "xy\xDF\xDF",
       "\xE0\x80xy",
       "x\xE0\x80y",
       "xy\xE0\x80",
       "\xEF\x80xy",
       "x\xEF\x80y",
       "xy\xEF\x80",
       "\xF0\x80\x80x",
       "x\xF0\x80\x80",
       "\xF7\x80\x80x",
       "x\xF7\x80\x80",
       "\xF8\x80\x80\x80x",
       "x\xF8\x80\x80\x80",
       "\xFB\x80\x80\x80x",
       "x\xFB\x80\x80\x80",
       "\xFC\x80\x80\x80\x80x",
       "x\xFC\x80\x80\x80\x80",
       "\xFD\x80\x80\x80\x80x",
       "x\xFD\x80\x80\x80\x80",
       "\xFExyz",		/* impossible bytes */
       "x\xFEyz",
       "xy\xFEz",
       "xyz\xFE",
       "\xFFxyz",
       "x\xFFyz",
       "xy\xFFz",
       "xyz\xFF",
       "\xC0\xAFxy",		/* overlong sequences */
       "x\xC0\xAFy",
       "xy\xC0\xAF",
       "\xE0\x80\xAFx",
       "x\xE0\x80\xAF",
       "\xF0\x80\x80\xAFx",
       "x\xF0\x80\x80\xAF",
       "\xF8\x80\x80\x80\xAFx",
       "x\xF8\x80\x80\x80\xAF",
       "\xFC\x80\x80\x80\x80\xAFx",
       "x\xFC\x80\x80\x80\x80\xAF",
       "\xC1\xBFxy",
       "x\xC1\xBFy",
       "xy\xC1\xBF",
       "\xE0\x9F\xBFx",
       "x\xE0\x9F\xBF",
       "\xF0\x8F\xBF\xBFx",
       "x\xF0\x8F\xBF\xBF",
       "\xF8\x87\xBF\xBF\xBFx",
       "x\xF8\x87\xBF\xBF\xBF",
       "\xFC\x83\xBF\xBF\xBF\xBFx",
       "x\xFC\x83\xBF\xBF\xBF\xBF",
       "x\xC0\x80",		/* overlong NULs */
       "x\xE0\x80\x80",
       "x\xF0\x80\x80\x80",
       "x\xF8\x80\x80\x80\x80",
       "x\xFC\x80\x80\x80\x80\x80",
       /* single UTF-16 surrogates */
       "x\xED\xA0\x80",
       "x\xED\xAD\xBF",
       "x\xED\xAE\x80",
       "x\xED\xAF\xBF",
       "x\xED\xB0\x80",
       "x\xED\xBE\x80",
       "x\xED\xBF\xBF",
       "x\xED\xA0\x80\xED\xB0\x80", /* paired UTF-16 surrogates */
       "x\xED\xA0\x80\xED\xBF\xBF",
       "x\xED\xAD\xBF\xED\xB0\x80",
       "x\xED\xAD\xBF\xED\xBF\xBF",
       "x\xED\xAE\x80\xED\xB0\x80",
       "x\xED\xAE\x80\xED\xBF\xBF",
       "x\xED\xAF\xBF\xED\xB0\x80",
       "x\xED\xAF\xBF\xED\xBF\xBF",
       "x\xEF\xBF\xBE",		/* other illegal code positions */
       "x\xEF\xBF\xBF"
   };
   int i, j;
#define NUM_BAD (sizeof notvalid / sizeof notvalid[0])
#define NUM_GOOD (sizeof valid / sizeof valid[0])
   int ncid, dimid, varid, res;
   double attvals[] = {-2.0};
   double attvals_in[1];
#define NATTVALS (sizeof attvals / sizeof attvals[0])
   char *attstring = "text";
#define MAX_ATTSTRING_LEN 100
   char attstr_in[MAX_ATTSTRING_LEN];
   int dimids[NUM_GOOD];
   int varids[NUM_GOOD];
#if 0
   int attnums[NUM_GOOD];
#endif
   char *testfile = FILE_NAME;
   int formats[] = {
       NC_FORMAT_CLASSIC
       ,
       NC_FORMAT_64BIT
#ifdef USE_NETCDF4
       ,
       NC_FORMAT_NETCDF4
       ,
       NC_FORMAT_NETCDF4_CLASSIC
#endif	/* USE_NETCDF4 */
   };
   int num_formats = (sizeof formats) / (sizeof formats[0]);
   char *format_names[] = {
       "classic", "64-bit offset", "netCDF-4/HDF5", "netCDF-4 classic model"
   };

   printf("\n*** testing names with file %s...\n", testfile);
   for (j = 0; j < num_formats; j++)
   {
       printf("*** switching to netCDF %s format...", format_names[j]);
       nc_set_default_format(formats[j], NULL);
       if((res = nc_create(testfile, NC_CLOBBER, &ncid)))
	   ERR;

       /* Define dimensions, variables, and attributes with various
	* acceptable names */
       for (i = 0; i < NUM_GOOD; i++) {
	   if ((res = nc_def_dim(ncid, valid[i], DIMLEN, &dimid)))
	       ERR;
	   dimids[i] = dimid;
	   /* Define variable with same name */
	   if ((res = nc_def_var(ncid, valid[i], NC_FLOAT, NDIMS, &dimids[i],
				 &varid)))
	       ERR;
	   varids[i] = varid;
	   /* Define variable and global attributes with same name and value */
	   if ((res = nc_put_att_text(ncid, varid, valid[i],
				      strlen(valid[i]), valid[i])))
	       ERR;
	   if ((res = nc_put_att_double(ncid, NC_GLOBAL, valid[i], NC_DOUBLE,
					NATTVALS, attvals)))
	       ERR;
#if 0
	   attnums[i] = i;
#endif
       }

       /* Try defining dimensions, variables, and attributes with various
	* bad names and make sure these are rejected */
       for (i = 0; i < NUM_BAD; i++) {
	   if ((res = nc_def_dim(ncid, notvalid[i], DIMLEN, &dimid))
	       != NC_EBADNAME) ERR;
	   if ((res = nc_def_var(ncid, notvalid[i], NC_FLOAT, NDIMS, dimids,
				 &varid))
	       != NC_EBADNAME) ERR;
	   if ((res = nc_put_att_text(ncid, varid, notvalid[i],
				      strlen(attstring), attstring))
	       != NC_EBADNAME) ERR;
	   if ((res = nc_put_att_double(ncid, NC_GLOBAL, notvalid[i], NC_DOUBLE,
					NATTVALS, attvals))
	       != NC_EBADNAME) ERR;
       }
       if ((res = nc_enddef(ncid)))
	   ERR;
       if ((res = nc_close(ncid)))
	   ERR;

       /* Check it out, make sure all objects with good names were defined OK */
       if ((res = nc_open(testfile, NC_NOWRITE, &ncid)))
	   ERR;
       for (i = 0; i < NUM_GOOD; i++) {
	   size_t attlen;
	   if ((res = nc_inq_dimid(ncid, valid[i], &dimid)) ||
	       dimid != dimids[i])
	       ERR;
	   if ((res = nc_inq_varid(ncid, valid[i], &varid)) ||
	       varid != varids[i])
	       ERR;
	   res = nc_inq_attlen(ncid, varid, valid[i], &attlen);
	   if ((res = nc_get_att_text(ncid, varid, valid[i], attstr_in)))
	       ERR;
	   attstr_in[attlen] = '\0';
	   if (strcmp(valid[i], attstr_in) != 0)
	       ERR;
	   if ((res = nc_get_att_double(ncid, NC_GLOBAL, valid[i],
					attvals_in))
	       || attvals[0] != attvals_in[0])
	       ERR;
       }
       if ((res = nc_close(ncid)))
	   ERR;
/*        (void) remove(testfile); */
       SUMMARIZE_ERR;
   }
   FINAL_RESULTS;

   return 0;
}
예제 #13
0
GDALDataset *GMTDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Does this file have the GMT magic number?                    */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->fpL == NULL || poOpenInfo->nHeaderBytes < 50 )
        return NULL;

    if( poOpenInfo->pabyHeader[0] != 'C' 
        || poOpenInfo->pabyHeader[1] != 'D' 
        || poOpenInfo->pabyHeader[2] != 'F' 
        || poOpenInfo->pabyHeader[3] != 1 )
        return NULL;
    
    CPLMutexHolderD(&hNCMutex);

/* -------------------------------------------------------------------- */
/*      Try opening the dataset.                                        */
/* -------------------------------------------------------------------- */
    int cdfid, nm_id, dim_count, z_id;

    if( nc_open( poOpenInfo->pszFilename, NC_NOWRITE, &cdfid ) != NC_NOERR )
        return NULL;

    if( nc_inq_varid( cdfid, "dimension", &nm_id ) != NC_NOERR 
        || nc_inq_varid( cdfid, "z", &z_id ) != NC_NOERR )
    {
#ifdef notdef
        CPLError( CE_Warning, CPLE_AppDefined, 
                  "%s is a GMT file, but not in GMT configuration.",
                  poOpenInfo->pszFilename );
#endif
        nc_close( cdfid );
        return NULL;
    }

    if( nc_inq_ndims( cdfid, &dim_count ) != NC_NOERR || dim_count < 2 )
    {
        nc_close( cdfid );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        nc_close( cdfid );
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The GMT driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    GMTDataset 	*poDS;

    CPLReleaseMutex(hNCMutex);  // Release mutex otherwise we'll deadlock with GDALDataset own mutex
    poDS = new GMTDataset();
    CPLAcquireMutex(hNCMutex, 1000.0);

    poDS->cdfid = cdfid;
    poDS->z_id = z_id;
    
/* -------------------------------------------------------------------- */
/*      Get dimensions.  If we can't find this, then this is a          */
/*      GMT file, but not a normal grid product.                     */
/* -------------------------------------------------------------------- */
    size_t start[2], edge[2];
    int    nm[2];

    start[0] = 0;
    edge[0] = 2;

    nc_get_vara_int(cdfid, nm_id, start, edge, nm);
    
    poDS->nRasterXSize = nm[0];
    poDS->nRasterYSize = nm[1];

/* -------------------------------------------------------------------- */
/*      Fetch "z" attributes scale_factor, add_offset, and              */
/*      node_offset.                                                    */
/* -------------------------------------------------------------------- */
    double scale_factor=1.0, add_offset=0.0;
    int node_offset = 1;

    nc_get_att_double( cdfid, z_id, "scale_factor", &scale_factor );
    nc_get_att_double( cdfid, z_id, "add_offset", &add_offset );
    nc_get_att_int( cdfid, z_id, "node_offset", &node_offset );

/* -------------------------------------------------------------------- */
/*      Get x/y range information.                                      */
/* -------------------------------------------------------------------- */
    int x_range_id, y_range_id;

    if( nc_inq_varid (cdfid, "x_range", &x_range_id) == NC_NOERR 
        && nc_inq_varid (cdfid, "y_range", &y_range_id) == NC_NOERR )
    {
        double x_range[2], y_range[2];

        nc_get_vara_double( cdfid, x_range_id, start, edge, x_range );
        nc_get_vara_double( cdfid, y_range_id, start, edge, y_range );

        // Pixel is area
        if( node_offset == 1 )
        {
            poDS->adfGeoTransform[0] = x_range[0];
            poDS->adfGeoTransform[1] = 
                (x_range[1] - x_range[0]) / poDS->nRasterXSize;
            poDS->adfGeoTransform[2] = 0.0;
            poDS->adfGeoTransform[3] = y_range[1];
            poDS->adfGeoTransform[4] = 0.0;
            poDS->adfGeoTransform[5] = 
                (y_range[0] - y_range[1]) / poDS->nRasterYSize;
        }

        // Pixel is point - offset by half pixel. 
        else /* node_offset == 0 */ 
        {
            poDS->adfGeoTransform[1] = 
                (x_range[1] - x_range[0]) / (poDS->nRasterXSize-1);
            poDS->adfGeoTransform[0] = 
                x_range[0] - poDS->adfGeoTransform[1]*0.5;
            poDS->adfGeoTransform[2] = 0.0;
            poDS->adfGeoTransform[4] = 0.0;
            poDS->adfGeoTransform[5] = 
                (y_range[0] - y_range[1]) / (poDS->nRasterYSize-1);
            poDS->adfGeoTransform[3] = 
                y_range[1] - poDS->adfGeoTransform[5]*0.5;
        }
    }
    else
    {
        poDS->adfGeoTransform[0] = 0.0;
        poDS->adfGeoTransform[1] = 1.0;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = 0.0;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = 1.0;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    poDS->nBands = 1;
    poDS->SetBand( 1, new GMTRasterBand( poDS, z_id, 1 ));

    if( scale_factor != 1.0 || add_offset != 0.0 )
    {
        poDS->GetRasterBand(1)->SetOffset( add_offset );
        poDS->GetRasterBand(1)->SetScale( scale_factor );
    }

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );

    CPLReleaseMutex(hNCMutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for external overviews.                                   */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() );
    CPLAcquireMutex(hNCMutex, 1000.0);

    return( poDS );
}
예제 #14
0
int
main(int argc, char **argv)
{
    (void) signal(SIGFPE, SIG_IGN);

   printf("\n*** Testing netcdf-4 attribute functions.\n");
   printf("*** testing really simple global atts...");
#define NUM_SIMPLE_ATTS 9
   {
      int ncid;
      char name[NUM_SIMPLE_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf", 
						      "Gd", "G7", "G8", "G9"};
      char name_in[NC_MAX_NAME];
      int j;

      /* Create a file with some global atts. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      for (j = 0; j < NUM_SIMPLE_ATTS; j++)
	 if (nc_put_att_int(ncid, NC_GLOBAL, name[j], NC_INT, 0, NULL)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and check the order. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      for (j = 0; j < NUM_SIMPLE_ATTS; j++)
      {
	 if (nc_inq_attname(ncid, NC_GLOBAL, j, name_in)) ERR;
	 if (strcmp(name_in, name[j])) ERR;
      }

      /* Close up shop. */
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple global atts...");
   {      
      int ncid;
      nc_type att_type;
      size_t att_len;
      int i;

      char *speech_in;
      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
      unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT};
      unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT};
      unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL};
      long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64};


      /* This won't work, because classic files can't create these types. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, 
			    ushort_out) != NC_ESTRICTNC3) ERR;      
      if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, 
			  uint_out) != NC_ESTRICTNC3) ERR;      
      if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, 
			      int64_out) != NC_ESTRICTNC3) ERR;      
      if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, 
			       uint64_out) != NC_ESTRICTNC3) ERR;      
      if (nc_close(ncid)) ERR;

      /* Create a file with a global attribute of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR;      
      if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR;
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR;      
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR;      
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR;      
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR;      
      if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR;      
      if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR;      
      if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR;      
      if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR;      
      if (nc_close(ncid)) ERR;

      /* Open the file and check attributes. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      /* Check text. */
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len))
	 ERR;
      if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
      if (!(speech_in = malloc(att_len + 1))) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR;      
      if (strcmp(speech, speech_in)) ERR;
      free(speech_in);
      /* Check numeric values. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != schar_out[i]) ERR;
      if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (uchar_in[i] != uchar_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != short_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != int_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != float_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != double_out[i]) ERR;
      if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (ushort_in[i] != ushort_out[i]) ERR;
      if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (uint_in[i] != uint_out[i]) ERR;
      if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int64_in[i] != int64_out[i]) ERR;
      if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (uint64_in[i] != uint64_out[i]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing attribute data type conversions...");

   {
      int ncid;
      int i;

      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
      unsigned short ushort_in[ATT_LEN];
      unsigned int uint_in[ATT_LEN];
      unsigned long long uint64_in[ATT_LEN];
      long long int64_in[ATT_LEN];

      /* Reopen the file and try different type conversions. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;

      /* No text conversions are allowed, and people who try them shold
       * be locked up, away from decent folk! */
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_TEXT_NAME, short_in) != NC_ECHAR) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_TEXT_NAME, int_in) != NC_ECHAR) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_TEXT_NAME, float_in) != NC_ECHAR) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_TEXT_NAME, double_in) != NC_ECHAR) ERR;
/*   if (nc_get_att_ubyte(ncid, NC_GLOBAL, ATT_TEXT_NAME, uchar_in) != NC_ECHAR) ERR;*/
      if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_TEXT_NAME, ushort_in) != NC_ECHAR) ERR;
      if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint_in) != NC_ECHAR) ERR;
      if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_TEXT_NAME, int64_in) != NC_ECHAR) ERR;
      if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_TEXT_NAME, uint64_in) != NC_ECHAR) ERR;

      /* Read all atts (except text) as double. */
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SCHAR_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != schar_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_SHORT_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != short_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_INT_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != int_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_FLOAT_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != float_out[i]) ERR;
      /* Read all atts (except text) as float. */
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SCHAR_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != schar_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_SHORT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != short_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_INT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != (float)int_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != (float)double_out[i]) ERR;
      /* Read all atts (except text) as int. */
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SCHAR_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != schar_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_SHORT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != short_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_FLOAT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != (int)float_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != (int)double_out[i]) ERR;
      /* Read all atts (except text) as short. */
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SCHAR_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != schar_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in) != NC_ERANGE) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != (short)int_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != (short)float_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != (short)double_out[i]) ERR;
      /* Read all atts (except text) as schar. Some range errors will
       * result converting to schar. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in) != NC_ERANGE) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)short_out[i]) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in) != NC_ERANGE) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)int_out[i]) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)float_out[i]) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != (signed char)double_out[i]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple variable atts...");
   {
      int ncid, varid, dimids[2];
      nc_type att_type;
      size_t att_len;
      int i, v;

      char *speech_in;
      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};

      /* Create a file with two vars, attaching to each an attribute of
       * each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR;      
      if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR;      
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR;      
      if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR;      
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_put_att_text(ncid, varid, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, varid, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR; 
      if (nc_put_att_short(ncid, varid, ATT_SHORT_NAME, NC_SHORT, 3, short_out)) ERR;           
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_put_att_float(ncid, varid, ATT_FLOAT_NAME, NC_FLOAT, 3, float_out)) ERR;      
      if (nc_put_att_double(ncid, varid, ATT_DOUBLE_NAME, NC_DOUBLE, 3, double_out)) ERR;      
      if (nc_close(ncid)) ERR;

      /* Open the file and check attributes. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      for (v=0; v<2; v++)
      {
	 if (nc_inq_att(ncid, v, ATT_TEXT_NAME, &att_type, &att_len)) ERR;
	 if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
	 if (!(speech_in = malloc(att_len + 1))) ERR;
	 if (nc_get_att_text(ncid, v, ATT_TEXT_NAME, speech_in)) ERR;      
	 if (strcmp(speech, speech_in)) ERR;
	 free(speech_in);
	 if (nc_get_att_schar(ncid, v, ATT_SCHAR_NAME, schar_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (schar_in[i] != schar_out[i]) ERR;
	 if (nc_get_att_short(ncid, v, ATT_SHORT_NAME, short_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (short_in[i] != short_out[i]) ERR;
	 if (nc_get_att_int(ncid, v, ATT_INT_NAME, int_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (int_in[i] != int_out[i]) ERR;
	 if (nc_get_att_float(ncid, v, ATT_FLOAT_NAME, float_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (float_in[i] != float_out[i]) ERR;
	 if (nc_get_att_double(ncid, v, ATT_DOUBLE_NAME, double_in)) ERR;      
	 for (i = 0; i < ATT_LEN; i++)
	    if (double_in[i] != double_out[i]) ERR;
      }
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing zero-length attributes...");
   {
      int ncid;

      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/

      /* Create a file with a global attribute of each type of zero length. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR;
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR;
/*   if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR;
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR;
      if (nc_close(ncid)) ERR;
   }

   /* Make sure we can read all these zero-length atts. */
   {
      int ncid;
      signed char schar_in[ATT_LEN];
      short short_in[ATT_LEN];
      /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
      int int_in[ATT_LEN];
      float float_in[ATT_LEN];
      double double_in[ATT_LEN];
      size_t len;
      nc_type xtype;

      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_CHAR) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_BYTE) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_SHORT) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_INT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_INT) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_FLOAT) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, &xtype, &len)) ERR;
      if (len || xtype != NC_DOUBLE) ERR;
      /* Conversions no longer result in range errors, since there's no data. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing zero-length attributes and redef...(this test skipped for HDF5-1.8.0 beta1");
   {
      int ncid;
      signed char schar_in[ATT_LEN];
      short short_in[ATT_LEN];
      int int_in[ATT_LEN];
      float float_in[ATT_LEN];
      double double_in[ATT_LEN];


      /* Create a file with a global attribute of each type of zero length. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL)) ERR;
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL)) ERR;
/*   if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UCHAR, ATT_LEN, uchar_out)) ERR;*/
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL)) ERR;
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL)) ERR;
      if (nc_close(ncid)) ERR;

      /* Make sure we can read all these zero-length atts added during a
       * redef. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;
      /* Conversions no longer result in range errors, since there's no data. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) ERR;
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

   printf("*** testing attribute deletes and renames...");
   {
      int ncid, varid, dimids[2];
      nc_type att_type;
      size_t att_len;
      char *speech_in;
      char name_in[NC_MAX_NAME + 1];
      int attid_in, natts_in;
      int int_out[ATT_LEN] = {-100000, 128, 100000};

      /* Create a file with a global attribute. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, 
			  speech)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Rename it. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_attid(ncid, NC_GLOBAL, ATT_TEXT_NAME, &attid_in)) ERR;
      if (attid_in != 0) ERR;
      if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR;
      if (strcmp(name_in, ATT_TEXT_NAME)) ERR;
      if (nc_rename_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ATT_TEXT_NAME2)) ERR;      
      if (nc_inq_attname(ncid, NC_GLOBAL, attid_in, name_in)) ERR;
      if (strcmp(name_in, ATT_TEXT_NAME2)) ERR;
      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2, &att_type, &att_len)) ERR;
      if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
      if (!(speech_in = malloc(att_len + 1))) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME2, speech_in)) ERR;      
      if (strcmp(speech, speech_in)) ERR;
      free(speech_in);
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in) != NC_ENOTATT) ERR;      
      if (nc_close(ncid)) ERR;

      /* Now delete the att. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_del_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2)) ERR;
      if (nc_close(ncid)) ERR;

      /* Now create a file with a variable, which has an att. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and delete it. Make sure it's gone. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen the file and readd the attribute. Enddef and redef,
       * and delete it, then check to make sure it's gone. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out)) ERR;      
      if (nc_enddef(ncid)) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_del_att(ncid, 0, ATT_INT_NAME)) ERR;
      if (nc_inq_varnatts(ncid, 0, &natts_in)) ERR;
      if (natts_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing attribute create order...");

#define ATT0 "Maturin"
#define ATT1 "Aubery"
   {
      int ncid, varid, dimids[2];
      int attid_in;
      const int number = 42;

      /* Create a file with several global attributes. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT0, NC_INT, 1, &number)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT1, NC_INT, 1, &number)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Open it and check the order. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_attid(ncid, NC_GLOBAL, ATT0, &attid_in)) ERR;
      if (attid_in != 0) ERR;
      if (nc_inq_attid(ncid, NC_GLOBAL, ATT1, &attid_in)) ERR;
      if (attid_in != 1) ERR;
      if (nc_close(ncid)) ERR;

      /* Now create a file with a variable, which has two atts. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_put_att_int(ncid, varid, ATT0, NC_INT, 1, &number)) ERR;
      if (nc_put_att_int(ncid, varid, ATT1, NC_INT, 1, &number)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and check the order of the attributes on the var. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq_attid(ncid, 0, ATT0, &attid_in)) ERR;
      if (attid_in != 0) ERR;
      if (nc_inq_attid(ncid, 0, ATT1, &attid_in)) ERR;
      if (attid_in != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing attribute ordering some more...");

#define VAR_NAME "i"
#define A1_NAME "i"      
#define A2_NAME "f"      
#define A3_NAME "d"      
#define A1_LEN 3
#define A2_LEN 4
#define A3_LEN 5
   {
      int ncid;
      int varid, natts, nvars;
      double dvalue[] = {999.99, 999.99, 999.99, 999.99, 999.99};
      int varids[1];
      char name_in[NC_MAX_NAME + 1];

      /* Create a file with one var, and attach three atts to it. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid)) ERR;
      if (nc_put_att_double(ncid, varid, A1_NAME, NC_INT, A1_LEN, dvalue)) ERR;      
      if (nc_put_att_double(ncid, varid, A2_NAME, NC_INT, A2_LEN, dvalue)) ERR;      
      if (nc_put_att_double(ncid, varid, A3_NAME, NC_INT, A3_LEN, dvalue)) ERR;      
      if (nc_close(ncid)) ERR;
      
      /* Reopen the file and check. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq_varids(ncid, &nvars, varids)) ERR;
      if (nvars != 1 || varids[0] != 0) ERR;
      if (nc_inq_varnatts(ncid, 0, &natts)) ERR;
      if (natts != 3) ERR;
      if (nc_inq_attname(ncid, 0, 0, name_in)) ERR;
      if (strcmp(name_in, A1_NAME)) ERR;
      if (nc_inq_attname(ncid, 0, 1, name_in)) ERR;
      if (strcmp(name_in, A2_NAME)) ERR;
      if (nc_inq_attname(ncid, 0, 2, name_in)) ERR;
      if (strcmp(name_in, A3_NAME)) ERR;

      /* Close up shop. */
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing attribute ordering even more...");

   /* Test the ordering of atts for each cmode. */
   if (tst_att_ordering(NC_CLOBBER)) ERR;
   if (tst_att_ordering(NC_CLOBBER|NC_64BIT_OFFSET)) ERR;
   if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4)) ERR;
   if (tst_att_ordering(NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR;

   SUMMARIZE_ERR;
   printf("*** testing attributes and enddef/redef...");

#define ATT_1 "a"
#define ATT_2 "b"
#define ATT_3 "c"
   {
      int ncid, att = 1;

      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL|NC_CLOBBER, &ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_1, NC_INT, 1, &att)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_2, NC_INT, 1, &att)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_3, NC_INT, 1, &att)) ERR;

      if (nc_close(ncid)) ERR;

      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing copy of simple global atts...");
   {      
      int ncid, ncid2;
      nc_type att_type;
      size_t att_len;
      int i;

      char *speech_in;
      signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
      unsigned char uchar_in[ATT_LEN], uchar_out[ATT_LEN] = {0, 128, NC_MAX_CHAR};
      short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
      int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
      float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
      double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
      unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT};
      unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT};
      unsigned long long uint64_in[ATT_LEN], uint64_out[ATT_LEN] = {0, 128, 18446744073709551612ULL};
      long long int64_in[ATT_LEN], int64_out[ATT_LEN] = {NC_MIN_INT64, 128, NC_MAX_INT64};

      /* Create a file with a global attribute of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech)) ERR;      
      if (nc_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out)) ERR;      
      if (nc_put_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, NC_UBYTE, ATT_LEN, uchar_out)) ERR;
      if (nc_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out)) ERR;      
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out)) ERR;      
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out)) ERR;      
      if (nc_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out)) ERR;      
      if (nc_put_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, NC_USHORT, ATT_LEN, ushort_out)) ERR;      
      if (nc_put_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, NC_UINT, ATT_LEN, uint_out)) ERR;      
      if (nc_put_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, NC_INT64, ATT_LEN, int64_out)) ERR;      
      if (nc_put_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, NC_UINT64, ATT_LEN, uint64_out)) ERR;      

      /* Create another file and copy all the attributes. */
      if (nc_create(FILE_NAME2, NC_NETCDF4, &ncid2)) ERR;      
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_UCHAR_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_USHORT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_INT64_NAME, ncid2, NC_GLOBAL)) ERR;
      if (nc_copy_att(ncid, NC_GLOBAL, ATT_UINT64_NAME, ncid2, NC_GLOBAL)) ERR;

      /* Close both files. */
      if (nc_close(ncid)) ERR;
      if (nc_close(ncid2)) ERR;

      /* Open the file and check attributes. */
      if (nc_open(FILE_NAME2, 0, &ncid)) ERR;
      /* Check text. */
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len)) ERR;
      if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERR;
      if (!(speech_in = malloc(att_len + 1))) ERR;
      if (nc_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) ERR;      
      if (strcmp(speech, speech_in)) ERR;
      free(speech_in);
      /* Check numeric values. */
      if (nc_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (schar_in[i] != schar_out[i]) ERR;
      if (nc_get_att_uchar(ncid, NC_GLOBAL, ATT_UCHAR_NAME, uchar_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (uchar_in[i] != uchar_out[i]) ERR;
      if (nc_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (short_in[i] != short_out[i]) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (int_in[i] != int_out[i]) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (float_in[i] != float_out[i]) ERR;
      if (nc_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in)) ERR;      
      for (i = 0; i < ATT_LEN; i++)
	 if (double_in[i] != double_out[i]) ERR;
      if (nc_get_att_ushort(ncid, NC_GLOBAL, ATT_USHORT_NAME, ushort_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (ushort_in[i] != ushort_out[i]) ERR;
      if (nc_get_att_uint(ncid, NC_GLOBAL, ATT_UINT_NAME, uint_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (uint_in[i] != uint_out[i]) ERR;
      if (nc_get_att_longlong(ncid, NC_GLOBAL, ATT_INT64_NAME, int64_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (int64_in[i] != int64_out[i]) ERR;
      if (nc_get_att_ulonglong(ncid, NC_GLOBAL, ATT_UINT64_NAME, uint64_in)) ERR;
      for (i = 0; i < ATT_LEN; i++)
	 if (uint64_in[i] != uint64_out[i]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
예제 #15
0
int CNetCdfInterface::ncGetAttType(int ncid, int varid, const char* attrName, double* data)
{
  return nc_get_att_double(ncid, varid, attrName, data);
}
예제 #16
0
파일: netcdf.c 프로젝트: sekcheong/monetdb
str
NCDFattach(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	mvc *m = NULL;
	sql_schema *sch = NULL;
	sql_table *tfiles = NULL, *tdims = NULL, *tvars = NULL, *tvardim = NULL, *tattrs = NULL;
	sql_column *col;
	str msg = MAL_SUCCEED;
	str fname = *(str*)getArgReference(stk, pci, 1);
	char buf[BUFSIZ], *s= buf;
	oid fid, rid = oid_nil;
	sql_trans *tr;

	int ncid;   /* dataset id */
	int ndims, nvars, ngatts, unlimdim;
	int didx, vidx, vndims, vnatts, i, aidx, coord_dim_id = -1;
	int vdims[NC_MAX_VAR_DIMS];

	size_t dlen, alen;
	char dname[NC_MAX_NAME+1], vname[NC_MAX_NAME+1], aname[NC_MAX_NAME +1], 
	  abuf[80], *aval;
	char **dims = NULL;
	nc_type vtype, atype; /* == int */

	int retval, avalint;
	float avalfl;
	double avaldbl;

	msg = getSQLContext(cntxt, mb, &m, NULL);
	if (msg)
        return msg;

	tr = m->session->tr;
	sch = mvc_bind_schema(m, "sys");
	if ( !sch )
        return createException(MAL, "netcdf.attach", "Cannot get schema sys\n");

	tfiles = mvc_bind_table(m, sch, "netcdf_files");
	tdims = mvc_bind_table(m, sch, "netcdf_dims");
	tvars = mvc_bind_table(m, sch, "netcdf_vars");
	tvardim = mvc_bind_table(m, sch, "netcdf_vardim");
	tattrs = mvc_bind_table(m, sch, "netcdf_attrs");

	if (tfiles == NULL || tdims == NULL || tvars == NULL || 
	    tvardim == NULL || tattrs == NULL)
        return createException(MAL, "netcdf.attach", "Catalog table missing\n");

	/* check if the file is already attached */
	col = mvc_bind_column(m, tfiles, "location");
	rid = table_funcs.column_find_row(m->session->tr, col, fname, NULL);
	if (rid != oid_nil) 
	    return createException(SQL, "netcdf.attach", "File %s is already attached\n", fname);

	/* Open NetCDF file  */
	if ((retval = nc_open(fname, NC_NOWRITE, &ncid)))
        return createException(MAL, "netcdf.test", "Cannot open NetCDF \
file %s: %s", fname, nc_strerror(retval));

	if ((retval = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdim)))
        return createException(MAL, "netcdf.test", "Cannot read NetCDF \
header: %s", nc_strerror(retval));

	/* Insert row into netcdf_files table */
	col = mvc_bind_column(m, tfiles, "file_id");
	fid = store_funcs.count_col(tr, col, 1) + 1;

	snprintf(buf, BUFSIZ, INSFILE, (int)fid, fname);
	if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	        != MAL_SUCCEED )
	    goto finish;

	/* Read dimensions from NetCDF header and insert a row for each one into netcdf_dims table */

	dims = (char **)GDKzalloc(sizeof(char *) * ndims);
	for (didx = 0; didx < ndims; didx++){
	    if ((retval = nc_inq_dim(ncid, didx, dname, &dlen)))
	        return createException(MAL, "netcdf.attach", "Cannot read dimension %d : %s", didx, nc_strerror(retval));

	    snprintf(buf, BUFSIZ, INSDIM, didx, (int)fid, dname, (int)dlen);
	    if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
    	 != MAL_SUCCEED )
	        goto finish;

	    dims[didx] = GDKstrdup(dname);
	}

	/* Read variables and attributes from the header and insert rows in netcdf_vars, netcdf_vardims, and netcdf_attrs tables */
	for (vidx = 0; vidx < nvars; vidx++){
	    if ( (retval = nc_inq_var(ncid, vidx, vname, &vtype, &vndims, vdims, &vnatts)))
	        return createException(MAL, "netcdf.attach", 
			     "Cannot read variable %d : %s", 
			     vidx, nc_strerror(retval));

    	/* Check if this is coordinate variable */
        if ( (vndims == 1) && ( strcmp(vname, dims[vdims[0]]) == 0 ))
	        coord_dim_id = vdims[0];
        else coord_dim_id = -1;

	    snprintf(buf, BUFSIZ, INSVAR, vidx, (int)fid, vname, prim_type_name(vtype), vndims, coord_dim_id);
	    if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	        != MAL_SUCCEED )
            goto finish;

	    if ( coord_dim_id < 0 ){
	        for (i = 0; i < vndims; i++){
                snprintf(buf, BUFSIZ, INSVARDIM, vidx, vdims[i], (int)fid, i);
                if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
            	   != MAL_SUCCEED )
                	goto finish;
	        }
	    }

    	if ( vnatts > 0 ) { /* fill in netcdf_attrs table */

            for (aidx = 0; aidx < vnatts; aidx++){
                if ((retval = nc_inq_attname(ncid,vidx,aidx,aname)))
                    return createException(MAL, "netcdf.attach",
                        "Cannot read attribute %d of variable %d: %s",
                        aidx, vidx, nc_strerror(retval));

	            if ((retval = nc_inq_att(ncid,vidx,aname,&atype,&alen)))
                    return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s type and length: %s",
	                    aname, nc_strerror(retval));


        	switch ( atype ) {
        	case NC_CHAR:
                aval = (char *) GDKzalloc(alen + 1);
                if ((retval = nc_get_att_text(ncid,vidx,aname,aval)))
                    return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
		fix_quote(aval, alen);
                aval[alen] = '\0';
                snprintf(buf, BUFSIZ, INSATTR, vname, aname, "string", aval, (int)fid, "root");
                GDKfree(aval);
            break;

        	case NC_INT:
	            if ((retval = nc_get_att_int(ncid,vidx,aname,&avalint)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
                snprintf(abuf,80,"%d",avalint);
                snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root");
	        break;
	
        	case NC_FLOAT:
	            if ((retval = nc_get_att_float(ncid,vidx,aname,&avalfl)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
	            snprintf(abuf,80,"%7.2f",avalfl);
	            snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root");
	        break;

	        case NC_DOUBLE:
	            if ((retval = nc_get_att_double(ncid,vidx,aname,&avaldbl)))
        	        return createException(MAL, "netcdf.attach",
	                    "Cannot read attribute %s value: %s",
	                    aname, nc_strerror(retval));
    	        snprintf(abuf,80,"%7.2e",avaldbl);
	            snprintf(buf, BUFSIZ, INSATTR, vname, aname, prim_type_name(atype), abuf, (int)fid, "root");
	        break;

        	default: continue; /* next attribute */
	        }

		printf("statement: '%s'\n", s);
        	if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	            != MAL_SUCCEED )
                goto finish;

	        } /* attr loop */

	    }
	} /* var loop */

	/* Extract global attributes */

	for (aidx = 0; aidx < ngatts; aidx++){
	    if ((retval = nc_inq_attname(ncid,NC_GLOBAL,aidx,aname)))
	        return createException(MAL, "netcdf.attach",
                "Cannot read global attribute %d: %s",
                aidx, nc_strerror(retval));

	    if ((retval = nc_inq_att(ncid,NC_GLOBAL,aname,&atype,&alen)))
	        return createException(MAL, "netcdf.attach",
                "Cannot read global attribute %s type and length: %s",
                aname, nc_strerror(retval));
    	switch ( atype ) {
	        case NC_CHAR:
	            aval = (char *) GDKzalloc(alen + 1);
	            if ((retval = nc_get_att_text(ncid,NC_GLOBAL,aname,aval)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read global attribute %s value: %s",
    	                aname, nc_strerror(retval));
		    fix_quote(aval, alen);
	            aval[alen] = '\0';
	            snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, "string", aval, (int)fid, "root");
	            GDKfree(aval);
	            break;

            case NC_INT:
	            if ((retval = nc_get_att_int(ncid,NC_GLOBAL,aname,&avalint)))
	                return createException(MAL, "netcdf.attach",
			    	    "Cannot read global attribute %s of type %s : %s",
	                    aname, prim_type_name(atype), nc_strerror(retval));
    	        snprintf(abuf,80,"%d",avalint);
	            snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root");
	            break;

    	    case NC_FLOAT:
	            if ((retval = nc_get_att_float(ncid,NC_GLOBAL,aname,&avalfl)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read global attribute %s of type %s: %s",
	                    aname, prim_type_name(atype), nc_strerror(retval));
    	        snprintf(abuf,80,"%7.2f",avalfl);
	            snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root");
	            break;

            case NC_DOUBLE:
    	        if ((retval = nc_get_att_double(ncid,NC_GLOBAL,aname,&avaldbl)))
	                return createException(MAL, "netcdf.attach",
	                    "Cannot read global attribute %s value: %s",
	                    aname, nc_strerror(retval));
	            snprintf(abuf,80,"%7.2e",avaldbl);
    	        snprintf(buf, BUFSIZ, INSATTR, "GLOBAL", aname, prim_type_name(atype), abuf, (int)fid, "root");
	            break;

            default: continue; /* next attribute */
        }

	printf("global: '%s'\n", s);
        if ( ( msg = SQLstatementIntern(cntxt, &s, "netcdf.attach", TRUE, FALSE, NULL))
	          != MAL_SUCCEED )
	        goto finish;

    } /* global attr loop */


 finish:
    nc_close(ncid);

    if (dims != NULL ){
        for (didx = 0; didx < ndims; didx++)
            GDKfree(dims[didx]);
        GDKfree(dims);
    }

	return msg;
}
bool
NETCDFFileObject::ReadAttribute(const char *varname, const char *attname,
    TypeEnum *type, int *ndims, int **dims, void **value)
{
    const char *mName = "NETCDFFileObject::ReadAttribute: ";
    int varid, status;
    int natts = 0;
    bool varvalid = false;

    if(varname == 0)
    {
        varid = NC_GLOBAL;
        if((status = nc_inq_natts(GetFileHandle(), &natts)) == NC_NOERR)
            varvalid = natts > 0;
        else
        {
            debug4 << mName << "0: ";
            HandleError(status);
        }
    }
    else
    {
        // Look up the variable name and gets its variable id.
        varvalid = GetVarId(varname, &varid);
    }

    if(varvalid)
    {
        nc_type atttype;
        size_t  attsize;
        if((status = nc_inq_att(GetFileHandle(), varid, attname, &atttype,
                                &attsize)) == NC_NOERR)
        {
            void *val = 0;
            TypeEnum t = NO_TYPE;

            // Try and read the attribute.
            if(atttype == NC_CHAR)
            {
                char *arr = new char[attsize+1];
                status = nc_get_att_text(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                {
                    // Trim trailing spaces.
                    arr[attsize] = '\0';
                    char *c2 = arr + attsize - 1;
                    while(c2 >= arr && *c2 == ' ')
                        *c2-- = '\0';

                    val = (void*)arr;
                }
                t = CHARARRAY_TYPE;
            }
            else if(atttype == NC_BYTE)
            {
                unsigned char *arr = new unsigned char[attsize+1];
                status = nc_get_att_uchar(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = UCHARARRAY_TYPE;
            }
            else if(atttype == NC_SHORT)
            {
                short *arr = new short[attsize];
                status = nc_get_att_short(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = SHORTARRAY_TYPE;
            } 
            else if(atttype == NC_INT)
            {
                int *arr = new int[attsize];
                status = nc_get_att_int(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = INTEGERARRAY_TYPE;
            } 
            else if(atttype == NC_LONG)
            {
                long *arr = new long[attsize];
                status = nc_get_att_long(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = LONGARRAY_TYPE;
            } 
            else if(atttype == NC_FLOAT)
            {
                float *arr = new float[attsize];
                status = nc_get_att_float(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = FLOATARRAY_TYPE;
            } 
            else if(atttype == NC_DOUBLE)
            {
                double *arr = new double[attsize];
                status = nc_get_att_double(GetFileHandle(), varid, attname, arr);
                if(status != NC_NOERR)
                    delete [] arr;
                else
                    val = (void*)arr;
                t = DOUBLEARRAY_TYPE;
            } 

            if(status == NC_NOERR)
            {
                *type = t;
                *ndims = 1;
                int *d = new int[1];
                d[0] = (int)attsize;
                *dims = d;
                *value = val;
            }
            else
            {
                *type = NO_TYPE;
                *ndims = 0;
                *dims = 0;
                *value = 0;
                debug4 << mName << "3: ";
                HandleError(status);
                varvalid = false;
            }
        }
        else
        {
            varvalid = false;
            debug4 << mName << "4: ";
            HandleError(status);
        }
    }

    return varvalid;
}
예제 #18
0
파일: ncdf.c 프로젝트: cran/ncdf
/* NOTE that space for the attribute must already be allocated! */
void R_nc_get_att_double( int *ncid, int *varid, char **attname, 
			double *attribute, int *retval )
{
	*retval = nc_get_att_double(*ncid, *varid, attname[0], attribute);
}
예제 #19
0
int test_pio_attr(int flag)
{
   /* MPI stuff. */
   int mpi_size, mpi_rank;
   MPI_Comm comm = MPI_COMM_WORLD;
   MPI_Info info = MPI_INFO_NULL;

   /* Netcdf-4 stuff. */
   int ncid;
   int nvid;
   int j, i;

   double rh_range[2];
   static char title[] = "parallel attr to netCDF";
   nc_type    st_type,vr_type;
   size_t     vr_len,st_len;
   size_t     orivr_len;
   double *vr_val;
   char   *st_val;

   /* two dimensional integer data*/
   int dimids[NDIMS1];
   size_t start[NDIMS1];
   size_t count[NDIMS1];
   int *data;
   int *tempdata;

   /* Initialize MPI. */
   MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);

   /* Create a parallel netcdf-4 file. */
/*    nc_set_log_level(NC_TURN_OFF_LOGGING); */
   /*    nc_set_log_level(3);*/

   if (nc_create_par(file_name, facc_type, comm, info, &ncid)) ERR;

   /* Create a 2-D variable so that an attribute can be added. */
   if (nc_def_dim(ncid, "d1", DIMSIZE2, dimids)) ERR;
   if (nc_def_dim(ncid, "d2", DIMSIZE, &dimids[1])) ERR;

   /* Create one var. */
   if (nc_def_var(ncid, "v1", NC_INT, NDIMS1, dimids, &nvid)) ERR;

   orivr_len = 2;
   rh_range[0] = 1.0;
   rh_range[1] = 1000.0;

   /* Write attributes of a variable */

   if (nc_put_att_double (ncid, nvid, "valid_range", NC_DOUBLE,
			  orivr_len, rh_range)) ERR;

   if (nc_put_att_text (ncid, nvid, "title", strlen(title),
			title)) ERR;

   /* Write global attributes */
   if (nc_put_att_double (ncid, NC_GLOBAL, "g_valid_range", NC_DOUBLE,
			  orivr_len, rh_range)) ERR;
   if (nc_put_att_text (ncid, NC_GLOBAL, "g_title", strlen(title), title)) ERR;

   if (nc_enddef(ncid)) ERR;

   /* Set up slab for this process. */
   start[0] = 0;
   start[1] = mpi_rank * DIMSIZE/mpi_size;
   count[0] = DIMSIZE2;
   count[1] = DIMSIZE/mpi_size;

   /* Access parallel */
   if (nc_var_par_access(ncid, nvid, flag)) ERR;

   /* Allocating data */
   data      = malloc(sizeof(int)*count[1]*count[0]);
   tempdata  = data;
   for(j = 0; j < count[0]; j++)
      for (i = 0; i < count[1]; i++)
      {
	 *tempdata = mpi_rank * (j + 1);
	 tempdata++;
      }

   if (nc_put_vara_int(ncid, nvid, start, count, data)) ERR;
   free(data);

   /* Close the netcdf file. */
if (nc_close(ncid)) ERR;

   /* Read attributes */
if (nc_open_par(file_name, facc_type_open, comm, info, &ncid)) ERR;

   /* Set up slab for this process. */
   start[0] = 0;
   start[1] = mpi_rank * DIMSIZE/mpi_size;
   count[0] = DIMSIZE2;
   count[1] = DIMSIZE/mpi_size;

   /* Inquiry variable */
   if (nc_inq_varid(ncid, "v1", &nvid)) ERR;

   /* Access parallel */
   if (nc_var_par_access(ncid, nvid, flag)) ERR;

   /* Inquiry attribute */
   if (nc_inq_att (ncid, nvid, "valid_range", &vr_type, &vr_len)) ERR;

   /* check stuff */
   if(vr_type != NC_DOUBLE || vr_len != orivr_len) ERR;

   vr_val = (double *) malloc(vr_len * sizeof(double));

   /* Get variable attribute values */
   if (nc_get_att_double(ncid, nvid, "valid_range", vr_val)) ERR;

   /* Check variable attribute value */
   for(i = 0; i < vr_len; i++)
      if (vr_val[i] != rh_range[i])
	 ERR_RET;
   free(vr_val);

   /* Inquiry global attribute */
   if (nc_inq_att (ncid, NC_GLOBAL, "g_valid_range", &vr_type, &vr_len)) ERR;

   /* Check stuff. */
   if(vr_type != NC_DOUBLE || vr_len != orivr_len) ERR;

   /* Obtain global attribute value */
   vr_val = (double *) malloc(vr_len * sizeof(double));
   if (nc_get_att_double(ncid, NC_GLOBAL, "g_valid_range", vr_val)) ERR;

   /* Check global attribute value */
   for(i = 0; i < vr_len; i++)
      if (vr_val[i] != rh_range[i]) ERR_RET;
   free(vr_val);

   /* Inquiry string attribute of a variable */
   if (nc_inq_att (ncid, nvid, "title", &st_type, &st_len)) ERR;

   /* check string attribute length */
   if(st_len != strlen(title)) ERR_RET;

   /* Check string attribute type */
   if(st_type != NC_CHAR) ERR_RET;

   /* Allocate meory for string attribute */
   st_val = (char *) malloc(st_len * (sizeof(char)));

   /* Obtain variable string attribute value */
   if (nc_get_att_text(ncid, nvid,"title", st_val)) ERR;

   /*check string value */
   if(strncmp(st_val,title,st_len)) {
      free(st_val);
      ERR_RET;
   }
   free(st_val);

   /*Inquiry global attribute */
   if (nc_inq_att (ncid, NC_GLOBAL, "g_title", &st_type, &st_len)) ERR;

   /* check attribute length*/
   if(st_len != strlen(title)) ERR_RET;

   /*check attribute type*/
   if(st_type != NC_CHAR) ERR_RET;

   /* obtain global string attribute value */
   st_val = (char*)malloc(st_len*sizeof(char));
   if (nc_get_att_text(ncid, NC_GLOBAL,"g_title", st_val)) ERR;

   /* check attribute value */
   if(strncmp(st_val,title,st_len)){
      free(st_val);
      ERR_RET;
   }
   free(st_val);

   /* Close the netcdf file. */
   if (nc_close(ncid)) ERR;

   return 0;
}
예제 #20
0
static void
do_ncdump(const char *path, struct fspec* specp)
{
    int ndims;			/* number of dimensions */
    int nvars;			/* number of variables */
    int ngatts;			/* number of global attributes */
    int xdimid;			/* id of unlimited dimension */
    int dimid;			/* dimension id */
    int varid;			/* variable id */
    struct ncdim dims[NC_MAX_DIMS]; /* dimensions */
    size_t vdims[NC_MAX_DIMS];	/* dimension sizes for a single variable */
    struct ncvar var;		/* variable */
    struct ncatt att;		/* attribute */
    int id;			/* dimension number per variable */
    int ia;			/* attribute number */
    int iv;			/* variable number */
    int is_coord;		/* true if variable is a coordinate variable */
    int ncid;			/* netCDF id */
    vnode* vlist = 0;		/* list for vars specified with -v option */
    int nc_status;		/* return from netcdf calls */

    nc_status = nc_open(path, NC_NOWRITE, &ncid);
    if (nc_status != NC_NOERR) {
	error("%s: %s", path, nc_strerror(nc_status));
    }
    /*
     * If any vars were specified with -v option, get list of associated
     * variable ids
     */
    if (specp->nlvars > 0) {
	vlist = newvlist();	/* list for vars specified with -v option */
	for (iv=0; iv < specp->nlvars; iv++) {
	    NC_CHECK( nc_inq_varid(ncid, specp->lvars[iv], &varid) );
	    varadd(vlist, varid);
	}
    }

    /* if name not specified, derive it from path */
    if (specp->name == (char *)0) {
	specp->name = name_path (path);
    }

    Printf ("netcdf %s {\n", specp->name);
    /*
     * get number of dimensions, number of variables, number of global
     * atts, and dimension id of unlimited dimension, if any
     */
    NC_CHECK( nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
    /* get dimension info */
    if (ndims > 0)
      Printf ("dimensions:\n");
    for (dimid = 0; dimid < ndims; dimid++) {
	NC_CHECK( nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
	if (dimid == xdimid)
	  Printf ("\t%s = %s ; // (%ld currently)\n",dims[dimid].name,
		  "UNLIMITED", (long)dims[dimid].size);
	else
	  Printf ("\t%s = %ld ;\n", dims[dimid].name, (long)dims[dimid].size);
    }

    if (nvars > 0)
	Printf ("variables:\n");
    /* get variable info, with variable attributes */
    for (varid = 0; varid < nvars; varid++) {
	NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims,
			     var.dims, &var.natts) );
	Printf ("\t%s %s", type_name(var.type), var.name);
	if (var.ndims > 0)
	  Printf ("(");
	for (id = 0; id < var.ndims; id++) {
	    Printf ("%s%s",
		    dims[var.dims[id]].name,
		    id < var.ndims-1 ? ", " : ")");
	}
	Printf (" ;\n");

	/* get variable attributes */
	for (ia = 0; ia < var.natts; ia++)
	    pr_att(ncid, varid, var.name, ia); /* print ia-th attribute */
    }


    /* get global attributes */
    if (ngatts > 0)
      Printf ("\n// global attributes:\n");
    for (ia = 0; ia < ngatts; ia++)
	pr_att(ncid, NC_GLOBAL, "", ia); /* print ia-th global attribute */
    
    if (! specp->header_only) {
	if (nvars > 0) {
	    Printf ("data:\n");
	}
	/* output variable data */
	for (varid = 0; varid < nvars; varid++) {
	    /* if var list specified, test for membership */
	    if (specp->nlvars > 0 && ! varmember(vlist, varid))
	      continue;
	    NC_CHECK( nc_inq_var(ncid, varid, var.name, &var.type, &var.ndims,
			    var.dims, &var.natts) );
	    if (specp->coord_vals) {
		/* Find out if this is a coordinate variable */
		is_coord = 0;
		for (dimid = 0; dimid < ndims; dimid++) {
		    if (strcmp(dims[dimid].name, var.name) == 0 &&
			var.ndims == 1) {
			is_coord = 1;
			break;
		    }
		}
		if (! is_coord)	/* don't get data for non-coordinate vars */
		  continue;
	    }
	    /*
	     * Only get data for variable if it is not a record variable,
	     * or if it is a record variable and at least one record has
	     * been written.
	     */
	    if (var.ndims == 0
		|| var.dims[0] != xdimid
		|| dims[xdimid].size != 0) {

		/* Collect variable's dim sizes */
		for (id = 0; id < var.ndims; id++)
		  vdims[id] = dims[var.dims[id]].size;
		var.has_fillval = 1; /* by default, but turn off for bytes */

		/* get _FillValue attribute */
		nc_status = nc_inq_att(ncid,varid,_FillValue,&att.type,&att.len);
		if(nc_status == NC_NOERR &&
		   att.type == var.type && att.len == 1) {
		    if(var.type == NC_CHAR) {
			char fillc;
			NC_CHECK( nc_get_att_text(ncid, varid, _FillValue,
						  &fillc ) );
			var.fillval = fillc;
		    } else {
			NC_CHECK( nc_get_att_double(ncid, varid, _FillValue,
						    &var.fillval) );
		    }
		} else {
		    switch (var.type) {
		    case NC_BYTE:
			/* don't do default fill-values for bytes, too risky */
			var.has_fillval = 0;
			break;
		    case NC_CHAR:
			var.fillval = NC_FILL_CHAR;
			break;
		    case NC_SHORT:
			var.fillval = NC_FILL_SHORT;
			break;
		    case NC_INT:
			var.fillval = NC_FILL_INT;
			break;
		    case NC_FLOAT:
			var.fillval = NC_FILL_FLOAT;
			break;
		    case NC_DOUBLE:
			var.fillval = NC_FILL_DOUBLE;
			break;
		    default:
			break;
		    }
		}
		if (vardata(&var, vdims, ncid, varid, specp) == -1) {
		    error("can't output data for variable %s", var.name);
		    NC_CHECK(
			nc_close(ncid) );
		    if (vlist)
			free(vlist);
		    return;
		}
	    }
	}
    }
    
    Printf ("}\n");
    NC_CHECK(
	nc_close(ncid) );
    if (vlist)
	free(vlist);
}
예제 #21
0
파일: ncdf3.c 프로젝트: cran/ncdf
/***************************************************************************************
 * Given a numeric varid, this reads the data from the file.
 * Does not return on errors.
 */
SEXP R_nc_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 = R_NilValue /* -Wall */, 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_ncu_getListElement( sx_nc, "id" ))[0];

	/*-----------------------------------------------------------------------
	 * 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_ncu_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_nc_get_vara_numvarid: failed to get ndims for var!\n" );

	/*------------------------------------------------------
	 * Get our variable's size, and the start & count to use
	 *-----------------------------------------------------*/
	R_ncu_get_varsize( ncid, varid, ndims, varsize );
	R_ncu_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_nc_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_nc_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);
}
예제 #22
0
/*ARGSUSED*/
int
main(int argc, char *argv[])
{
	int cmode=NC_CLOBBER, omode, ret;
	int	 id;
	char buf[256];
#ifdef SYNCDEBUG
	char *str = "one";
#endif
	int ii;
	size_t ui;
	const struct tcdfvar *tvp = testvars;
	union getret got;
	const size_t initialsz = 8192;
	size_t chunksz = 8192;
	size_t align = 8192/32;

	MPI_Init(&argc, &argv);

        /* cmode |= NC_PNETCDF |NC_64BIT_OFFSET; */
        cmode != NC_PNETCDF |NC_64BIT_DATA;
	ret = nc_create_par(fname,cmode, MPI_COMM_WORLD, MPI_INFO_NULL, &id);
	if(ret != NC_NOERR)  {
		fprintf(stderr,"Error %s in file %s at line %d\n",nc_strerror(ret),__FILE__,__LINE__);
		exit(ret);
        }
	
	assert( nc_put_att_text(id, NC_GLOBAL,
		"TITLE", 12, "another name") == NC_NOERR);
	assert( nc_get_att_text(id, NC_GLOBAL,
		"TITLE", buf) == NC_NOERR);
/*	(void) printf("title 1 \"%s\"\n", buf); */
	assert( nc_put_att_text(id, NC_GLOBAL,
		"TITLE", strlen(fname), fname) == NC_NOERR);
	assert( nc_get_att_text(id, NC_GLOBAL,
		"TITLE", buf) == NC_NOERR);
	buf[strlen(fname)] = 0;
/*	(void) printf("title 2 \"%s\"\n", buf); */
	assert( strcmp(fname, buf) == 0);

	createtestdims(id, NUM_DIMS, sizes, dim_names);
	testdims(id, NUM_DIMS, sizes, dim_names);

	createtestvars(id, testvars, NUM_TESTVARS); 

 	{
 	int ifill = -1; double dfill = -9999;
 	assert( nc_put_att_int(id, Long_id,
 		_FillValue, NC_INT, 1, &ifill) == NC_NOERR);
 	assert( nc_put_att_double(id, Double_id,
 		_FillValue, NC_DOUBLE, 1, &dfill) == NC_NOERR);
 	}

#ifdef REDEF
	assert( nc__enddef(id, 0, align, 0, 2*align) == NC_NOERR );
	assert( nc_put_var1_int(id, Long_id, indices[3], &birthday) 
		== NC_NOERR );
	fill_seq(id);
	assert( nc_redef(id) == NC_NOERR );
/*	assert( nc_rename_dim(id,2, "a long dim name") == NC_NOERR); */
#endif

	assert( nc_rename_dim(id,1, "IXX") == NC_NOERR);
	assert( nc_inq_dim(id, 1, buf, &ui) == NC_NOERR);
	/* (void) printf("dimrename: %s\n", buf); */
	assert( nc_rename_dim(id,1, dim_names[1]) == NC_NOERR);

#ifdef ATTRX
	assert( nc_rename_att(id, 1, "UNITS", "units") == NC_NOERR);
	assert( nc_del_att(id, 4, "FIELDNAM")== NC_NOERR);
	assert( nc_del_att(id, 2, "SCALEMIN")== NC_NOERR);
	assert( nc_del_att(id, 2, "SCALEMAX")== NC_NOERR);
#endif /* ATTRX */

	assert( nc__enddef(id, 0, align, 0, 2*align) == NC_NOERR );

#ifndef REDEF
	fill_seq(id);
	assert( nc_put_var1_int(id, Long_id, indices[3], &birthday)== NC_NOERR );
#endif

	assert( nc_put_vara_schar(id, Byte_id, s_start, s_edges,
		(signed char *)sentence)
		== NC_NOERR);
	assert( nc_put_var1_schar(id, Byte_id, indices[6], (signed char *)(chs+1))
		== NC_NOERR);
	assert( nc_put_var1_schar(id, Byte_id, indices[5], (signed char *)chs)
		== NC_NOERR);

	assert( nc_put_vara_text(id, Char_id, s_start, s_edges, sentence)
		== NC_NOERR);
	assert( nc_put_var1_text(id, Char_id, indices[6], (chs+1))
		== NC_NOERR) ;
	assert( nc_put_var1_text(id, Char_id, indices[5], chs)
		== NC_NOERR);

	assert( nc_put_var1_short(id, Short_id, indices[4], shs)
		== NC_NOERR);

	assert( nc_put_var1_float(id, Float_id, indices[2], &e)
		== NC_NOERR);

	assert( nc_put_var1_double(id, Double_id, indices[1], &zed)
		== NC_NOERR);
	assert( nc_put_var1_double(id, Double_id, indices[0], &pinot)
		== NC_NOERR);


#ifdef SYNCDEBUG
	(void) printf("Hit Return to sync\n");
	gets(str);
	nc_sync(id,0);
	(void) printf("Sync done. Hit Return to continue\n");
	gets(str);
#endif /* SYNCDEBUG */

	ret = nc_close(id);
	/* (void) printf("nc_close ret = %d\n\n", ret); */


/*
 *	read it
 */
        omode = NC_NOWRITE;
        omode = NC_NOWRITE | NC_PNETCDF;
	if(ret != NC_NOERR)
	{
   	    (void) printf("Could not open %s: %s\n", fname,
			nc_strerror(ret));
   	    exit(1);
	}
	/* (void) printf("reopen id = %d for filename %s\n", */
	/* 	id, fname); */

	/*	NC	*/ 
	/* (void) printf("NC "); */
	assert( nc_inq(id, &(cdesc->num_dims), &(cdesc->num_vars),
		&(cdesc->num_attrs), &(cdesc->xtendim) ) == NC_NOERR);
	assert((size_t) cdesc->num_dims == num_dims);
	assert(cdesc->num_attrs == 1);
	assert(cdesc->num_vars == NUM_TESTVARS);
	/* (void) printf("done\n"); */
	
	/*	GATTR	*/
	/* (void) printf("GATTR "); */

	assert( nc_inq_attname(id, NC_GLOBAL, 0, adesc->mnem) == 0);
	assert(strcmp("TITLE",adesc->mnem) == 0);
	assert( nc_inq_att(id, NC_GLOBAL, adesc->mnem, &(adesc->type), &(adesc->len))== NC_NOERR);
	assert( adesc->type == NC_CHAR );
	assert( adesc->len == strlen(fname) );
	assert( nc_get_att_text(id, NC_GLOBAL, "TITLE", buf)== NC_NOERR);
	buf[adesc->len] = 0;
	assert( strcmp(fname, buf) == 0);

	/*	VAR	*/
	/* (void) printf("VAR "); */
	assert( cdesc->num_vars == NUM_TESTVARS );

	for(ii = 0; ii < cdesc->num_vars; ii++, tvp++ ) 
	{
		int jj;
		assert( nc_inq_var(id, ii,
			vdesc->mnem,
			&(vdesc->type),
			&(vdesc->ndims),
			vdesc->dims,
			&(vdesc->num_attrs)) == NC_NOERR);
		if(strcmp(tvp->mnem , vdesc->mnem) != 0)
		{
			(void) printf("attr %d mnem mismatch %s, %s\n",
				ii, tvp->mnem, vdesc->mnem);
			continue;
		}
		if(tvp->type != vdesc->type)
		{
			(void) printf("attr %d type mismatch %d, %d\n",
				ii, (int)tvp->type, (int)vdesc->type);
			continue;
		}
		for(jj = 0; jj < vdesc->ndims; jj++ )
		{
			if(tvp->dims[jj] != vdesc->dims[jj] )
			{
		(void) printf(
		"inconsistent dim[%d] for variable %d: %d != %d\n",
		jj, ii, tvp->dims[jj], vdesc->dims[jj] );
			continue;
			}
		}

		/* VATTR */
		/* (void) printf("VATTR\n"); */
		for(jj=0; jj<vdesc->num_attrs; jj++ ) 
		{
			assert( nc_inq_attname(id, ii, jj, adesc->mnem) == NC_NOERR);
			if( strcmp(adesc->mnem, reqattr[jj]) != 0 )
			{
				(void) printf("var %d attr %d mismatch %s != %s\n",
					ii, jj, adesc->mnem, reqattr[jj] );
				break;
			}
		}

		if( nc_inq_att(id, ii, reqattr[0], &(adesc->type), &(adesc->len))
			!= -1) {
		assert( adesc->type == NC_CHAR );
		assert( adesc->len == strlen(tvp->units) );
	 	assert( nc_get_att_text(id,ii,reqattr[0],buf)== NC_NOERR); 
		buf[adesc->len] = 0;
		assert( strcmp(tvp->units, buf) == 0);
		}

		if(
			nc_inq_att(id, ii, reqattr[1], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len == 1 );
	 	assert( nc_get_att_double(id, ii, reqattr[1], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->validmin);
		}

		if(
			nc_inq_att(id, ii, reqattr[2], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len == 1 );
	 	assert( nc_get_att_double(id, ii, reqattr[2], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->validmax);
		}

		if(
			nc_inq_att(id, ii, reqattr[3], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len ==1 );
	 	assert( nc_get_att_double(id, ii, reqattr[3], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->scalemin);
		}

		if(
			nc_inq_att(id, ii, reqattr[4], &(adesc->type), &(adesc->len))
			!= -1)
		{
		assert( adesc->type == NC_DOUBLE );
		assert( adesc->len == 1 );
	 	assert( nc_get_att_double(id, ii, reqattr[4], &got.dbl)== NC_NOERR);
		chkgot(adesc->type, got, tvp->scalemax);
		}

		if( nc_inq_att(id, ii, reqattr[5], &(adesc->type), &(adesc->len))== NC_NOERR)
		{
		assert( adesc->type == NC_CHAR );
		assert( adesc->len == strlen(tvp->fieldnam) );
	 	assert( nc_get_att_text(id,ii,reqattr[5],buf)== NC_NOERR); 
		buf[adesc->len] = 0;
		assert( strcmp(tvp->fieldnam, buf) == 0);
		}
	}

	/* (void) printf("fill_seq "); */
	check_fill_seq(id);
	/* (void) printf("Done\n"); */

	assert( nc_get_var1_double(id, Double_id, indices[0], &got.dbl)== NC_NOERR);
	/* (void) printf("got val = %f\n", got.dbl ); */

	assert( nc_get_var1_double(id, Double_id, indices[1], &got.dbl)== NC_NOERR);
	/* (void) printf("got val = %f\n", got.dbl ); */

	assert( nc_get_var1_float(id, Float_id, indices[2], &got.fl[0])== NC_NOERR);
	/* (void) printf("got val = %f\n", got.fl[0] ); */

	assert( nc_get_var1_int(id, Long_id, indices[3], &got.in[0])== NC_NOERR);
	/* (void) printf("got val = %d\n", got.in[0] ); */

	assert( nc_get_var1_short(id, Short_id, indices[4], &got.sh[0])== NC_NOERR);
	/* (void) printf("got val = %d\n", got.sh[0] ); */

	assert( nc_get_var1_text(id, Char_id, indices[5], &got.by[0]) == NC_NOERR);
	/* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */
		 /* got.by[0] , got.by[0]); */

	assert( nc_get_var1_text(id, Char_id, indices[6], &got.by[0]) == NC_NOERR);
	/* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */
	/* 	 got.by[0], got.by[0] ); */

	(void) memset(buf,0,sizeof(buf));
	assert( nc_get_vara_text(id, Char_id, s_start, s_edges, buf) == NC_NOERR);
	/* (void) printf("got NC_CHAR val = \"%s\"\n", buf); */

	assert( nc_get_var1_schar(id, Byte_id, indices[5],
			(signed char *)&got.by[0])== NC_NOERR);
	/* (void) printf("got val = %c (0x%02x) \n", got.by[0] , got.by[0]); */

	assert( nc_get_var1_schar(id, Byte_id, indices[6],
			(signed char *)&got.by[0])== NC_NOERR);
	/* (void) printf("got val = %c (0x%02x) \n", got.by[0], got.by[0] ); */

	(void) memset(buf,0,sizeof(buf));
	assert( nc_get_vara_schar(id, Byte_id, s_start, s_edges,
			(signed char *)buf)== NC_NOERR );
	/* (void) printf("got val = \"%s\"\n", buf); */

	{
		double dbuf[NUM_RECS * SIZE_1 * SIZE_2];
		assert(nc_get_var_double(id, Float_id, dbuf) == NC_NOERR);
		/* (void) printf("got vals = %f ... %f\n", dbuf[0], */
		/* 	 dbuf[NUM_RECS * SIZE_1 * SIZE_2 -1] ); */
	}

	ret = nc_close(id);
	/* (void) printf("re nc_close ret = %d\n", ret); */

	MPI_Finalize();
	return 0;
}
예제 #23
0
int NETCDF_setup(coordinateInfo *trajInfo, int *actualAtoms) {
#ifdef BINTRAJ
  int err,spatial,i;
  netcdfTrajectoryInfo *NCInfo;
  char *filename;
#  ifdef MPI
  MPI_Offset ist;
#  else
  size_t ist;
#  endif

  if (prnlev>0) fprintf(stdout,"NETCDF_setup(): Setting up %s\n",trajInfo->filename);

  NCInfo=trajInfo->NCInfo;
  if (NCInfo == NULL) return 1;

  filename=trajInfo->filename;

  /* DAN ROE: For DEBUG of netcdf files, prints what vars are stored */
  if (prnlev>3) dan_netcdf_debug(NCInfo->ncid);

  /*
   *  Get global attributes (after initializing a structure to hold the data), 
   */
  trajInfo->title =           netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "title");
  trajInfo->application =     netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "application");
  trajInfo->program =         netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "program");
  trajInfo->version =         netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "programVersion");
  NCInfo->Conventions =       netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "Conventions");
  NCInfo->ConventionVersion = netcdfGetAttributeText(NCInfo->ncid, NC_GLOBAL, "ConventionVersion");
  if (strstr(NCInfo->Conventions, "AMBER") == NULL) {
    printfone("WARNING: NetCDF file has Conventions that do not include the string \"AMBER\"\n");
  }
  if (strcmp(NCInfo->ConventionVersion, "1.0") != 0) {
    printfone("WARNING: NetCDF file has ConventionVersion differing from \"1.0\"\n");
  }

  /*
   *  get the NetCDF dimension ID's and sizes for the frames, spatial and atoms
   */
    
  NCInfo->frameDID   = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_FRAME, &(trajInfo->stop));
  NCInfo->spatialDID = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_SPATIAL, &spatial);
  NCInfo->atomDID    = netcdfGetDimensionInfo(NCInfo->ncid, AMBER_NETCDF_ATOM, actualAtoms);

  if (spatial != 3) {
    printfone("ptraj cannot handle NetCDF files with other than 3 dims\n");
    return 1;
  }

  /*
   *  perform a sanity check on time variable and units.
   * DAN ROE: Should errors here really terminate ptraj?
   */
  err =    nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_TIME, &NCInfo->timeVID);
  if (err != NC_NOERR) {
    printfone("Error: NetCDF time variable: %s", nc_strerror(err));
    return 1;
  }
  //  error(ROUTINE, "NetCDF time variable, error: %s", nc_strerror(err));

  err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->timeVID, &i);
  if ( err != NC_NOERR ) {
    printfone("Error: Getting number of time attributes in NetCDF file %s\n", filename);
    return 1;
  }
  //  error(ROUTINE, "Getting number of time attributes in NetCDF file %s\n", filename);
  if ( i != 1 ) {
    printfone("Error: Only one time attribute is expected in NetCDF file %s\n", filename);
    return 1;
  }
  //  error(ROUTINE, "Only one time attribute is expected in NetCDF file %s\n", filename);

  err =    nc_inq_attlen(NCInfo->ncid, NCInfo->timeVID, "units", &ist);
  if (err != NC_NOERR) {
    printfone("Error: Grabbing time units attribute length in NetCDF file: %s\n", 
              nc_strerror(err));
    return 1;
  }
  NCInfo->timeUnits = (char *) safe_malloc(sizeof(char) * (ist+1));

  err =    nc_get_att_text(NCInfo->ncid, NCInfo->timeVID, "units", NCInfo->timeUnits);
  if (err != NC_NOERR) {
    printfone("Error: Could not get time units from NetCDF file %s: %s", 
              filename, nc_strerror(err));
    safe_free(NCInfo->timeUnits);
    return 1;
  }
  if (strcmp("picosecond",NCInfo->timeUnits) != 0)
    printfone("WARNING: Expecting time units in picoseconds, got -%s-\n", NCInfo->timeUnits);

  err =    nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_SPATIAL, &NCInfo->spatialVID);
  if (err != NC_NOERR) {
    printfone("Error: Getting spatialVID in the NetCDF file %s: %s\n", 
            filename, nc_strerror(err));
    return 1;
  }

  /*
   *  NETCDF: check to see what trajectory data is within the NetCDF file
   *  and perform sanity checks...
   *
   *  ARE COORDINATES PRESENT?
   */ 
    err =    nc_inq_varid(NCInfo->ncid, AMBER_NETCDF_COORDS, &NCInfo->coordinateVID);
    if (err != NC_NOERR) {
      printfone("Error: No coordinates are present in the NetCDF file %s\n", filename);
      return 1;
    } 

    err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->coordinateVID, &i);
    if ( err != NC_NOERR ) {
      printfone("Error: Getting number of coordinate attributes in NetCDF file %s\n", filename);
      return 1;
    }
    if ( i != 1 ) {
      printfone("Error: Only a single coordinate attribute is expected in NetCDF file %s\n", 
                filename);
      return 1;
    }

    err =    nc_inq_attlen(NCInfo->ncid, NCInfo->coordinateVID, "units", &ist);
    if (err != NC_NOERR) {
      printfone("Error: Getting coordinateVID attribute length. %s\n",nc_strerror(err));
      return 1;
    }    
    NCInfo->coordinateUnits = (char *) safe_malloc(sizeof(char) * (ist+1));

    err =    nc_get_att_text(NCInfo->ncid, NCInfo->coordinateVID, "units", NCInfo->coordinateUnits);
    if (err != NC_NOERR) {
      printfone("Error: Could not get coordinate units from NetCDF file %s", filename);
      safe_free(NCInfo->coordinateUnits);
      return 1;
    }
    if (strcmp("angstrom",NCInfo->coordinateUnits) != 0)
      printfone("WARNING: Expecting coordinate units in angstroms, got %s\n", 
                NCInfo->coordinateUnits);

  /*
   *  ARE CELL_LENGTHS (i.e. box info) PRESENT?
   */ 
    err =    nc_inq_varid(NCInfo->ncid, "cell_angles", &NCInfo->cellAngleVID);
    if ((err != NC_NOERR)&&(prnlev>0)) 
      printfone("Warning: NetCDF cell angle variable ID: %s\n", nc_strerror(err));
    err =    nc_inq_varid(NCInfo->ncid, "cell_lengths", &NCInfo->cellLengthVID);
    if ((err != NC_NOERR)&&(prnlev>0)) 
      printfone("Warning: NetCDF cell length variable ID: %s\n", nc_strerror(err));

    // Set up box information
    if (err == NC_NOERR) {
      // Angle information
      err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->cellAngleVID, &i);
      if ( i > 0 ) {
        err =    nc_inq_attlen(NCInfo->ncid, NCInfo->cellAngleVID, "units", &ist);
        if (err == NC_NOERR) {
          NCInfo->cellAngleUnits = (char *) safe_malloc(sizeof(char) * (ist+1));
          err=nc_get_att_text(NCInfo->ncid, NCInfo->cellAngleVID, "units", NCInfo->cellAngleUnits);
        }
      }

      // Cell length information
      err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->cellLengthVID, &i);
      if ( i > 0 ) {
        err =    nc_inq_attlen(NCInfo->ncid, NCInfo->cellLengthVID, "units", &ist);
        if (err == NC_NOERR) {
          NCInfo->cellLengthUnits = (char *) safe_malloc(sizeof(char) * (ist+1));
          err=nc_get_att_text(NCInfo->ncid, NCInfo->cellLengthVID, "units", 
                              NCInfo->cellLengthUnits);
        }
      }
      trajInfo->isBox = 1;
    } // End box information setup

  /*
   *  ARE VELOCITIES PRESENT?
   */ 

    err =    nc_inq_varid(NCInfo->ncid, "velocities", &NCInfo->velocityVID);
    if (err == NC_NOERR) {
      trajInfo->isVelocity = 1;
      err =    nc_inq_varnatts(NCInfo->ncid, NCInfo->velocityVID, &i);
      if ( i > 1 ) {
        err =    nc_inq_attlen(NCInfo->ncid, NCInfo->velocityVID, "units", &ist);
        if (err == NC_NOERR) {
          NCInfo->velocityUnits = (char *) safe_malloc(sizeof(char) * (ist+1));
          err = nc_get_att_text(NCInfo->ncid, NCInfo->velocityVID, "units", NCInfo->velocityUnits);
        }
        err = nc_get_att_double(NCInfo->ncid, NCInfo->velocityVID, "scale_factor", 
                                &NCInfo->velocityScale);
      }
    }

    /*
     * Are replica temperatures present?
     */
    err=   nc_inq_varid(NCInfo->ncid,"temp0",&NCInfo->TempVarID);
    if (err == NC_NOERR) {
      if (prnlev>0) printfone("\nNetCDF file has replica temperatures.\n");
    } else {
      if (prnlev>0) printfone("\nNetCDF file does not have replica temperatures.\n");
      NCInfo->TempVarID=-1;
    }

  return 0;
#endif //BINTRAJ

  return 1;
}
예제 #24
0
NCstate NCdsHandleGContDefine(NCdsHandleGCont_t *gCont, int *ncids, size_t n) {
    int status, varid, i;
    int missingInt, fillInt;
    double missingFloat, fillFloat, scale, offset;
    size_t unitlen, row, col;
    char unitstr[NC_MAX_NAME], gunitstr[NC_MAX_NAME];

    gCont->Data = (double *) NULL;
    gCont->AuxData = (double *) NULL;
    gCont->ObsNum = (size_t *) NULL;
    gCont->MeanIds = gCont->MinIds = gCont->MaxIds = gCont->StdIds = (int *) NULL;

    if (n < 1) return (NCfailed);
    if (NCdsHandleGridDefine((NCdsHandleGrid_t *) gCont, ncids, n) == NCfailed) return (NCfailed);

    if (gCont->DataType != NCtypeGCont) {
        CMmsgPrint(CMmsgAppError, "Invalid grid data in: %s %d", __FILE__, __LINE__);
        NCdsHandleGridClear((NCdsHandleGrid_t *) gCont);
        return (NCfailed);
    }
    if (((gCont->MeanIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->MinIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->MaxIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->StdIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) ||
        ((gCont->Data = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) ||
        ((gCont->AuxData = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) ||
        ((gCont->ObsNum = (size_t *) calloc(gCont->ColNum * gCont->RowNum, sizeof(size_t))) == (size_t *) NULL)) {
        CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__);
        if (gCont->MeanIds != (int *) NULL) free(gCont->MeanIds);
        if (gCont->MinIds != (int *) NULL) free(gCont->MinIds);
        if (gCont->MaxIds != (int *) NULL) free(gCont->MaxIds);
        if (gCont->StdIds != (int *) NULL) free(gCont->StdIds);
        NCdsHandleGridClear((NCdsHandleGrid_t *) gCont);
        return (NCfailed);
    }
    for (i = 0; i < n; ++i) gCont->MeanIds[i] = gCont->MinIds[i] = gCont->MaxIds[i] = gCont->StdIds[i] = NCundefined;

    for (i = 0; i < n; ++i) {
        switch (gCont->GType) {
            default:
                gCont->FillValue.Float = gCont->MissingVal.Float = FLOAT_NOVALUE;
                break;
            case NC_BYTE:
            case NC_SHORT:
            case NC_INT:
                if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillInt)) !=
                    NC_NOERR) {
                    if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                 &missingInt)) != NC_NOERR)
                        missingInt = fillInt = INT_NOVALUE;
                    else fillInt = missingInt;
                }
                else if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                  &missingInt)) != NC_NOERR)
                    missingInt = fillInt;
                break;
            case NC_FLOAT:
            case NC_DOUBLE:
                if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillFloat)) !=
                    NC_NOERR) {
                    if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                    &missingFloat)) != NC_NOERR)
                        missingFloat = fillFloat = FLOAT_NOVALUE;
                    else
                        fillFloat = missingFloat;
                }
                else if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal,
                                                     &missingFloat)) != NC_NOERR)
                    missingFloat = fillFloat;
                break;
        }
        if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAScaleFactor, &scale)) !=
            NC_NOERR)
            scale = 1.0;
        if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAAddOffset, &offset)) !=
            NC_NOERR)
            offset = 0.0;
        if (((status = nc_inq_attlen(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, &unitlen)) == NC_NOERR) &&
            ((status = nc_get_att_text(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, unitstr)) == NC_NOERR))
            unitstr[unitlen] = '\0';
        if (i == 0) {
            if ((status == NC_NOERR) && (utScan(unitstr, &(gCont->GUnit)) == 0)) {
                gCont->DoGUnit = true;
                strcpy (gunitstr, unitstr);
            }
            else gCont->DoGUnit = false;
            switch (gCont->GType) {
                case NC_BYTE:
                case NC_SHORT:
                case NC_INT:
                    gCont->FillValue.Int = fillInt;
                    gCont->MissingVal.Int = missingInt;
                    break;
                default:
                case NC_FLOAT:
                case NC_DOUBLE:
                    gCont->FillValue.Float = fillFloat;
                    gCont->MissingVal.Float = missingFloat;
                    break;
            }
            gCont->Scale = scale;
            gCont->Offset = offset;
        }
        else {
            if (gCont->DoGUnit && ((status != NC_NOERR) || strcmp(unitstr, gunitstr) != 0)) {
                CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (units) in: %s %d", __FILE__, __LINE__);
                return (NCfailed);
            }
            switch (gCont->GType) {
                case NC_BYTE:
                case NC_SHORT:
                case NC_INT:
                    if ((gCont->FillValue.Int != fillInt) || (gCont->MissingVal.Int != missingInt)) {
                        CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (int fill value) in: %s %d", __FILE__,
                                   __LINE__);
                        return (NCfailed);
                    }
                    break;
                default:
                case NC_FLOAT:
                case NC_DOUBLE:
                    if ((NCmathEqualValues(gCont->FillValue.Float, fillFloat) == false) ||
                        (NCmathEqualValues(gCont->MissingVal.Float, missingFloat) == false)) {
                        CMmsgPrint(CMmsgAppError, "Inconsistent bundle (float fill value) in: %s %d", __FILE__,
                                   __LINE__);
                        return (NCfailed);
                    }
                    break;
            }
            if ((NCmathEqualValues(gCont->Scale, scale) == false) ||
                (NCmathEqualValues(gCont->Offset, offset) == false)) {
                CMmsgPrint(CMmsgAppError, "Inconsistent bundle (scale and offset) in: %s %d", __FILE__, __LINE__);
                return (NCfailed);
            }
        }
        gCont->MeanIds[i] = nc_inq_varid(ncids[i], NCnameVAAverage, &varid) == NC_NOERR ? varid : NCundefined;
        gCont->MaxIds[i] = nc_inq_varid(ncids[i], NCnameVAMaximum, &varid) == NC_NOERR ? varid : NCundefined;
        gCont->MinIds[i] = nc_inq_varid(ncids[i], NCnameVAMinimum, &varid) == NC_NOERR ? varid : NCundefined;
        gCont->StdIds[i] = nc_inq_varid(ncids[i], NCnameVAStdDev, &varid) == NC_NOERR ? varid : NCundefined;
    }
    for (row = 0; row < gCont->RowNum; row++)
        for (col = 0; col < gCont->ColNum; col++)
            NCdsHandleGContSetFill(gCont, row, col);
    return (NCsucceeded);
}