Exemple #1
0
int NCfindVariableByAttribute (int ncid, int ndims, const char *attribute, const char *content) {
	int status;
	int varid;
	int nvars;
	int n;
	size_t attlen;
	char text [NC_MAX_NAME + 1];

	if ((status = nc_inq_nvars (ncid, &nvars)) != NC_NOERR) {
		CMmsgPrint (CMmsgAppError,"NetCDF file inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
		return (CMfailed);
	}
	for (varid = 0;varid < nvars; ++varid) {
		if (ndims > 0) {
			if ((status = nc_inq_varndims (ncid, varid, &n)) != NC_NOERR) {
				CMmsgPrint (CMmsgAppError,"NetCDF variable dimensions inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
				return (CMfailed);			
			}
			if (n != ndims) continue;
		}
		if ((status = nc_inq_attlen (ncid, varid, attribute, &attlen)) != NC_NOERR) continue;
		if ((attlen > strlen (content)) || (attlen > NC_MAX_NAME)) continue;
		if ((status = nc_get_att_text (ncid,varid,attribute,text)) != NC_NOERR) {
			CMmsgPrint (CMmsgAppError,"NetCDF attribute inquiring error \"%s\" in %s:%d!\n",nc_strerror (status),__FILE__,__LINE__);
			return (CMfailed);			
		}
		else text [attlen] = '\0';
		if (strcmp (text,content) == 0) break;
 	}
	return (varid < nvars ? varid : CMfailed);
}
Exemple #2
0
/*********************************************************************************
 * Return the varid of the only var in the file, or -1 if more than one.
 */
int R_ncu_varid_onlyvar( int ncid )
{
	int	ierr, nvars, varid, i, dimid;
	char	varname[MAX_NC_NAME];

	varid = -1;
	ierr = nc_inq_nvars( ncid, &nvars );
	if( ierr != NC_NOERR )
		error("Error reading from netcdf file!");

	for( i=0; i<nvars; i++ ) {
		ierr = nc_inq_varname( ncid, i, varname );
		if( ierr != NC_NOERR )
			error("Error reading from netcdf file!");
		ierr = nc_inq_dimid( ncid, varname, &dimid );
		if( ierr != NC_NOERR ) {
			/* Did NOT find this var as a dim, means it is NOT a dimvar */
			if( varid != -1 )
				/* More than one non-dimvar dim in this file */
				return( -1 );
			varid = i;
			}
		}
	return( varid );
}
Exemple #3
0
int NCdataGetCoreVarId(int ncid) {
    int status;
    int varid, nvars, ndims;
    int dimid[4], xdim = NCundefined, ydim = NCundefined, i, j;

    if ((status = nc_inq_nvars(ncid, &nvars)) != NC_NOERR) {
        NCprintNCError (status, "NCdataGetGridVarId");
        return (NCfailed);
    }

    if (((xdim = NCdataGetCDimId(ncid)) == NCfailed) &&
        (((xdim = NCdataGetXDimId(ncid)) == NCfailed) || ((ydim = NCdataGetYDimId(ncid)) == NCfailed)))
        return (NCfailed);

    for (varid = 0; varid < nvars; ++varid) {
        if ((status = nc_inq_varndims(ncid, varid, &ndims)) != NC_NOERR) {
            NCprintNCError (status, "NCdataGetGridVarId");
            return (NCfailed);
        }
        if ((ndims < 1) || (ndims > 4)) continue;
        if ((status = nc_inq_vardimid(ncid, varid, dimid)) != NC_NOERR) {
            NCprintNCError (status, "NCdataGetGridVarId");
            return (NCfailed);
        }
        for (i = 0; i < ndims; ++i)
            if (xdim == dimid[i]) {
                if (ydim == NCundefined) return (varid);
                for (j = 0; j < ndims; ++j) if (ydim == dimid[j]) return (varid);
            }
    }
    return (NCfailed);
}
Exemple #4
0
int NcFile::num_vars( void ) const
{
    int num = 0;
    if (is_valid())
      NcError::set_err(
		       nc_inq_nvars(the_id, &num)
		       );
    return num;
}
Exemple #5
0
/*
 * Retrieves the number of record variables, the record variable ids, and the
 * record size of each record variable.  If any pointer to info to be returned
 * is null, the associated information is not returned.  Returns -1 on error.
 */
int
nc_inq_rec(
	int ncid,
	size_t *nrecvarsp,
	int *recvarids,
	size_t *recsizes)
{
    int status;
    int nvars = 0;
    int recdimid;
    int varid;
    int rvarids[MAX_NC_VARS];
    int nrvars = 0;

    status = nc_inq_nvars(ncid, &nvars); 
    if(status != NC_NOERR)
	return status;

    status = nc_inq_unlimdim(ncid, &recdimid); 
    if(status != NC_NOERR)
	return status;

    *nrecvarsp = 0;
    if (recdimid == -1)
	return NC_NOERR;
    
    status = numrecvars(ncid, &nrvars, rvarids);
    if(status != NC_NOERR)
	return status;

    if (nrecvarsp != NULL)
	*nrecvarsp = nrvars;
    if (recvarids != NULL)
	for (varid = 0; varid < nrvars; varid++)
	    recvarids[varid] = rvarids[varid];

    if (recsizes != NULL)
	for (varid = 0; varid < nrvars; varid++) {
	    size_t rsize;
	    status = ncrecsize(ncid, rvarids[varid], &rsize);
	    if (status != NC_NOERR)
		return status;
	    recsizes[varid] = rsize;
	}
	return NC_NOERR;
}
Exemple #6
0
NCstate NCdataCopyAllAttibutes(int inNCid, int outNCid, bool overwrite) {
    int status, inVarid, outVarid, varnum;
    char varName[NC_MAX_NAME];
    if (NCdataCopyAttributes(inNCid, NC_GLOBAL, outNCid, NC_GLOBAL, overwrite) == NCfailed) return (NCfailed);

    if ((status = nc_inq_nvars(inNCid, &varnum)) != NC_NOERR) {
        NCprintNCError (status, "NCdataCopyAttibutes");
        return (NCfailed);
    }
    for (inVarid = 0; inVarid < varnum; ++inVarid) {
        if ((status = nc_inq_varname(inNCid, inVarid, varName)) != NC_NOERR) {
            NCprintNCError (status, "NCdataCopyAttibutes");
            return (NCfailed);
        }
        if ((status = nc_inq_varid(outNCid, varName, &outVarid)) != NC_NOERR) continue;
        if (NCdataCopyAttributes(inNCid, inVarid, outNCid, outVarid, overwrite) == NCfailed) return (NCfailed);
    }
    return (NCsucceeded);
}
Exemple #7
0
/*
 * Computes number of record variables in an open netCDF file, and an array of
 * the record variable ids, if the array parameter is non-null.
 */
static int
numrecvars(int ncid, int *nrecvarsp, int *recvarids)
{
    int status;
    int nvars = 0;
    int ndims = 0;
    int nrecvars = 0;
    int varid;
    int recdimid;
    int dimids[MAX_NC_DIMS];

    status = nc_inq_nvars(ncid, &nvars); 
    if(status != NC_NOERR)
	return status;

    status = nc_inq_unlimdim(ncid, &recdimid); 
    if(status != NC_NOERR)
	return status;

    if (recdimid == -1) {
	*nrecvarsp = 0;
	return NC_NOERR;
    }
    nrecvars = 0;
    for (varid = 0; varid < nvars; varid++) {
	status = nc_inq_varndims(ncid, varid, &ndims); 
	if(status != NC_NOERR)
	    return status;
	status = nc_inq_vardimid(ncid, varid, dimids); 
	if(status != NC_NOERR)
	    return status;
	if (ndims > 0 && dimids[0] == recdimid) {
	    if (recvarids != NULL)
	      recvarids[nrecvars] = varid;
	    nrecvars++;
	}
    }
    *nrecvarsp = nrecvars;
    return NC_NOERR;
}
Exemple #8
0
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);
}
Exemple #9
0
int
check_4D_example(char *file_name, int expected_format)
{
   int ncid;
   int format, ndims_in, nvars_in, natts_in;
   int dimid[NDIMS_EX];
   int varid[NVARS_EX];
   char dim_name_in[NDIMS_EX][NC_MAX_NAME];
   char var_name_in[NVARS_EX][NC_MAX_NAME];
   char name_in[NC_MAX_NAME + 1];
   char units_in[NC_MAX_NAME + 1];
   nc_type xtype_in;
   size_t len_in;
   int i;

   if (nc_open(file_name, 0, &ncid)) ERR;

   /* Count stuff. */
   if (nc_inq_format(ncid, &format)) ERR;
   if (nc_inq_ndims(ncid, &ndims_in)) ERR;
   if (ndims_in != NDIMS_EX) ERR;
   if (nc_inq_nvars(ncid, &nvars_in)) ERR;
   if (nvars_in != NVARS_EX) ERR;
   if (nc_inq_natts(ncid, &natts_in)) ERR;
   if (natts_in != 0) ERR;
   if (format != expected_format) ERR;

   /* Check dimensions. */
   ndims_in = 0;
   if (nc_inq_dimids(ncid, &ndims_in, dimid, 0)) ERR;
   if (ndims_in != NDIMS_EX) ERR;
   for (i = 0; i < NDIMS_EX; i++)
   {
      if (dimid[i] != i) ERR;
      if (nc_inq_dimname(ncid, i, dim_name_in[i])) ERR;
   }
   if (strcmp(dim_name_in[0], LVL_NAME) || strcmp(dim_name_in[1], LAT_NAME) ||
       strcmp(dim_name_in[2], LON_NAME) || strcmp(dim_name_in[3], REC_NAME)) ERR;

   /* Check variables. */
   nvars_in = 0;
   if (nc_inq_varids(ncid, &nvars_in, varid)) ERR;
   if (nvars_in != NVARS_EX) ERR;
   for (i = 0; i < NVARS_EX; i++)
   {
      if (varid[i] != i) ERR;
      if (nc_inq_varname(ncid, i, var_name_in[i])) ERR;
   }
   if (strcmp(var_name_in[0], LAT_NAME) || strcmp(var_name_in[1], LON_NAME) ||
       strcmp(var_name_in[2], PRES_NAME) || strcmp(var_name_in[3], TEMP_NAME)) ERR;

   if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || 
       dimid[0] != 1 || natts_in != 1) ERR;
   if (nc_inq_var(ncid, 1, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 || 
       dimid[0] != 2 || natts_in != 1) ERR;
   if (nc_inq_var(ncid, 2, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, PRES_NAME) || xtype_in != NC_FLOAT || ndims_in != 4 || 
       dimid[0] != 3 || dimid[1] != 0 || dimid[2] != 1 || dimid[3] != 2 || 
       natts_in != 1) ERR;
   if (nc_inq_var(ncid, 3, name_in, &xtype_in, &ndims_in, dimid, &natts_in)) ERR;
   if (strcmp(name_in, TEMP_NAME) || xtype_in != NC_FLOAT || ndims_in != 4 || 
       dimid[0] != 3 || dimid[1] != 0 || dimid[2] != 1 || dimid[3] != 2 || 
       natts_in != 1) ERR;

   /* Check variable atts. */
   if (nc_inq_att(ncid, 0, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(DEGREES_NORTH)) ERR;
   if (nc_get_att_text(ncid, 0, UNITS, units_in)) ERR;
   if (strncmp(units_in, DEGREES_NORTH, strlen(DEGREES_NORTH))) ERR;

   if (nc_inq_att(ncid, 1, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(DEGREES_EAST)) ERR;
   if (nc_get_att_text(ncid, 1, UNITS, units_in)) ERR;
   if (strncmp(units_in, DEGREES_EAST, strlen(DEGREES_EAST))) ERR;

   if (nc_inq_att(ncid, 2, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(PRES_UNITS)) ERR;
   if (nc_get_att_text(ncid, 2, UNITS, units_in)) ERR;
   if (strncmp(units_in, PRES_UNITS, strlen(PRES_UNITS))) ERR;

   if (nc_inq_att(ncid, 3, UNITS, &xtype_in, &len_in)) ERR;
   if (xtype_in != NC_CHAR || len_in != strlen(TEMP_UNITS)) ERR;
   if (nc_get_att_text(ncid, 3, UNITS, units_in)) ERR;
   if (strncmp(units_in, TEMP_UNITS, strlen(TEMP_UNITS))) ERR;

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

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

       printf("*** Compare values in nofill mode and fill mode files...");
       /* compare data in two files created with nofill mode and fill
	* mode, which should be identical if all the data were written */
       if (nc_open(FILE_NAME1, NC_NOWRITE, &ncid1)) ERR;
       if (nc_open(FILE_NAME2, NC_NOWRITE, &ncid2)) ERR;
       if (nc_inq_nvars(ncid1, &nvars1)) ERR;
       if (nc_inq_nvars(ncid2, &nvars2)) ERR;
       if (nvars1 != nvars2) ERR;
       badvars = 0;
       for(varid = 0; varid < nvars1; varid++) {
	   size_t nvals, nn;
	   int ndims, *dimids, dim;
	   nc_type vtype;
	   char varname1[NC_MAX_NAME];		   
	   char varname2[NC_MAX_NAME];
	   /* How many values in this variable to compare? */
	   if (nc_inq_varndims(ncid1, varid, &ndims)) ERR;
	   dimids = malloc((ndims + 1) * sizeof(int));
	   if (!dimids) ERR;
	   if (nc_inq_vardimid (ncid1, varid, dimids)) ERR;
	   nvals = 1;
	   for(dim = 0; dim < ndims; dim++) {
	       size_t len;
	       if (nc_inq_dimlen(ncid1, dimids[dim], &len)) ERR;
	       nvals *= len;
	   }
	   if (nc_inq_vartype(ncid1, varid, &vtype)) ERR;
	   if (nc_inq_varname(ncid1, varid, varname1)) ERR;
	   if (nc_inq_varname(ncid1, varid, varname2)) ERR;
	   
	   if (vtype != NC_CHAR) {  /* numeric data, just read in as doubles */
	       double *data1, *data2;
	       /* Allocate space to hold values in both files */
	       data1 = malloc((nvals + 1) * sizeof(double));
	       if (!data1) ERR;
	       data2 = malloc((nvals + 1) * sizeof(double));
	       if (!data2) ERR;
	       /* Read in values */
	       if (nc_get_var_double(ncid1, varid, data1)) ERR;
	       if (nc_get_var_double(ncid2, varid, data2)) ERR;
	       /* Compare values */
	       for(nn = 0; nn < nvals; nn++) {
		   if (data1[nn] != data2[nn]) {
		       badvars++;
		       fprintf(stderr, 
			       "\tFrom nofill file, %s[%d] = %.15g\tFrom fill file, %s[%d] = %.15g\n", 
			       varname1, nn, data1[nn], varname2, nn, data2[nn]);
		       break;
		   };
	       }
	       free(data1);
	       free(data2);
	   } else {		/* character data */
	       char *data1, *data2;
	       /* Allocate space to hold values in both files */
	       data1 = malloc((nvals + 1) * sizeof(char));
	       if (!data1) ERR;
	       data2 = malloc((nvals + 1) * sizeof(char));
	       if (!data2) ERR;
	       /* Read in values */
	       if (nc_get_var_text(ncid1, varid, data1)) ERR;
	       if (nc_get_var_text(ncid2, varid, data2)) ERR;
	       /* Compare values */
	       for(nn = 0; nn < nvals; nn++) {
		   if (data1[nn] != data2[nn]) {
		       badvars++;
		       fprintf(stderr, 
			       "\tFrom nofill file, %s[%d] = %d\tFrom fill file, %s[%d] = %d\n", 
			       varname1, nn, data1[nn], varname2, nn, data2[nn]);
		       break;
		   };
	       }
	       free(data1);
	       free(data2);
	   }
	   free(dimids);
       }
       if(badvars > 0) ERR;
       if (nc_close(ncid1)) ERR;
       if (nc_close(ncid2)) ERR;
       SUMMARIZE_ERR;
   }
   FINAL_RESULTS;
}
Exemple #11
0
/* Has to be at the bottom because it uses many
 * other functions */
void sdatio_open_file(struct sdatio_file * sfile )  {
  /*printf("called\n");*/
  int retval;
  int ndims, nvars;
  int i, j;
  struct sdatio_dimension * sdim;
  struct sdatio_variable * svar;
  size_t lengthp;
  int nunlimdims;
  int *unlimdims;
  int is_unlimited;
  char * name_tmp;
  int * vardimids;
  char * dimension_list;
  nc_type vartype;
  int vartypeint;
  int dummy;
  int *nunlim;

  DEBUG_MESS("starting sdatio_open_file\n");

  retval = 0;

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

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

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

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

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

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

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

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


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

    
    svar->type = vartypeint;

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

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

    DEBUG_MESS("Starting sdatio_append_variable\n");

    sdatio_append_variable(sfile, svar);

    DEBUG_MESS("Ending sdatio_append_variable\n");

#ifdef PARALLEL
    if (sfile->is_parallel){
      sdatio_number_of_unlimited_dimensions(sfile, svar->name, &nunlim);
      if (nunlim > 0)
        if ((retval = nc_var_par_access(sfile->nc_file_id, svar->nc_id, NC_COLLECTIVE))) ERR(retval);
    }
#endif
    /*vartypeint = */
  }
  DEBUG_MESS("Finished reading variables\n");
  
  free(unlimdims);
  free(name_tmp);
}
Exemple #12
0
int Read_NetCDF_METARS_Header( char *filename, irregular_v5dstruct *ir)
{
   int temp, c, i, j, k, t, *times, tnid, status;
   int offset, numuniquetimes;
   int nc_id, numrecsid;
   int id, year, day, hour, minute, second;
   nc_type type;
   size_t sizea, sized, numrecs;
   int ntimes[MAXTIMES], uniquetimes[MAXTIMES];
   char vname[1000];
   char tdim[1000];
   size_t num_cloud_layers;
   int numdims;
   int dimids[10];
   size_t stringsize;
   int cloud_layer_id;
   int latid, lonid, hgtid;

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

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


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

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

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

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

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

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

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

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

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

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

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

 
   offset = 0;


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


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

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

   free(times);

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






   return 0;
}
Exemple #13
0
void bi::InputNetCDFBuffer::map() {
  int ncDim, ncVar;
  Var* var;
  std::string name;
  VarType type;
  int i, k, id;

  /* ns dimension */
  nsDim = nc_inq_dimid(ncid, "ns");
  if (nsDim >= 0) {
    BI_ERROR_MSG(ns < (int )nc_inq_dimlen(ncid, nsDim),
        "Given index " << ns << " outside range of ns dimension");
  }

  /* np dimension */
  npDim = nc_inq_dimid(ncid, "np");
  if (npDim >= 0) {
    BI_ERROR_MSG(np < 0 || np < (int )nc_inq_dimlen(ncid, npDim),
        "Given index " << np << " outside range of np dimension");
  }

  /* record dimensions, time and coordinate variables */
  int nvars = nc_inq_nvars(ncid);
  for (i = 0; i < nvars; ++i) {
    ncVar = i;
    name = nc_inq_varname(ncid, i);

    if (name.find("time") == 0) {
      /* is a time variable */
      ncDim = mapTimeDim(ncVar);
      if (ncDim >= 0) {
        BOOST_AUTO(iter, std::find(recDims.begin(), recDims.end(), ncDim));
        if (iter == recDims.end()) {
          /* newly encountered record dimension */
          recDims.push_back(ncDim);
          timeVars.push_back(ncVar);
          coordVars.push_back(-1);
        } else {
          /* record dimension encountered before */
          k = std::distance(recDims.begin(), iter);
          BI_ASSERT_MSG(timeVars[k] < 0,
              "Time variables " << nc_inq_varname(ncid, timeVars[k]) << " and " << name << " cannot share the same record dimension " << nc_inq_dimname(ncid, *iter));
          timeVars[k] = ncVar;
        }
      }
    } else if (name.find("coord") == 0) {
      /* is a coordinate variable */
      ncDim = mapCoordDim(ncVar);
      if (ncDim >= 0) {
        BOOST_AUTO(iter, std::find(recDims.begin(), recDims.end(), ncDim));
        if (iter == recDims.end()) {
          /* newly encountered record dimension */
          recDims.push_back(ncDim);
          timeVars.push_back(-1);
          coordVars.push_back(ncVar);
        } else {
          /* record dimension encountered before */
          k = std::distance(recDims.begin(), iter);
          BI_ASSERT_MSG(coordVars[k] < 0,
              "Coordinate variables " << nc_inq_varname(ncid, coordVars[k]) << " and " << name << " cannot share the same record dimension " << nc_inq_dimname(ncid, *iter));
          coordVars[k] = ncVar;
        }
      }
    }
  }

  /* model variables */
  for (i = 0; i < NUM_VAR_TYPES; ++i) {
    type = static_cast<VarType>(i);

    /* initialise NetCDF variables for this type */
    vars[type].resize(m.getNumVars(type), -1);

    /* map model variables */
    for (id = 0; id < m.getNumVars(type); ++id) {
      var = m.getVar(type, id);
      if (var->hasInput()) {
        BOOST_AUTO(pair, mapVarDim(var));
        k = pair.first;
        ncVar = pair.second;

        if (ncVar >= 0) {
          vars[type][id] = ncVar;
        }
        modelVars.insert(std::make_pair(k, var));
      }
    }
  }

  /* preload random access tables */
  std::multimap<real,int> seq;
  std::vector<size_t> starts(recDims.size(), 0), lens(recDims.size(), 0);
  real tnxt;

  for (k = 0; k < int(recDims.size()); ++k) {
    if (timeVars[k] >= 0 && modelVars.count(k) > 0) {
      /* ^ ignores record dimensions with no associated time or model
       *   variables */
      readTime(timeVars[k], starts[k], &lens[k], &tnxt);
      seq.insert(std::make_pair(tnxt, k));
    }
  }
  while (!seq.empty()) {
    /* next in time */
    tnxt = seq.begin()->first;
    k = seq.begin()->second;
    seq.erase(seq.begin());

    ncDim = recDims[k];
    ncVar = timeVars[k];

    if (times.empty() || times.back() != tnxt) {
      times.push_back(tnxt);
      recStarts.push_back(std::vector < size_t > (recDims.size(), 0));
      recLens.push_back(std::vector < size_t > (recDims.size(), 0));
    }
    recStarts.back()[k] = starts[k];
    recLens.back()[k] = lens[k];

    /* read next time and range for this time variable */
    starts[k] += lens[k];
    if (starts[k] < nc_inq_dimlen(ncid, ncDim)) {
      /* more to come on this record dimension */
      readTime(ncVar, starts[k], &lens[k], &tnxt);
      seq.insert(std::make_pair(tnxt, k));
    }
  }
}