Esempio n. 1
0
File: v2i.c Progetto: stcorp/harp
int
ncvarget1(
    int		ncid,
    int		varid,
    const long*	index,
    void*	value
)
{
	NDIMS_DECL
	A_DECL(coordp, size_t, ndims, index);
	A_INIT(coordp, size_t, ndims, index);
	{
	const int status = nc_get_var1(ncid, varid, coordp, value);
	A_FREE(coordp);
	if(status != NC_NOERR)
	{
		nc_advise("ncdimid", status, "ncid %d", ncid);
		return -1;
	}
	}
	return 0;
}
Esempio n. 2
0
/*+++++++++++++++++++++++++
.IDENTifer   SCIA_RD_NC_H2O_REC
.PURPOSE     read records from IMLM-H2O product in netCDF-4 (ADAGUC standard)
.INPUT/OUTPUT
  call as   numRec = SCIA_RD_NC_H2O_REC( ncid, &rec );
     input:
            int ncid              :  netCDF file ID
    output:
	    struct imlm_rec **rec :  IMLM-H2O records

.RETURNS     number of IMLM-H2O records (unsigned int)
.COMMENTS    static function
-------------------------*/
unsigned int SCIA_RD_NC_H2O_REC( int ncid, struct imlm_rec **rec_out )
{
     register unsigned int ni, nr;

     unsigned int numRec = 0;

     int    retval;
     int    time_id;
     int    var_id;
     size_t indx, length;

     float  *rbuff = NULL;
     double *dbuff = NULL;

     struct imlm_rec *rec = NULL;

     const size_t nr_byte = NUM_CORNERS * sizeof(float);

     rec_out[0] = NULL;
/*
 * get size of dimension scale "time"
 */
     if ( (retval = nc_inq_dimid( ncid, "time", &time_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     if ( (retval = nc_inq_dimlen( ncid, time_id, &length )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     numRec = (unsigned int) length;

     rec = (struct imlm_rec *) malloc( numRec * sizeof(struct imlm_rec) );
     if ( rec == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rec" );
/*
 * read Julian date of measurements
 */
     dbuff = (double *) malloc( numRec * sizeof(double) );
     if ( dbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "dbuff" );

     if ( (retval = nc_inq_varid( ncid, "time", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_double( ncid, var_id, dbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].dsr_time = dbuff[nr];
/*
 * read longitude and latitude of measurements
 */
     rbuff = (float *) malloc( numRec * sizeof(float) );
     if ( rbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rbuff" );

     if ( (retval = nc_inq_varid( ncid, "lon", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].lon_center = rbuff[nr];

     if ( (retval = nc_inq_varid( ncid, "lat", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].lat_center = rbuff[nr];
/*
 * read datasets (H2O, CH4)
 */
     if ( (retval = nc_inq_varid( ncid, "H2O", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].H2O = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "H2O_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].H2O_err = rbuff[nr];

     if ( (retval = nc_inq_varid( ncid, "CH4", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].CH4 = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "CH4_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].CH4_err = rbuff[nr];
#ifdef _IMLM_WHOLE_PRODUCT                /* additional species H2O, N2O */
     if ( (retval = nc_inq_varid( ncid, "H2O", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].H2O = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "H2O_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].H2O_err = rbuff[nr];

     if ( (retval = nc_inq_varid( ncid, "N2O", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].N2O = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "N2O_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].N2O_err = rbuff[nr];
#endif
     if ( (retval = nc_inq_varid( ncid, "albedo", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].albedo = rbuff[nr];

     retval = nc_inq_varid( ncid, "cloudFraction", &var_id );
     if ( retval != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].cl_fr = rbuff[nr];

     retval = nc_inq_varid( ncid, "meanElevation", &var_id );
     if ( retval != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].mean_elev = rbuff[nr];
/*
 * read longitude and latitude bounding boxes
 */
     rbuff = (float *) realloc( rbuff, NUM_CORNERS * numRec * sizeof(float) );
     if ( rbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rbuff" );

     if ( (retval = nc_inq_varid( ncid, "lon_bnds", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( ni = nr = 0; nr < numRec; nr++, ni += NUM_CORNERS )
	  (void) memcpy( rec[nr].lon_corner, rbuff+ni, nr_byte );

     if ( (retval = nc_inq_varid( ncid, "lat_bnds", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( ni = nr = 0; nr < numRec; nr++, ni += NUM_CORNERS )
	  (void) memcpy( rec[nr].lat_corner, rbuff+ni, nr_byte );
/*
 * read pixel meta-data as compound dataset
 */
     retval = nc_inq_varid( ncid, "tile_properties", &var_id );
     if ( retval != NC_NOERR ) 
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     for ( indx = 0; indx < (size_t) numRec; indx++ ) {
	  retval = nc_get_var1( ncid, var_id, &indx, &rec[indx].meta );
     }

     free( rbuff );
     free( dbuff );
     rec_out[0] = rec;
     return numRec;
 done:
     if ( rec != NULL ) free( rec );
     if ( rbuff != NULL ) free( rbuff );
     if ( dbuff != NULL ) free( dbuff );
     return 0;
}
Esempio n. 3
0
int
nc3d_getvarmx(int ncid, int varid,
	    const size_t *start,
	    const size_t *edges,
	    const ptrdiff_t* stride,
 	    const ptrdiff_t* map,
	    void* data,
	    nc_type dsttype0)
{
    NCerror ncstat = NC_NOERR;
    int i;
    NC* drno;
    NC* substrate;
    NC3_INFO* substrate3;
    NCDAPCOMMON* dapcomm;
    NC_var* var;
    CDFnode* cdfvar; /* cdf node mapping to var*/
    NClist* varnodes;
    nc_type dsttype;
    size_t externsize;
    size_t dimsizes[NC_MAX_VAR_DIMS];
    Dapodometer* odom = NULL;
    unsigned int ncrank;
    NClist* ncdims = NULL;
    size_t nelems;
#ifdef NEWVARM
    char* localcopy; /* of whole variable */
#endif

    ncstat = NC_check_id(ncid, (NC**)&drno);
    if(ncstat != NC_NOERR) goto done;
    dapcomm = (NCDAPCOMMON*)drno->dispatchdata;

    ncstat = NC_check_id(drno->substrate, &substrate);
    if(ncstat != NC_NOERR) goto done;
    substrate3 = (NC3_INFO*)drno->dispatchdata;

    var = NC_lookupvar(substrate3,varid);
    if(var == NULL) {ncstat = NC_ENOTVAR; goto done;}

    /* Locate var node via varid */
    varnodes = dapcomm->cdf.ddsroot->tree->varnodes;
    for(i=0;i<nclistlength(varnodes);i++) {
	CDFnode* node = (CDFnode*)nclistget(varnodes,i);
	if(node->array.basevar == NULL
           && node->nctype == NC_Atomic
           && node->ncid == varid) {
	    cdfvar = node;
	    break;
	}
    }

    ASSERT((cdfvar != NULL));
    ASSERT((strcmp(cdfvar->ncfullname,var->name->cp)==0));

    if(nclistlength(cdfvar->array.dimsetplus) == 0) {
       /* The variable is a scalar; consequently, there is only one
          thing to get and only one place to put it. */
	/* recurse with additional parameters */
        return THROW(nc3d_getvarx(ncid,varid,
		 NULL,NULL,NULL,
		 data,dsttype0));
    }
         
    dsttype = (dsttype0);

    /* Default to using the inquiry type for this var*/
    if(dsttype == NC_NAT) dsttype = cdfvar->externaltype;

    /* Validate any implied type conversion*/
    if(cdfvar->etype != dsttype && dsttype == NC_CHAR) {
	/* The only disallowed conversion is to/from char and non-byte
           numeric types*/
	switch (cdfvar->etype) {
	case NC_STRING: case NC_URL:
	case NC_CHAR: case NC_BYTE: case NC_UBYTE:
 	    break;
	default:
	    return THROW(NC_ECHAR);
	}
    }

    externsize = nctypesizeof(dsttype);

    /* Accumulate the dimension sizes and the total # of elements */
    ncdims = cdfvar->array.dimsetall;
    ncrank = nclistlength(ncdims);

    nelems = 1; /* also Compute the number of elements being retrieved */
    for(i=0;i<ncrank;i++) {
	CDFnode* dim = (CDFnode*)nclistget(ncdims,i);
	dimsizes[i] = dim->dim.declsize;
	nelems *= edges[i];
    }

    /* Originally, this code repeatedly extracted single values
       using get_var1. In an attempt to improve performance,
       I have converted to reading the whole variable at once
       and walking it locally.
    */

#ifdef NEWVARM
    localcopy = (char*)malloc(nelems*externsize);

    /* We need to use the varieties of get_vars in order to
       properly do conversion to the external type
    */

    switch (dsttype) {

    case NC_CHAR:
	ncstat = nc_get_vars_text(ncid,varid,start, edges, stride,
				  (char*)localcopy);
	break;
    case NC_BYTE:
	ncstat = nc_get_vars_schar(ncid,varid,start, edges, stride,
				   (signed char*)localcopy);
	break;
    case NC_SHORT:
	ncstat = nc_get_vars_short(ncid,varid, start, edges, stride,
			  	   (short*)localcopy);
	break;
    case NC_INT:
	ncstat = nc_get_vars_int(ncid,varid,start, edges, stride,
				 (int*)localcopy);
	break;
    case NC_FLOAT:
	ncstat = nc_get_vars_float(ncid,varid,start, edges, stride,
				   (float*)localcopy);
	break;
    case NC_DOUBLE:
	ncstat = nc_get_vars_double(ncid,varid,	start, edges, stride,
		 		    (double*)localcopy);
	break;
    default: break;
    }


    odom = dapodom_new(ncrank,start,edges,stride,NULL);

    /* Walk the local copy */
    for(i=0;i<nelems;i++) {
	size_t voffset = dapodom_varmcount(odom,map,dimsizes);
	void* dataoffset = (void*)(((char*)data) + (externsize*voffset));
	char* localpos = (localcopy + externsize*i);
	/* extract the indexset'th value from local copy */
	memcpy(dataoffset,(void*)localpos,externsize);
/*
fprintf(stderr,"new: %lu -> %lu  %f\n",
	(unsigned long)(i),
        (unsigned long)voffset,
	*(float*)localpos);
*/
	dapodom_next(odom);
    }    
#else
    odom = dapodom_new(ncrank,start,edges,stride,NULL);
    while(dapodom_more(odom)) {
	size_t* indexset = odom->index;
	size_t voffset = dapodom_varmcount(odom,map,dimsizes);
	char internalmem[128];
	char externalmem[128];
	void* dataoffset = (void*)(((char*)data) + (externsize*voffset));

	/* get the indexset'th value using variable's internal type */
	ncstat = nc_get_var1(ncid,varid,indexset,(void*)&internalmem);
        if(ncstat != NC_NOERR) goto done;
	/* Convert to external type */
	ncstat = dapconvert3(cdfvar->etype,dsttype,externalmem,internalmem);
        if(ncstat != NC_NOERR) goto done;
	memcpy(dataoffset,(void*)externalmem,externsize);
/*
fprintf(stderr,"old: %lu -> %lu  %f\n",
	(unsigned long)dapodom_count(odom),
        (unsigned long)voffset,
	*(float*)externalmem);
*/
	dapodom_next(odom);
    }    
#endif

done:
    return ncstat;
}
Esempio n. 4
0
/*+++++++++++++++++++++++++
.IDENTifer   SCIA_RD_NC_HDO_REC
.PURPOSE     read records from IMAP-HDO product in netCDF-4 (ADAGUC standard)
.INPUT/OUTPUT
  call as   numRec = SCIA_RD_NC_HDO_REC( ncid, &rec );
     input:
            int ncid              :  netCDF file ID
    output:
	    struct imap_rec **rec :  IMAP records

.RETURNS     number of IMAP records (unsigned int)
.COMMENTS    static function
-------------------------*/
unsigned int SCIA_RD_NC_HDO_REC( int ncid, struct imap_rec **rec_out )
{
     register unsigned int ni, nr;

     unsigned int numRec = 0;

     int    retval;
     int    time_id;
     int    var_id;
     size_t indx, length;

     float  *rbuff = NULL;
     double *dbuff = NULL;

     struct imap_rec *rec = NULL;

     const size_t nr_byte = NUM_CORNERS * sizeof(float);

     rec_out[0] = NULL;
/*
 * get size of dimension scale "time"
 */
     if ( (retval = nc_inq_dimid( ncid, "time", &time_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     if ( (retval = nc_inq_dimlen( ncid, time_id, &length )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     numRec = (unsigned int) length;

     rec = (struct imap_rec *) malloc( numRec * sizeof(struct imap_rec) );
     if ( rec == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rec" );
/*
 * read Julian date of measurements
 */
     dbuff = (double *) malloc( numRec * sizeof(double) );
     if ( dbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "dbuff" );

     if ( (retval = nc_inq_varid( ncid, "time", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_double( ncid, var_id, dbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].jday = dbuff[nr];
     free( dbuff );
/*
 * read longitude and latitude of measurements
 */
     rbuff = (float *) malloc( numRec * sizeof(float) );
     if ( rbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rbuff" );

     if ( (retval = nc_inq_varid( ncid, "lon", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].lon_center = rbuff[nr];

     if ( (retval = nc_inq_varid( ncid, "lat", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].lat_center = rbuff[nr];
/*
 * read datasets (HDO, HDO_error, H2O, H2O_error, H2O_model, delta_d)
 */
     /*+++++++++++++++++++++++++*/
     if ( (retval = nc_inq_varid( ncid, "H2O", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].h2o_vcd = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "H2O_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].h2o_error = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "H2O_model", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].h2o_model = rbuff[nr];

     /*+++++++++++++++++++++++++*/
     if ( (retval = nc_inq_varid( ncid, "HDO", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].hdo_vcd = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "HDO_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].hdo_error = rbuff[nr];

     /*+++++++++++++++++++++++++*/
     if ( (retval = nc_inq_varid( ncid, "delta_d", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].delta_d = rbuff[nr];
     if ( (retval = nc_inq_varid( ncid, "delta_d_error", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( nr = 0; nr < numRec; nr++ ) rec[nr].delta_d_error = rbuff[nr];
/*
 * read longitude and latitude bounding boxes
 */
     rbuff = (float *) realloc( rbuff, NUM_CORNERS * numRec * sizeof(float) );
     if ( rbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rbuff" );

     if ( (retval = nc_inq_varid( ncid, "lon_bnds", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( ni = nr = 0; nr < numRec; nr++, ni += NUM_CORNERS )
	  (void) memcpy( rec[nr].lon_corner, rbuff+ni, nr_byte );

     if ( (retval = nc_inq_varid( ncid, "lat_bnds", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     retval = nc_get_var_float( ncid, var_id, rbuff );
     for ( ni = nr = 0; nr < numRec; nr++, ni += NUM_CORNERS )
	  (void) memcpy( rec[nr].lat_corner, rbuff+ni, nr_byte );
/*
 * read pixel meta-data as compound dataset
 */
     if ( (retval = nc_inq_varid( ncid, "tile_properties", &var_id )) != NC_NOERR )
	  NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
     for ( indx = 0; indx < (size_t) numRec; indx++ ) {
	  retval = nc_get_var1( ncid, var_id, &indx, &rec[indx].meta );
     }

     rec_out[0] = rec;
     return numRec;
 done:
     if ( rec != NULL ) free( rec );
     if ( rbuff != NULL ) free( rbuff );
     if ( dbuff != NULL ) free( dbuff );
     return 0;
}
Esempio n. 5
0
int mov_session::open(QString openFilename)
{
    int ierr,ncid,i,nrow;
    int dimid_ntimeseries,nTimeseries;
    int varid_filename,varid_colors,varid_units,varid_names;
    int varid_xshift,varid_yshift,varid_type,varid_coldstart;
    int varid_stationfile,varid_plottitle,varid_xlabel,varid_ylabel;
    int varid_startdate,varid_enddate,varid_precision,varid_ymin,varid_ymax;
    int varid_autodate,varid_autoy,varid_checkState;
    const char * mydatachar[1];
    double mydatadouble[1];
    int mydataint[1];
    QMessageBox::StandardButton reply;
    QString filelocation,filename,series_name,color,type;
    QString coldstartstring,stationfile,stationfilepath;
    QString BaseFile,NewFile,TempFile,BaseDir;
    double unitconvert,xshift,yshift;
    size_t temp_size_t;
    size_t start[1];
    QDate tempstartdate,tempenddate;
    QString tempstring;
    QColor CellColor;
    QDateTime ColdStart;
    //ADCNC NetCDFData;
    //ADCASCII ADCData;
    bool continueToLoad,hasCheckInfo;
    Qt::CheckState checkState;


    QFile Session(openFilename);
    if(!Session.exists())
    {
        emit sessionError("File not found");
        return 1;
    }

    //Open the netCDF file
    ierr = mov_generic::NETCDF_ERR(nc_open(openFilename.toUtf8(),NC_NOWRITE,&ncid));
    if(ierr!=NC_NOERR)return 1;

    //Read some of the basics from the file (dimensions, variable IDs)
    ierr = mov_generic::NETCDF_ERR(nc_inq_dimid(ncid,"ntimeseries",&dimid_ntimeseries));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_filename",&varid_filename));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_colors",&varid_colors));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_names",&varid_names));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_filetype",&varid_type));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_units",&varid_units));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_xshift",&varid_xshift));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_yshift",&varid_yshift));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_coldstartdate",&varid_coldstart));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_stationfile",&varid_stationfile));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_plottitle",&varid_plottitle));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_xlabel",&varid_xlabel));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_ylabel",&varid_ylabel));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_precision",&varid_precision));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_startdate",&varid_startdate));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_enddate",&varid_enddate));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_ymin",&varid_ymin));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_ymax",&varid_ymax));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_autodate",&varid_autodate));
    if(ierr!=NC_NOERR)return 1;

    ierr = mov_generic::NETCDF_ERR(nc_inq_varid(ncid,"timeseries_autoy",&varid_autoy));
    if(ierr!=NC_NOERR)return 1;

    ierr = nc_inq_varid(ncid,"timeseries_checkState",&varid_checkState);
    if(ierr!=NC_NOERR)
        hasCheckInfo = false;
    else
        hasCheckInfo = true;

    //Read the scalar variables
    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_plottitle,&mydatachar));
    if(ierr!=NC_NOERR)return 1;
    this->plotTitleWidget->setText(QString(mydatachar[0]));

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_xlabel,&mydatachar));
    if(ierr!=NC_NOERR)return 1;
    this->xLabelWidget->setText(QString(mydatachar[0]));

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_ylabel,&mydatachar));
    if(ierr!=NC_NOERR)return 1;
    this->yLabelWidget->setText(QString(mydatachar[0]));

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_startdate,&mydatachar));
    if(ierr!=NC_NOERR)return 1;
    tempstring = QString(mydatachar[0]);
    tempstartdate = QDateTime::fromString(tempstring,"yyyy-MM-dd hh:mm:ss").date();
    this->startDateEdit->setDate(tempstartdate);

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_enddate,&mydatachar));
    if(ierr!=NC_NOERR)return 1;
    tempstring = QString(mydatachar[0]);
    tempenddate = QDateTime::fromString(tempstring,"yyyy-MM-dd hh:mm:ss").date();
    this->endDateEdit->setDate(tempenddate);

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_ymin,&mydatadouble));
    if(ierr!=NC_NOERR)return 1;
    this->yMinSpinBox->setValue(mydatadouble[0]);

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_ymax,&mydatadouble));
    if(ierr!=NC_NOERR)return 1;
    this->yMaxSpinBox->setValue(mydatadouble[0]);

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_autodate,&mydataint));
    if(ierr!=NC_NOERR)return 1;
    if(mydataint[0]==0)
        this->checkAllData->setChecked(false);
    else
        this->checkAllData->setChecked(true);

    ierr = mov_generic::NETCDF_ERR(nc_get_var(ncid,varid_autoy,&mydataint));
    if(ierr!=NC_NOERR)return 1;
    if(mydataint[0]==0)
        this->checkYAuto->setChecked(false);
    else
        this->checkYAuto->setChecked(true);

    //Next, read in the data and add rows to the table
    ierr = mov_generic::NETCDF_ERR(nc_inq_dimlen(ncid,dimid_ntimeseries,&temp_size_t));
    if(ierr!=NC_NOERR)return 1;
    nTimeseries = static_cast<int>(temp_size_t);
    nrow = 0;

    //Get the location we are currently working in
    mov_generic::splitPath(openFilename,TempFile,this->currentDirectory);

    for(i=0;i<nTimeseries;i++)
    {
        start[0] = static_cast<size_t>(i);

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_filename,start,&mydatachar));
        if(ierr!=NC_NOERR)return 1;
        filelocation = QString(mydatachar[0]);
        mov_generic::splitPath(filelocation,filename,TempFile);

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_names,start,&mydatachar));
        if(ierr!=NC_NOERR)return 1;
        series_name = QString(mydatachar[0]);

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_type,start,&mydatachar));
        if(ierr!=NC_NOERR)return 1;
        type = QString(mydatachar[0]);

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_colors,start,&mydatachar));
        if(ierr!=NC_NOERR)return 1;
        color = QString(mydatachar[0]);

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_units,start,&mydatadouble));
        if(ierr!=NC_NOERR)return 1;
        unitconvert = mydatadouble[0];

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_coldstart,start,&mydatachar));
        if(ierr!=NC_NOERR)return 1;
        coldstartstring = QString(mydatachar[0]);

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_xshift,start,&mydatadouble));
        if(ierr!=NC_NOERR)return 1;
        xshift = mydatadouble[0];

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_yshift,start,&mydatadouble));
        if(ierr!=NC_NOERR)return 1;
        yshift = mydatadouble[0];

        ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_stationfile,start,&mydatachar));
        if(ierr!=NC_NOERR)return 1;
        stationfilepath = QString(mydatachar[0]);
        mov_generic::splitPath(stationfilepath,stationfile,TempFile);

        if(hasCheckInfo)
        {
            ierr = mov_generic::NETCDF_ERR(nc_get_var1(ncid,varid_checkState,start,&mydataint));
            if(mydataint[0]==1)
                checkState = Qt::Checked;
            else
                checkState = Qt::Unchecked;
        }
        else
            checkState = Qt::Checked;

        continueToLoad = false;

        filelocation = this->currentDirectory+"/"+filelocation;
        mov_generic::splitPath(filelocation,BaseFile,BaseDir);


        QFile myfile(filelocation);
        if(!myfile.exists())
        {
            //The file wasn't found where we think it should be. Give the
            //user a chance to specify an alternate data directory
            if(this->alternateFolder==NULL)
            {
                //If we haven't previously specified an alternate folder, inform the user and
                //ask if they want to specify.
                reply = QMessageBox::question((QWidget*)parent(),"File not found",
                    "Data file not found in default location. Would you like to specify another?");
                if(reply==QMessageBox::Yes)
                {

                    //Get an alternate location
                    //this->alternateFolder = QFileDialog::getExistingDirectory(0,"Select Folder",this->previousDirectory);
                    this->alternateFolder = QFileDialog::getExistingDirectory((QWidget*)parent(),"Test",this->previousDirectory);
                    NewFile = this->alternateFolder+"/"+BaseFile;
                    QFile myfile(NewFile);
                    if(!myfile.exists())
                    {
                        continueToLoad = false;
                        emit sessionError("The file "+BaseFile+" was not found and has been skipped.");
                    }
                    else
                    {
                        continueToLoad = true;
                        filelocation = NewFile;
                    }
                }
                else
                    continueToLoad = false;
            }
            else
            {
                //Start by trying the previously specified alternate folder
                NewFile = this->alternateFolder+"/"+BaseFile;
                QFile myfile(NewFile);
                if(!myfile.exists())
                {
                    reply = QMessageBox::question((QWidget*)parent(),"File not found",
                        "File not found in default location. Would you like to specify another?");
                    if(reply==QMessageBox::Yes)
                    {
                        //Get an alternate location
                        this->alternateFolder = QFileDialog::getExistingDirectory((QWidget*)parent(),"Select Folder",this->previousDirectory);
                        NewFile = this->alternateFolder+"/"+BaseFile;
                        QFile myfile(NewFile);
                        if(!myfile.exists())
                        {
                            continueToLoad = false;
                            emit sessionError("The file "+BaseFile+" was not found and has been skipped.");
                        }
                        else
                        {
                            continueToLoad = true;
                            filelocation = NewFile;
                        }
                    }
                    else
                        continueToLoad = false;
                }
                else
                {
                    continueToLoad = true;
                    filelocation = NewFile;
                }
            }
        }
        else
        {
            continueToLoad = true;
        }

        if(type == "ADCIRC")
        {
            mov_generic::splitPath(stationfilepath,BaseFile,BaseDir);
            stationfilepath = this->currentDirectory+"/"+stationfilepath;
            QFile myfile(stationfilepath);
            if(!myfile.exists())
            {
                //The file wasn't found where we think it should be. Give the
                //user a chance to specify an alternate data directory
                if(this->alternateFolder==NULL)
                {
                    //If we haven't previously specified an alternate folder, inform the user and
                    //ask if they want to specify.
                    reply = QMessageBox::question((QWidget*)parent(),"File not found",
                        "Station file not found in default location. Would you like to specify another?");
                    if(reply==QMessageBox::Yes)
                    {
                        //Get an alternate location
                        this->alternateFolder = QFileDialog::getExistingDirectory((QWidget*)parent(),"Select Folder",this->previousDirectory);
                        NewFile = this->alternateFolder+"/"+BaseFile;
                        QFile myfile(NewFile);
                        if(!myfile.exists())
                        {
                            continueToLoad = false;
                            emit sessionError("The file "+BaseFile+" was not found and has been skipped.");
                        }
                        else
                        {
                            continueToLoad = true;
                            stationfilepath = NewFile;
                        }
                    }
                    else
                        continueToLoad = false;
                }
                else
                {
                    //Start by trying the previously specified alternate folder
                    NewFile = this->alternateFolder+"/"+BaseFile;
                    QFile myfile(NewFile);
                    if(!myfile.exists())
                    {
                        reply = QMessageBox::question((QWidget*)parent(),"File not found",
                            "File not found in default location. Would you like to specify another?");
                        if(reply==QMessageBox::Yes)
                        {
                            //Get an alternate location
                            this->alternateFolder = QFileDialog::getExistingDirectory((QWidget*)parent(),"Select Folder",this->previousDirectory);
                            NewFile = this->alternateFolder+"/"+BaseFile;
                            QFile myfile(NewFile);
                            if(!myfile.exists())
                            {
                                continueToLoad = false;
                                emit sessionError("The file "+BaseFile+" was not found and has been skipped.");
                            }
                            else
                            {
                                continueToLoad = true;
                                stationfilepath = NewFile;
                            }
                        }
                        else
                            continueToLoad = false;
                    }
                    else
                    {
                        continueToLoad = true;
                        stationfilepath = NewFile;
                    }
                }
            }
            else
            {
                continueToLoad = true;
            }
        }

        if(continueToLoad)
        {
            //Build the table
            nrow = nrow + 1;
            this->tableWidget->setRowCount(nrow);
            this->tableWidget->setRowCount(nrow);
            this->tableWidget->setItem(nrow-1,0,new QTableWidgetItem(filename));
            this->tableWidget->setItem(nrow-1,1,new QTableWidgetItem(series_name));
            this->tableWidget->setItem(nrow-1,2,new QTableWidgetItem(color));
            this->tableWidget->setItem(nrow-1,3,new QTableWidgetItem(QString::number(unitconvert)));
            this->tableWidget->setItem(nrow-1,4,new QTableWidgetItem(QString::number(xshift)));
            this->tableWidget->setItem(nrow-1,5,new QTableWidgetItem(QString::number(yshift)));
            this->tableWidget->setItem(nrow-1,6,new QTableWidgetItem(filelocation));
            this->tableWidget->setItem(nrow-1,7,new QTableWidgetItem((coldstartstring)));
            this->tableWidget->setItem(nrow-1,8,new QTableWidgetItem(type));
            this->tableWidget->setItem(nrow-1,9,new QTableWidgetItem(stationfile));
            this->tableWidget->setItem(nrow-1,10,new QTableWidgetItem(stationfilepath));
            CellColor.setNamedColor(color);
            this->tableWidget->item(nrow-1,2)->setBackgroundColor(CellColor);
            this->tableWidget->item(nrow-1,0)->setCheckState(checkState);
            ColdStart = QDateTime::fromString(coldstartstring,"yyyy-MM-dd hh:mm:ss");
        }
    }
    ierr = mov_generic::NETCDF_ERR(nc_close(ncid));
    if(ierr!=NC_NOERR)return 1;

    return 0;
}
Esempio n. 6
0
/*+++++++++++++++++++++++++
.IDENTifer   NADC_FRESCO_RD_NC_REC
.PURPOSE     read records from Fresco product in ADAGUC format (netCDF-4)
.INPUT/OUTPUT
  call as   numRec = NADC_FRESCO_RD_NC_REC( ncid, &rec );
     input:
            int ncid                :  netCDF file ID
    output:
            struct fresco_rec **rec :  Fresco records

.RETURNS     Number of records read from product (unsigned int)
.COMMENTS    None
-------------------------*/
unsigned int NADC_FRESCO_RD_NC_REC( int ncid, struct fresco_rec **rec_out )
{
    register unsigned int ni, nr;

    unsigned int numRec = 0u;

    int    retval;
    int    time_id;
    int    var_id;
    size_t indx, length;

    float  *rbuff = NULL;
    double *dbuff = NULL;

    struct fresco_rec *rec = NULL;

    const size_t nr_byte = NUM_CORNERS * sizeof(float);

    rec_out[0] = NULL;
    /*
     * read dimension scale "time"
     */
    if ( (retval = nc_inq_dimid( ncid, "time", &time_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    if ( (retval = nc_inq_dimlen( ncid, time_id, &length )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    numRec = (unsigned int) length;

    rec = (struct fresco_rec *) malloc( numRec * sizeof(struct fresco_rec) );
    if ( rec == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rec" );
    /*
     * read Julian date of measurements
     */
    dbuff = (double *) malloc( numRec * sizeof(double) );
    if ( dbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "dbuff" );

    if ( (retval = nc_inq_varid( ncid, "time", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_double( ncid, var_id, dbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].jday = dbuff[nr];
    free( dbuff );
    /*
     * read longitude and latitude of measurements
     */
    rbuff = (float *) malloc( numRec * sizeof(float) );
    if ( rbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rbuff" );

    if ( (retval = nc_inq_varid( ncid, "lon", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].lon_center = rbuff[nr];

    if ( (retval = nc_inq_varid( ncid, "lat", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].lat_center = rbuff[nr];
    /*
     * read datasets (cloudFraction,cloudFractionError,cloudTopHeight,cloudTopPress,
     *    cloudTopPressError,cloudAlbedo,cloudAlbedoError,surfaceAlbedo,
     *    surfaceHeight,groundPress)
     */
    if ( (retval = nc_inq_varid( ncid, "cloudFraction", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudFraction = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "cloudFractionError", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudFractionError = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "cloudTopHeight", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudTopHeight = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "cloudTopPress", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudTopPress = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "cloudTopPressError", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudTopPressError = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "cloudAlbedo", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudAlbedo = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "cloudAlbedoError", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].cloudAlbedoError = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "surfaceAlbedo", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].surfaceAlbedo = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "surfaceHeight", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].surfaceHeight = rbuff[nr];
    if ( (retval = nc_inq_varid( ncid, "groundPress", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( nr = 0; nr < numRec; nr++ ) rec[nr].groundPress = rbuff[nr];
    /*
     * read longitude and latitude of tile-corners
     */
    rbuff = (float *) realloc( rbuff, NUM_CORNERS * numRec * sizeof(float) );
    if ( rbuff == NULL ) NADC_GOTO_ERROR( NADC_ERR_ALLOC, "rbuff" );

    if ( (retval = nc_inq_varid( ncid, "lon_bnds", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( ni = nr = 0; nr < numRec; nr++, ni += NUM_CORNERS )
        (void) memcpy( rec[nr].lon_corner, rbuff+ni, nr_byte );

    if ( (retval = nc_inq_varid( ncid, "lat_bnds", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    retval = nc_get_var_float( ncid, var_id, rbuff );
    for ( ni = nr = 0; nr < numRec; nr++, ni += NUM_CORNERS )
        (void) memcpy( rec[nr].lat_corner, rbuff+ni, nr_byte );
    /*
     * read pixel meta-data as compound dataset
     */
    if ( (retval = nc_inq_varid( ncid, "tile", &var_id )) != NC_NOERR )
        NADC_GOTO_ERROR( NADC_ERR_FATAL, nc_strerror(retval) );
    for ( indx = 0; indx < (size_t) numRec; indx++ ) {
        retval = nc_get_var1( ncid, var_id, &indx, &rec[indx].meta );
    }

    rec_out[0] = rec;
    return numRec;
done:
    if ( rec != NULL ) free( rec );
    if ( rbuff != NULL ) free( rbuff );
    if ( dbuff != NULL ) free( dbuff );
    return 0;
}
int
main(int argc, char **argv)
{
   printf("\n*** Testing HDF4/NetCDF-4 interoperability...\n");
   printf("*** testing that netCDF can read a HDF4 file with some ints...");
   {
#define PRES_NAME "pres"
#define LAT_LEN 3
#define LON_LEN 2
#define DIMS_2 2

      int32 sd_id, sds_id;
      int32 dim_size[DIMS_2] = {LAT_LEN, LON_LEN};
      int32 start[DIMS_2] = {0, 0}, edge[DIMS_2] = {LAT_LEN, LON_LEN};
      int ncid, nvars_in, ndims_in, natts_in, unlimdim_in;
      size_t len_in;
      int data_out[LAT_LEN][LON_LEN], data_in[LAT_LEN][LON_LEN];
      size_t nstart[DIMS_2] = {0, 0}, ncount[DIMS_2] = {LAT_LEN, LON_LEN};
      size_t nindex[DIMS_2] = {0, 0};
      int scalar_data_in = 0;
      int i, j;

      /* Create some data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    data_out[i][j] = j;

      /* Create a file with one SDS, containing our phony data. */
      sd_id = SDstart(FILE_NAME, DFACC_CREATE);
      sds_id = SDcreate(sd_id, PRES_NAME, DFNT_INT32, DIMS_2, dim_size);
      if (SDwritedata(sds_id, start, NULL, edge, (void *)data_out)) ERR;
      if (SDendaccess(sds_id)) ERR;
      if (SDend(sd_id)) ERR;

      /* Now open with netCDF and check the contents. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; 
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR; 
      if (ndims_in != 2 || nvars_in != 1 || natts_in != 0 || unlimdim_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, NULL, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_inq_dim(ncid, 1, NULL, &len_in)) ERR;
      if (len_in != LON_LEN) ERR;
      
      /* Read the data through a vara function from the netCDF API. */
      if (nc_get_vara(ncid, 0, nstart, ncount, data_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (data_in[i][j] != data_out[i][j]) ERR;

      /* Reset for next test. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    data_in[i][j] = -88;

      /* Read the data through a vara_int function from the netCDF API. */
      if (nc_get_vara_int(ncid, 0, nstart, ncount, data_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (data_in[i][j] != data_out[i][j]) ERR;

      /* Reset for next test. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    data_in[i][j] = -88;

      /* Read the data through a var_int function from the netCDF API. */
      if (nc_get_var_int(ncid, 0, data_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (data_in[i][j] != data_out[i][j]) ERR;

      /* Read the data through a var1 function from the netCDF API. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	 {
	    nindex[0] = i;
	    nindex[1] = j;
	    if (nc_get_var1(ncid, 0, nindex, &scalar_data_in)) ERR;
	    if (scalar_data_in != data_out[i][j]) ERR;
	    scalar_data_in = -88; /* reset */
	    if (nc_get_var1_int(ncid, 0, nindex, &scalar_data_in)) ERR;
	    if (scalar_data_in != data_out[i][j]) ERR;
	 }

      if (nc_close(ncid)) ERR; 
   }
   SUMMARIZE_ERR;
   printf("*** testing with a more complex HDF4 file...");
   {
#define Z_LEN 3
#define Y_LEN 2
#define X_LEN 5
#define DIMS_3 3
#define NUM_TYPES 8

      int32 sd_id, sds_id;
      int32 dim_size[DIMS_3] = {Z_LEN, Y_LEN, X_LEN};
      int dimids_in[DIMS_3];
      int ncid, nvars_in, ndims_in, natts_in, unlimdim_in;
      size_t len_in;
      nc_type type_in;
      int hdf4_type[NUM_TYPES] = {DFNT_FLOAT32, DFNT_FLOAT64, 
				  DFNT_INT8, DFNT_UINT8, DFNT_INT16, 
				  DFNT_UINT16, DFNT_INT32, DFNT_UINT32};
      int netcdf_type[NUM_TYPES] = {NC_FLOAT, NC_DOUBLE, 
				  NC_BYTE, NC_UBYTE, NC_SHORT, 
				  NC_USHORT, NC_INT, NC_UINT};
      char tmp_name[NC_MAX_NAME + 1], name_in[NC_MAX_NAME + 1];
      char dim_name[NC_MAX_NAME + 1][DIMS_3] = {"z", "y", "x"};
      int d, t;

      /* Create a HDF4 SD file. */
      sd_id = SDstart (FILE_NAME, DFACC_CREATE);

      /* Create some HDF4 datasets. */
      for (t = 0; t < NUM_TYPES; t++)
      {
	 sprintf(tmp_name, "hdf4_dataset_type_%d", t);
	 if ((sds_id = SDcreate(sd_id, tmp_name, hdf4_type[t], 
				DIMS_3, dim_size)) == FAIL) ERR;	    
	 /* Set up dimensions. By giving them the same names for each
	  * dataset, I am specifying that they are shared
	  * dimensions. */
	 for (d = 0; d < DIMS_3; d++)
	 {
	    int32 dimid;
	    if ((dimid = SDgetdimid(sds_id, d)) == FAIL) ERR;
	    if (SDsetdimname(dimid, dim_name[d])) ERR;
	 }
	 if (SDendaccess(sds_id)) ERR;
      }
      if (SDend(sd_id)) ERR;

      /* Open the file with netCDF and check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdim_in)) ERR;
      if (ndims_in != DIMS_3 || nvars_in != NUM_TYPES || natts_in != 0 || unlimdim_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, NULL, &len_in)) ERR;
      if (len_in != Z_LEN) ERR;
      if (nc_inq_dim(ncid, 1, NULL, &len_in)) ERR;
      if (len_in != Y_LEN) ERR;
      if (nc_inq_dim(ncid, 2, NULL, &len_in)) ERR;
      if (len_in != X_LEN) ERR;
      for (t = 0; t < NUM_TYPES; t++)
      {
	 if (nc_inq_var(ncid, t, name_in, &type_in, &ndims_in, 
			dimids_in, &natts_in)) ERR;
	 if (type_in != netcdf_type[t] || ndims_in != DIMS_3 ||
	     dimids_in[0] != 0 || dimids_in[2] != 2 || dimids_in[2] != 2 || 
	     natts_in != 0) ERR;
      }
      
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}