示例#1
0
int main(int argc,char *argv[]) {
  struct DataMap *ptr;
  struct DataMapScalar *sx,*sy;
  struct DataMapArray *ax,*ay;
  size_t index[256];
  size_t start[256];
  size_t count[256];

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

  FILE *fp=NULL;
  gzFile zfp=0;

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

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


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

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

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


  /* load the map */

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

 

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


   


  block=0;
  while (1) {

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

    if (ptr==NULL) break;

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

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

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

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

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

    DataMapFree(ptr);
    block++;
  }
  nc_close(ncid);
  if (zflg) gzclose(zfp);
  else fclose(fp);
  return 0;
}
/**
 * Generates a bathymetryGrid by reading data from a local file.  Results are
 * dumped into topographyGrid.
 * @param topographyGrid A pointer to a zero-initialized Grid of size
 *      numRows x numCols.
 * @param inputFile The relative path to the topography file you wish to use.
 * @param inputFileType Use 'netcdf' if your file is in netcdf format.  Use
 *      'asc' if the file is a matrix of ascii values in the GIS asc format.
 * @param startRow The row to start reading data from.
 * @param startCol The col to start reading data from.
 * @param numRows The desired number of rows of data to read.
 * @param numCols The desired number of cols of data to read.
 * @param seriesName If inputFileType was set to 'netcdf', this should be set
 *      to the name of the series you wish to use.
 * @param timestamp A timestamp value used for error reporting.
 */
void getBathy(Grid* topographyGrid, std::string inputFile,
              std::string inputFileType, size_t startRow, size_t startCol,
              size_t numRows, size_t numCols, std::string seriesName,
              std::string timestamp) {
    // This will be the netCDF ID for the file and data variable.
    Eigen::MatrixXd temp;
    int ncid, varid, retval = -100;

    // NetCDF
    if (inputFileType.compare("netcdf") == 0) {
        // Data will be read in column major, so set up a matrix of inverse
        //    size to recieve it.
        temp.resize(numCols, numRows);
        // Open the file. NC_NOWRITE tells netCDF we want read-only access to
        //    the file.
        if ((retval = nc_open(inputFile.c_str(), NC_NOWRITE, &ncid))) {
            printError("ERROR: Cant open NetCDF File. Invalid inputFile path.",
                        retval, timestamp);
        }

        // Get the varid of the data variable, based on its name.
        if ((retval = nc_inq_varid(ncid, seriesName.c_str(), &varid))) {
            printError("ERROR: Can't access variable id.  Invalid seriesName.",
                        retval, timestamp);
        }
        // Read the data.
        try {
            // for whatever reason, this is in column, row order.
            static size_t start[] = {startRow, startCol};
            static size_t range[] = {numRows, numCols};
            retval = nc_get_vara_double(ncid, varid, start, range,
                                        temp.data());
            // TODO(Greg) Figure out a way to read data in row wise to avoid
            //             this transposition.
            topographyGrid->data.block(border, border, numRows, numCols) =
                            temp.transpose().block(0, 0, numRows, numCols);
        }
        catch (int i) {
            printError("ERROR: Error reading data.  Invalid file format.",
                        retval, timestamp);
        }
        // Close the file, freeing all resources.
        if ((retval = nc_close(ncid))) {
            printError("ERROR: Error closing the file.", retval, timestamp);
        }
    } else if (inputFileType.compare("asc") == 0) {
        // ASC
        temp.resize(numRows, numCols);
        std::ifstream input(inputFile);
        int null = 0;
        size_t numHeaderLines = 5,
               rowsLine = 1,
               colsLine = 0,
               nullLine = 5,
               cursor = 0,
               rows = 0,
               cols = 0,
               startRowIndex = startRow+numHeaderLines,
               endRowIndex = startRowIndex+numRows,
               i = 0,
               j = 0;
        std::string line = "";
        std::vector<std::string> vLine;
        if (input.is_open()) {
            for (cursor = 0; cursor < endRowIndex; cursor ++) {
                getline(input, line);

                if (cursor <= numHeaderLines) {
                    // Get the number of columns in the file
                    if (cursor == colsLine) {
                        vLine = split(&line, ' ');
                        if (!silent) {
                            std::cout << "\nAvailable Cols: " <<
                                         vLine[vLine.size()-1];
                        }
                        cols = stoi(vLine[vLine.size() - 1]);

                        if (cols < startCol + numCols) {
                            std::cout << "\nERROR, requested bathymetry " <<
                                    " grid column coordinates are out of" <<
                                    " bounds.\n";
                            exit(1);
                        }
                    } else if (cursor == rowsLine) {
                        // Get the number of rows in the file.
                        vLine = split(&line, ' ');
                        if (!silent) {
                        std::cout << "Available Rows:" <<
                                     vLine[vLine.size() - 1];
                        }
                        rows = stoi(vLine[vLine.size() - 1]);

                        if (rows < startRow + numRows) {
                            std::cout << "\nERROR, requested bathymetry" <<
                                    " grid row coordinates are out of" <<
                                    " bounds.\n";
                            exit(1);
                        }
                    } else if (cursor == nullLine) {
                        // Get the null value substitute
                        vLine = split(&line, ' ');
                        if (debug) {
                            std::cout << "Null values =" <<
                                         vLine[vLine.size() - 1] << "\n";
                        }
                        null = stoi(vLine[vLine.size() - 1]);
                    }
                } else if (cursor >= startRowIndex) {
                    vLine = split(&line, ' ');
                    for (i = startCol; i < startCol + numCols; i ++) {
                        // std::cout<<"accessing temp(" <<
                        // cursor-startRowIndex-1 << "," <<i-startCol<<")\n";
                        // std::cout<<"Cursor:"<<cursor<<"   SRI:" <<
                        // startRowIndex << "\n";
                        temp(cursor - startRowIndex, i - startCol) =
                                stod(vLine[i]);
                    }
                }
            }

            input.close();

            for (i = 0; i < numRows; i ++) {
                for (j = 0; j < numCols; j ++) {
                    if (temp(i, j) == null) {
                        temp(i, j) = 0;
                    }
                }
            }
            topographyGrid->data.block(border, border, numRows, numCols) =
                            temp.block(0, 0, numRows, numCols);
        } else {
            std::cout << "\nUnable to open bathymetry file: \"" << inputFile <<
                         "\"\n";
            exit(0);
        }
    } else {
        // Invalid filetype
        std::cout << "Bathymetry file type not supported.  Simulating" <<
                     "Bathymetry.\n";
        simulatetopographyGrid(topographyGrid, static_cast<int>(numRows),
                               static_cast<int>(numCols));
    }
    topographyGrid->clearNA();
    topographyGrid->data =
            topographyGrid->data.unaryExpr(std::ptr_fun(validateDepth));
    if (acousticParams["debug"] == "1") {
        // topographyGrid->printData();
        std::cout << "startx " << startCol << "\nXDist: "<< numCols <<
                  "\nstartY:  "<< startRow << "\nYDist: " << numRows << "\n";
        std::cout << "inputFileType: " << inputFileType << "\ninputFile: " <<
                  inputFile << "\nseriesName: " << seriesName << "\n";
        std::cout << "retval: " << retval << "\n" << "ncid: " << ncid << "\n\n";
    }
}
示例#3
0
int
main(int argc, char **argv)
{
   fprintf(stderr,"Test more renaming.\n");
   fprintf(stderr,"*** test renaming affect on varids...");
   {
      int ncid, dimid1, dimid2, varid1, varid2;
      int dimid_in, varid_in;
      char file_name[NC_MAX_NAME + 1];

      /* Create file with two scalar vars. */
      sprintf(file_name, "%s_coord_to_non_coord.nc", TEST_NAME);
      if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_var(ncid, D1_NAME, NC_INT, 0, NULL, &varid1)) ERR;
      if (nc_def_var(ncid, D2_NAME, NC_INT, 0, NULL, &varid2)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and rename a var. */
      nc_set_log_level(4);
      if (nc_open(file_name, NC_WRITE, &ncid)) ERR;
      if (nc_rename_var(ncid, varid1, TMP_NAME)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen file and check, */
      if (nc_open(file_name, NC_WRITE, &ncid)) ERR;
      if (nc_inq_varid(ncid, TMP_NAME, &varid_in)) ERR;
      /* if (varid_in != varid1) ERR; */
      if (nc_inq_varid(ncid, D1_NAME, &varid_in) != NC_ENOTVAR) ERR;
      if (nc_inq_varid(ncid, D2_NAME, &varid_in)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   /* fprintf(stderr,"*** test renaming coord var to non-coord var..."); */
   /* { */
   /*    int ncid, dimid1, dimid2, varid1, varid2; */
   /*    int dimid_in, varid_in; */
   /*    char file_name[NC_MAX_NAME + 1]; */

   /*    /\* Create file with two dims and associated coordinate vars. *\/ */
   /*    sprintf(file_name, "%s_coord_to_non_coord.nc", TEST_NAME); */
   /*    if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; */
   /*    if (nc_def_dim(ncid, D1_NAME, DIM1_LEN, &dimid1)) ERR; */
   /*    if (nc_def_dim(ncid, D2_NAME, DIM1_LEN, &dimid2)) ERR; */
   /*    if (nc_def_var(ncid, D1_NAME, NC_INT, NDIM1, &dimid1, &varid1)) ERR; */
   /*    if (nc_def_var(ncid, D2_NAME, NC_INT, NDIM1, &dimid2, &varid2)) ERR; */
   /*    if (nc_close(ncid)) ERR; */

   /*    /\* Open the file and rename a var. *\/ */
   /*    nc_set_log_level(4); */
   /*    if (nc_open(file_name, NC_WRITE, &ncid)) ERR; */
   /*    if (nc_rename_var(ncid, varid1, TMP_NAME)) ERR; */
   /*    if (nc_close(ncid)) ERR; */

   /*    /\* Reopen file and check, *\/ */
   /*    if (nc_open(file_name, NC_WRITE, &ncid)) ERR; */
   /*    if (nc_inq_dimid(ncid, D1_NAME, &dimid_in)) ERR; */
   /*    printf("dimid_in %d\n", dimid_in); */
   /*    if (dimid_in != dimid1) ERR; */
   /*    if (nc_inq_dimid(ncid, D2_NAME, &dimid_in)) ERR; */
   /*    if (dimid_in != dimid2) ERR; */
   /*    if (nc_inq_dimid(ncid, TMP_NAME, &dimid_in) != NC_EBADDIM) ERR; */
   /*    if (nc_inq_varid(ncid, TMP_NAME, &varid_in)) ERR; */
   /*    /\* if (varid_in != varid1) ERR; *\/ */
   /*    if (nc_inq_varid(ncid, D1_NAME, &varid_in) != NC_ENOTVAR) ERR; */
   /*    if (nc_close(ncid)) ERR; */

   /*    /\* if (nc_open(file_name, NC_WRITE, &ncid)) ERR; *\/ */
   /*    /\* if (nc_rename_var(ncid, varid2, D1_NAME)) ERR; *\/ */
   /*    /\* if (nc_close(ncid)) ERR; *\/ */

   /*    /\* /\\* Reopen file and check, *\\/ *\/ */
   /*    /\* if (nc_open(file_name, NC_WRITE, &ncid)) ERR; *\/ */
   /*    /\* if (nc_inq_dimid(ncid, D1_NAME, &dimid_in)) ERR; *\/ */
   /*    /\* if (dimid_in != dimid1) ERR; *\/ */
   /*    /\* if (nc_inq_dimid(ncid, D2_NAME, &dimid_in)) ERR; *\/ */
   /*    /\* if (dimid_in != dimid2) ERR; *\/ */
   /*    /\* if (nc_inq_dimid(ncid, TMP_NAME, &dimid_in) != NC_EBADDIM) ERR; *\/ */
   /*    /\* if (nc_inq_varid(ncid, TMP_NAME, &varid_in)) ERR; *\/ */
   /*    /\* if (varid_in != varid1) ERR; *\/ */
   /*    /\* if (nc_inq_varid(ncid, D1_NAME, &varid_in)) ERR; *\/ */
   /*    /\* if (varid_in != varid2) ERR; *\/ */
   /*    /\* if (nc_close(ncid)) ERR; *\/ */
   /* } */
   /* SUMMARIZE_ERR; */
   /* fprintf(stderr,"*** test exchanging names of two coord vars, making them non-coord vars with names same as dims..."); */
   /* { */
   /*    int ncid, dimid1, dimid2, varid1, varid2; */
   /*    int dimid_in, varid_in; */
   /*    char file_name[NC_MAX_NAME + 1]; */

   /*    /\* Create file with dim and associated coordinate var. *\/ */
   /*    sprintf(file_name, "%s_non_coord_to_dim.nc", TEST_NAME); */
   /*    if (nc_create(file_name, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR; */
   /*    if (nc_def_dim(ncid, D1_NAME, DIM1_LEN, &dimid1)) ERR; */
   /*    if (nc_def_dim(ncid, D2_NAME, DIM1_LEN, &dimid2)) ERR; */
   /*    if (nc_def_var(ncid, D1_NAME, NC_INT, NDIM1, &dimid1, &varid1)) ERR; */
   /*    if (nc_def_var(ncid, D2_NAME, NC_INT, NDIM1, &dimid2, &varid2)) ERR; */
   /*    if (nc_close(ncid)) ERR; */

   /*    /\* Open the file and rename the vars. *\/ */
   /*    nc_set_log_level(4); */
   /*    if (nc_open(file_name, NC_WRITE, &ncid)) ERR; */
   /*    if (nc_rename_var(ncid, varid1, TMP_NAME)) ERR; */
   /*    nc_sync(ncid); */
   /*    /\* if (nc_rename_var(ncid, varid2, D1_NAME)) ERR; *\/ */
   /*    /\* nc_sync(ncid); *\/ */
   /*    /\* if (nc_rename_var(ncid, varid1, D2_NAME)) ERR; *\/ */
   /*    if (nc_close(ncid)) ERR; */

   /*    /\* Reopen file and check, *\/ */
   /*    if (nc_open(file_name, NC_WRITE, &ncid)) ERR; */
   /*    /\* if (nc_inq_dimid(ncid, D1_NAME, &dimid_in)) ERR; *\/ */
   /*    /\* if (dimid_in != dimid1) ERR; *\/ */
   /*    /\* if (nc_inq_dimid(ncid, D2_NAME, &dimid_in)) ERR; *\/ */
   /*    /\* if (dimid_in != dimid2) ERR; *\/ */
   /*    /\* if (nc_inq_dimid(ncid, TMP_NAME, &dimid_in) != NC_EBADDIM) ERR; *\/ */
   /*    /\* if (nc_inq_varid(ncid, TMP_NAME, &varid_in)) ERR; *\/ */
   /*    /\* if (varid_in != varid1) ERR; *\/ */
   /*    /\* if (nc_inq_varid(ncid, D1_NAME, &varid_in)) ERR; *\/ */
   /*    /\* if (varid_in != varid2) ERR; *\/ */
   /*    if (nc_close(ncid)) ERR; */
   /* } */
   /* SUMMARIZE_ERR; */
   FINAL_RESULTS;
}
示例#4
0
文件: surface3d.c 项目: H2Lib/H2Lib
psurface3d
read_nc_surface3d(const char *filename)
{
#ifdef USE_NETCDF
  psurface3d gr;
  real(*x)[3];
  uint(*e)[2];
  uint(*t)[3];
  uint(*s)[3];
  uint      vertices;
  uint      edges;
  uint      triangles;
  int       res, nc_in;
  int       x_id, e_id, t_id, s_id;
  int       vertices_id, edges_id, triangles_id;
  size_t    dim;

  /* Open CDF file */
  res = nc_open(filename, NC_NOWRITE, &nc_in);
  nc_handle_error(res);

  /* Obtain dimensions */
  res = nc_inq_dimid(nc_in, "vertices", &vertices_id);
  nc_handle_error(res);
  res = nc_inq_dimid(nc_in, "edges", &edges_id);
  nc_handle_error(res);
  res = nc_inq_dimid(nc_in, "triangles", &triangles_id);
  nc_handle_error(res);

  /* Get values of dimensions */
  res = nc_inq_dimlen(nc_in, vertices_id, &dim);
  nc_handle_error(res);
  vertices = dim;
  res = nc_inq_dimlen(nc_in, edges_id, &dim);
  nc_handle_error(res);
  edges = dim;
  res = nc_inq_dimlen(nc_in, triangles_id, &dim);
  nc_handle_error(res);
  triangles = dim;

  /* Create surface3d object */
  gr = new_surface3d(vertices, edges, triangles);
  x = gr->x;
  e = gr->e;
  t = gr->t;
  s = gr->s;

  /* Obtain variables */
  res = nc_inq_varid(nc_in, "x", &x_id);
  nc_handle_error(res);
  res = nc_inq_varid(nc_in, "e", &e_id);
  nc_handle_error(res);
  res = nc_inq_varid(nc_in, "t", &t_id);
  nc_handle_error(res);
  res = nc_inq_varid(nc_in, "s", &s_id);
  nc_handle_error(res);

  /* Read variables */
  res = nc_get_var(nc_in, x_id, x);
  res = nc_get_var(nc_in, e_id, e);
  res = nc_get_var(nc_in, t_id, t);
  res = nc_get_var(nc_in, s_id, s);

  /* Close file */
  res = nc_close(nc_in);
  nc_handle_error(res);

  return gr;

#else
  (void) filename;

  (void) printf("Sorry, no NetCDF support.\n");
  return 0;
#endif
}
示例#5
0
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;
}
示例#6
0
int
check_file(int format, unsigned char *uchar_out)
{
   int ncid;
   int ndims, natts;
   int dimids_var[1], var_type;
   char var_name[NC_MAX_NAME+1];
   unsigned char uchar_in[DIM1_LEN];
   signed char char_in[DIM1_LEN];
   unsigned short ushort_in[DIM1_LEN];
   short short_in[DIM1_LEN];
   unsigned int uint_in[DIM1_LEN];
   int int_in[DIM1_LEN];
   long long int64_in[DIM1_LEN];
   unsigned long long uint64_in[DIM1_LEN];
   int i, res;

   /* Read it back in, and check conversions. */
   if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (strcmp(var_name, VAR1_NAME) || natts !=0 || ndims != 1 ||
       dimids_var[0] != 0 || var_type != NC_BYTE) ERR;

   /* This is actually an NC_BYTE, with some negatives, so this should
    * generate a range error for netcdf-4, but not for netcdf-3,
    * because range errors are not generated for byte type
    * conversions. */
   res = nc_get_var_uchar(ncid, 0, uchar_in);
   if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
   {
      if (res != NC_ERANGE) ERR;
   }
   else if (res) ERR;

   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (uchar_in[i] != uchar_out[i] && uchar_in[i] != NC_FILL_UBYTE) ERR;
#else
      if (uchar_in[i] != uchar_out[i]) ERR;
#endif

   if (nc_get_var_schar(ncid, 0, char_in)) ERR;
   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (char_in[i] != (signed char)uchar_out[i] && char_in[i] != NC_FILL_BYTE) ERR;
#else
      if (char_in[i] != (signed char)uchar_out[i]) ERR;
#endif

   if (nc_get_var_short(ncid, 0, short_in)) ERR;
   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (short_in[i] != (signed char)uchar_out[i] && short_in[i] != NC_FILL_BYTE) ERR;
#else
      if (short_in[i] != (signed char)uchar_out[i]) ERR;
#endif

   if (nc_get_var_int(ncid, 0, int_in)) ERR;
   for (i=0; i<DIM1_LEN; i++)
#ifdef ERANGE_FILL
      if (int_in[i] != (signed char)uchar_out[i] && int_in[i] != NC_FILL_BYTE) ERR;
#else
      if (int_in[i] != (signed char)uchar_out[i]) ERR;
#endif

   if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC)
   {
      /* Since we wrote them as NC_BYTE, some of these are negative
       * values, and will return a range error when reading into
       * unsigned type. To compare values, first cast uchar_out to
       * signed int, then cast again to the type we are reading it
       * as. */
      if (nc_get_var_ushort(ncid, 0, ushort_in) != NC_ERANGE) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (ushort_in[i] != (unsigned short)(signed char)uchar_out[i]) ERR;

      if (nc_get_var_uint(ncid, 0, uint_in) != NC_ERANGE) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (uint_in[i] != (unsigned int)(signed char)uchar_out[i]) ERR;

      if (nc_get_var_ulonglong(ncid, 0, uint64_in) != NC_ERANGE) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (uint64_in[i] != (unsigned long long)(signed char)uchar_out[i]) ERR;

      if (nc_get_var_longlong(ncid, 0, int64_in)) ERR;
      for (i=0; i<DIM1_LEN; i++)
	 if (int64_in[i] != (signed char)uchar_out[i]) ERR;

   }

   if (nc_close(ncid)) ERR;
   return 0;
}
示例#7
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing specified endiannesss fill values.\n");
   printf("*** testing simple case with int...");
   {
      int  ncid, varid, var2id, var3id;
      int data_in;
      int fill = NC_FILL_INT;

      /* Create file with a scalar int var that's big-endian. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_INT, VAR_RANK, 0, &varid)) ERR;
      if (nc_def_var_endian(ncid, varid, NC_ENDIAN_BIG)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_INT, VAR_RANK, 0, &var2id)) ERR;
      if (nc_def_var_endian(ncid, var2id, NC_ENDIAN_LITTLE)) ERR;
      /* close without writing data, so vars 1 and 2 should contain
       * NC_FILL_INT */
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, VAR_RANK, 0, &var3id)) ERR;
      if (nc_def_var_endian(ncid, var3id, NC_ENDIAN_BIG)) ERR;
      if (nc_put_var(ncid, var3id, &fill)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR;
      if (nc_inq_varid(ncid, VAR2_NAME, &var2id)) ERR;
      if (nc_get_var_int(ncid, varid, &data_in)) ERR;
      if (data_in != NC_FILL_INT) ERR;
      if (nc_get_var_int(ncid, var2id, &data_in)) ERR;
      if (data_in != NC_FILL_INT) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing short, int, int64, and unsigned...");
   {
#define NUM_TYPES_TO_CHECK 6
      int  ncid, varid[NUM_TYPES_TO_CHECK];
      int check_type[NUM_TYPES_TO_CHECK] = {NC_SHORT, NC_USHORT, NC_INT,
					    NC_UINT, NC_INT64, NC_UINT64};
      char var_name[NUM_TYPES_TO_CHECK][NC_MAX_NAME + 1] = {"SHORT", "USHORT",
							   "INT", "UINT", "INT64",
							   "UINT64"};
      long long fill_value[NUM_TYPES_TO_CHECK] = {NC_FILL_SHORT, NC_FILL_USHORT, NC_FILL_INT,
						  NC_FILL_UINT, NC_FILL_INT64, NC_FILL_UINT64};
      long long data_in;
      int t;

      /* Create file with a scalar vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      for (t = 0; t < NUM_TYPES_TO_CHECK; t++)
      {
	 if (nc_def_var(ncid, var_name[t], check_type[t], 0, 0, &varid[t])) ERR;
	 if (nc_def_var_endian(ncid, varid[t], NC_ENDIAN_BIG)) ERR;
      }
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      for (t = 0; t < NUM_TYPES_TO_CHECK; t++)
      {
	 int err = nc_get_var_longlong(ncid, varid[t], &data_in);
	 if(err && err != NC_ERANGE)
	   ERR;
	 if (data_in != fill_value[t])
	   ERR;
      }
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;

   return 0;
}
示例#8
0
void write_ts(double wrts)
    {
    int i,j,k,m;
    int status;
    char message[144];
    int err;
    double *wrdy;
#ifdef WRTTS
    wrdy = malloc(sizeof(double));
#endif
    /********** set means to zero                                   */
    /*  2d variables */
    if (flags[8]) set_fix_darray2d_zero(mn_eaml);
    /*---------------------------------------
     *
     *     write tracer values on output field
     *
     *--------------------------------------*/

    printf("write output field\n");

    if (flags[8]) add_fix_darray2d(mn_eaml, eaml);
    //HF outer if, inner for loops, instead of vice versa!
    //HF think about writing appropriate subroutine(s)!!!
    if (flags[1]) copy_darray3d(mn_u, u, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_u[k][i][j] = u[k][i][j];
     } */
    if (flags[2]) copy_darray3d(mn_v, v, NZ, NXMEM, NYMEM);
    /* {
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_v[k][i][j] = v[k][i][j];
     }*/
    if (flags[3])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_h[k][i][j] = h[k][i][j];
	}
    if (flags[4]) copy_darray3d(mn_uhtm, uhtm, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_uhtm[k][i][j] = uhtm[k][i][j];
     }*/
    if (flags[5]) copy_darray3d(mn_vhtm, vhtm, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_vhtm[k][i][j] = vhtm[k][i][j];
     }*/
    if (flags[6])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_ea[k][i][j] = ea[k][i][j];
	}
    if (flags[7])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_eb[k][i][j] = Salttm[k][i][j];
	}
#ifdef AGE
    if (flags[9]) copy_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
#endif
    if (flags[18])
	{
	for (k=0;k<2;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_rml[k][i][j] = rml[k][i][j];
	}
	    printf("Writing variables for sub timestep %i out to netCDF\n\n",itts);
	    //  open netcdf file for each writing
	    status = nc_open(output_filename, NC_WRITE, &cdfid);
	    if (status != NC_NOERR)
		{
		strcpy(message,"Opening file"); strcat(message,output_filename);
		handle_error(message,status);
		}
	    *wrdy = wrts;
	    err = write_time(cdfid,fn,timeid[0],nrec, wrdy);
	    if (err == -1) printf("Error writing day.\n");

	    for (m=0;m<NOVARS;m++) if (flags[m])
		{
		err = write_field(cdfid, fn, vars[m], varinfo[varmap[m]],
			nrec,var[m]);
		if (err == -1) printf("Error writing %s.\n",vars[m].name);
		}
	    close_file(&cdfid, &fn);

	    printf("netcdf record = %d\n",nrec++);
	    }
示例#9
0
int main(void)
    {
    double inmon, tmon;
    double mon, nxt, lst;
    double *iyr;
    double *nyr;
    double dyr, day;
    double ndyr;
    double *dy;
    double dmon[12];
    double dbmon;
    double yearday;
    int imon, inxt, ilst;
# ifndef WRTTS
    int itts; /* tracer time step counter */
# endif
    int nmnfirst;
#ifdef SEPFILES
    double smon, snxt;
    int ismon, isnxt, ihnxt;
#endif

#ifndef WRTTS
    size_t nrec = 0;
#endif
    int err, i, j, k;
    int cmon;
    int nmn;
    double frac;
    static int m;
#ifndef WRTTS
    int varmap[NOVARS];

    FILE *fn;
    char output_filename[200];
#endif
    char run_name[200];
    char restart_filename[200];
    struct vardesc var_out[NOVARS];
#ifndef WRTTS
    struct varcdfinfo varinfo[NOVARS];
    int nvar = 0, cdfid, timeid[2];
#endif

    extern int flags[NOVARS];
    extern int rflags[NOVARS];

    //BX-a  for testing only
    int status;
    char message[144];
    //BX-e

    //BX  allocate tracer fields
    err = alloc_arrays();
    if (err)
	printf("Error allocating arrays.\n");

    err = alloc_trac();
    if (err)
	printf("Error allocating tracer field.\n");

    iyr = malloc(sizeof(double));
    nyr = malloc(sizeof(double));
    dy = malloc(sizeof(double));

    mlen[0] = 31; /* January      */
    mlen[1] = 28; /* February     */
    mlen[2] = 31; /* March        */
    mlen[3] = 30; /* April        */
    mlen[4] = 31; /* May          */
    mlen[5] = 30; /* June         */
    mlen[6] = 31; /* July         */
    mlen[7] = 31; /* August       */
    mlen[8] = 30; /* September    */
    mlen[9] = 31; /* October      */
    mlen[10] = 30; /* November     */
    mlen[11] = 31; /* December     */

    dmon[0] = 0.0;

    for (i = 1; i <= 11; i++)
	{
	dmon[i] = dmon[i - 1] + mlen[i - 1];
	}

    /*----------------------------------*
     *
     *     get user input
     *
     *----------------------------------*/

    {
    char line[100];
    int scan_count, done = 1;

    printf("Enter directory to use to read.\n");
    fgets(directory, sizeof(directory), stdin);

    directory[strlen(directory) - 1] = '\0';
    k = strlen(directory);
    if (k > 0)
	if (directory[k - 1] != '/')
	    {
	    directory[k] = '/';
	    directory[k + 1] = '\0';
	    printf("Using directory %s first.\n", directory);
	    }

    strcat(directory, fname);
    strcpy(fname, directory);
    printf("file path = %s\n", fname);

    while (done)
	{

	printf(
		"\nEnter the starting month and the total months to integrate.\n");

	fgets(line, sizeof(line), stdin);
	line[strlen(line) - 1] = '\0';
	scan_count = sscanf(line, "%lg, %lg,", &inmon, &tmon);
	if (scan_count == 2)
	    {
	    if (inmon < 0 || tmon < 0)
		printf("Negative values not allowed\n");
	    else
		done = 0;
	    }
	else
	    printf("Incorrect number of values, %d, read.\n", scan_count);
	}

    printf("\ninitial month = %g \n", inmon);
    printf("final month = %g \n", inmon + tmon - 1);
    printf("total months = %g \n\n", tmon);

    /*-----------------------------------
     *
     *     set output print flags to 0
     *
     *     added restart flags as a restart bug fix until
     *     memory restriction problem is solved 31OCT07 BX
     *
     *----------------------------------*/

    for (i = 0; i <= NOVARS - 1; i++)
	flags[i] = 0;
    for (i = 0; i <= NOVARS - 1; i++)
	rflags[i] = 0;

    flags[1] = 0;
    flags[2] = 0; /* u,v */
    rflags[1] = 0;
    rflags[2] = 0; /* u,v */
    flags[0] = 0;
    flags[3] = 0; /* D, h */
    rflags[0] = 0;
    rflags[3] = 0; /* D, h */
    flags[4] = 0;
    flags[5] = 0; /* uhtm, vhtm */
    rflags[4] = 0;
    rflags[5] = 0; /* uhtm, vhtm */
    flags[6] = 0;
    flags[7] = 0;
    flags[8] = 0; /* ea, eb, eaml */
    flags[18] = 0; /* ML potential density */
    rflags[18] = 0; /* ML potential density */
#ifdef AGE
    flags[9] = 1;
    rflags[9] = 1; /* ideal age tracer*/
#endif

    printf("Enter base name for output\n");

    fgets(run_name, sizeof(run_name), stdin);
    run_name[strlen(run_name) - 1] = '\0';
    sprintf(output_filename, "%s.%04g.nc", run_name, inmon + tmon - 1);
    printf("Create NetCDF output file '%s'.\n", output_filename);



    } // end of block "get user input"

    //DT
    lastsave = -1;
    //DT

    /*-----------------------------------
     *
     *     allocate and initialize fields
     *
     *----------------------------------*/

    read_grid();
    printf("Done reading grid or metric file.\n");

    set_metrics();
    printf("Done setting metrics.\n");

    /* Copy the variable descriptions to a list of the actual output variables. */
    for (i = 0; i < NOVARS; i++)
	if (flags[i] > 0)
	    {
	    var_out[nvar] = vars[i];
	    varmap[i] = nvar;
	    nvar++;
	    }
    // force float precision output with last argument
    printf("Making NETCDF %s file\n", output_filename);
    create_file(output_filename, NETCDF_FILE, var_out, nvar, &fn, &cdfid,
	    timeid, varinfo, 1);
    // don't force
    // create_file(output_filename, NETCDF_FILE, var_out, nvar, &fn, &cdfid, timeid, varinfo, 0);
    printf("Closing file \n");
    close_file(&cdfid, &fn);

    /* Allocate the memory for the fields to be calculated.		*/
    alloc_fields();

    /* initialize tracer pointers					*/

    for (m = 0; m < NOVARS; m++)
	{
	if (flags[m])
	    for (k = 0; k < varsize[m]; k++)
		var[m][k] = 0.0;
	}

    /********** set means to zero                                   */
    /*  2d variables */
    if (flags[8])
	set_fix_darray2d_zero(mn_eaml);


    /*  3d variables */
    if (flags[1])
	set_darray3d_zero(mn_u, NZ, NXMEM, NYMEM);
    if (flags[2])
	set_darray3d_zero(mn_v, NZ, NXMEM, NYMEM);
    if (flags[3])
	set_darray3d_zero(mn_h, NZ, NXMEM, NYMEM);
    if (flags[4])
	set_darray3d_zero(mn_uhtm, NZ, NXMEM, NYMEM);
    if (flags[5])
	set_darray3d_zero(mn_vhtm, NZ, NXMEM, NYMEM);
    if (flags[6])
	set_darray3d_zero(mn_ea, NZ, NXMEM, NYMEM);
    if (flags[7])
	set_darray3d_zero(mn_eb, NZ, NXMEM, NYMEM);
#ifdef AGE
    if (flags[9])
	set_darray3d_zero(mn_age, NZ, NXMEM, NYMEM);

#endif
    printf("Reading bathymetry, D.\n");

    // initialize D to be all ocean first

    for (i = 0; i <= NXMEM - 1; i++)
	{
	for (j = 0; j <= NYMEM - 1; j++)
	    {
	    D[i][j] = MINIMUM_DEPTH;
	    }
	}
#ifndef USE_CALC_H
    printf("calling read_D\n");
    read_D();

    for (i = 0; i <= NXMEM - 1; i++)
	for (j = 0; j <= NYMEM - 1; j++)
	    if (D[i][j] < 10.0)
		D[i][j] = MINIMUM_DEPTH;
#endif

    read_grid();
    set_metrics();

    dyr = inmon / 12;
    smon = (double) ((int) inmon % NMONTHS);
    mon = 12 * modf(dyr, iyr);

    printf("\n initial mon = %g - %g - %g \n\n", inmon, smon, mon);


    imon = (int) (mon + 0.00001);
    /* Begin edit DT */
    int iyear = floor((inmon + imon) / 12);
    theyear = iyear;
#ifdef RESTART
    theyear++;
    iyear++;
#endif
    /*  End edit DT  */
    inxt = imon + 1;

    ismon = (int) (smon + 0.00001) % NMONTHS;

    isnxt = (ismon+1) % NMONTHS;
    ihnxt = (ismon+2) % NMONTHS;

    dbmon = (double) inmon;
    lst = 12 * modf((dbmon - 1 + 12) / 12, iyr);
    ilst = (int) (lst + 0.00001);

    // ashao: Read in next month's isopycnal thickness fields
    // (will be copied at the beginning of the integration)
    // Done this way so that if hindcasts are used the physical fields switch smoothly
    // to/from climatological fields
    //BX  files are not in regular order (uvw are midmonth and h starts with last month)

        currtime = BEGYEAR;
    if (usehindcast) {
        // Check to see if simulation started within the hindcast years
        if ( (currtime >= BEGHIND) || (currtime < (ENDHIND+1) ) ) {
        	hindindex=inmon;
        	read_h(ismon,hend,"hind");
        }
    }
    else {
    	read_h(ismon, hend,"clim");
    }
    // for files in regular order (h before uvw) use code here
    //BX
    // read_uvw(imon,1);
    //BX
    // read_h(imon,inxt);



#ifdef USE_CALC_H
    z_sum(h, D);
#endif
    printf("\nSetting up and initializing\n");

#ifdef RESTART
    initialize(inmon,run_name);
#else
    initialize(imon);
#endif
    nmn = 0;

    //HF the next line should be in init.h (and be optional!)
#undef OUTPUT_IC
#ifdef OUTPUT_IC
    /*-----------------------------------
     *
     *     write tracer initial conditions
     *
     *----------------------------------*/

    printf("Writing initial condition variables out to netCDF\n\n",cmon);

    //  open netcdf file for each writing
    status = nc_open(output_filename, NC_WRITE, &cdfid);
    if (status != NC_NOERR)
	{
	strcpy(message,"Opening file"); strcat(message,output_filename);
	handle_error(message,status);
	}

    err = write_time(cdfid,fn,timeid[0],nrec, dy);
    if (err == -1) printf("Error writing day.\n");

    if (flags[3])
	{
	for (k=0;k<NZ;k++)
	    for (i=0;i<NXMEM;i++)
		for (j=0;j<NYMEM;j++)
		    mn_h[k][i][j] += h[k][i][j];
	}

#ifdef AGE
    if (flags[9]) add_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
    /*{
     for (k=0;k<NZ;k++)
     for (i=0;i<NXMEM;i++)
     for (j=0;j<NYMEM;j++)
     mn_age[k][i][j] += age[k][i][j];
     }*/
#endif /* AGE */


    for (m=0;m<NOVARS;m++) if (flags[m])
	{
	err = write_field(cdfid, fn, vars[m], varinfo[varmap[m]],
		nrec,var[m]);
	if (err == -1) printf("Error writing %s.\n",vars[m].name);
	}
    //  close file after each writing
    close_file(&cdfid, &fn);
    printf("netcdf record = %d\n",nrec++);
#endif /* OUTPUT_IC */




    /*-------------------------------------------------------------------*
     *
     *     begin integration loop
     *
     *-------------------------------------------------------------------*/

    mon = 0.0; /* reiniti */
    nmnfirst = 1;


    for (cmon = inmon; cmon < inmon + tmon; cmon++)
	{
	nmn++;

	dyr = cmon / 12.0;
	ndyr = (cmon + 1) / 12.0;

	dbmon = (double) cmon;
	lst = 12 * modf((dbmon - 1 + 12) / 12, iyr);
	ilst = (int) (lst + 0.00001);
	printf("double-mon=%g,lastmon=%g,ilst=%i\n", dbmon, lst, ilst);


	smon = (double) ((int) cmon % NMONTHS);
	snxt = (double) ((int) (cmon + 1) % NMONTHS);

	mon = 12.0 * modf(dyr, iyr);
	nxt = 12.0 * modf(ndyr, nyr);

	printf("the current month is %i-%g-%g \n", cmon, smon, mon);
	printf("the current year is %g \n", *iyr);

	imon = (int) (mon + 0.00001);
	inxt = (int) (nxt + 0.00001);

	ismon = (int) (smon + 0.00001);
	isnxt = (int) (snxt + 0.00001);

	yearday = 0;
	for (i=0;i<=imon;i++) yearday += dmon[imon];
	currtime = *iyr + BEGYEAR + yearday/365.0;

	day = (*iyr) * 365.0 + dmon[imon];
	*dy = currtime;

	printf("the current day is -%g- \n", *dy);
	printf("the current ismon/smon is -%i-%g- \n", ismon, smon);
	printf("the next smonth/mean index: -%i- \n", isnxt);

	dt = ((double) mlen[imon]);
	dt = dt * 86400 / (double) NTSTEP;


	for (itts = 1; itts <= NTSTEP; itts++)
	    {
	    printf("\nSub time step number= %i \n", itts);
	    /*-----------------------------------
	     *
	     *     get physical fields and bc's
	     *
	     *----------------------------------*/

	    printf("Month %d timestamp Start: %4.2f End: %4.2f\n",cmon,currtime,currtime+dt/31536000);
	    currtime += dt / 31536000; //ashao: advance currenttime
	    copy_2fix_darray3d(hstart,hend,NZ,NXMEM,NYMEM);
	    copy_2fix_darray3d(h,hstart,NZ,NXMEM,NYMEM);
	    if (usehindcast) {
	        if ( ( cmon >= starthindindex) && ( hindindex <= (numhindmonths-1) )) {
			
			printf("Reading in UVW from hindcast\n");
	        	read_uvw(hindindex,"hind");
		        read_h(hindindex,hend,"hind");
	        	hindindex++;
	        }
		else {
		
		printf("Reading in UVW from climatology\n");
	    	read_uvw(isnxt,"clim");
	    	read_h(isnxt, hend,"clim");
		}
	    }
	    else {
		printf("Reading in UVW from climatology\n");
	    	read_uvw(isnxt,"clim");
	    	read_h(isnxt, hend,"clim");
	    }
	    printf("Month- hstart:%d hend:%d\n",ismon,isnxt);

	    /*-----------------------------------
	     *
	     *     integrate 1 time step
	     *
	     *----------------------------------*/

	    printf("step fields - day = %g\n\n", day);
	    step_fields(iyear, itts, imon, iterno); // modified ashao


	    /*-------------------------------------------------------------------*
	     *
	     *     end integration loop
	     *
	     *-------------------------------------------------------------------*/

	    /*-----------------------------------
	     *
	     *     calculate tracer averages
	     *
	     *----------------------------------*/

	    printf("calculate tracer averages\n");

	    if (flags[8])
		add_fix_darray2d(mn_eaml, eaml);
	    if (flags[1])
		add_darray3d(mn_u, u, NZ, NXMEM, NYMEM);
	    if (flags[2])
		add_darray3d(mn_v, v, NZ, NXMEM, NYMEM);
	    if (flags[3])
		{
		for (k = 0; k < NZ; k++)
		    for (i = 0; i < NXMEM; i++)
			for (j = 0; j < NYMEM; j++)
			    {
			    mn_h[k][i][j] += h[k][i][j];
			    }
		}
	    if (flags[4])
		add_darray3d(mn_uhtm, uhtm, NZ, NXMEM, NYMEM);
	    if (flags[5])
		add_darray3d(mn_vhtm, vhtm, NZ, NXMEM, NYMEM);
	    if (flags[6])
		add_darray3d(mn_ea, ea, NZ, NXMEM, NYMEM);
	    if (flags[7])
		add_darray3d(mn_eb, eb, NZ, NXMEM, NYMEM);
#ifdef AGE
	    //DT
	    //    if (flags[9]) add_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
	    if (flags[9])
	    {
	    	for (k = 0; k < NZ; k++)
	    	{
	    		for (i = 0; i < NXMEM; i++)
	    		{
	    			for (j = 0; j < NYMEM; j++)
	    			{
	    				if (age[k][i][j] > 0.0)
	    				{
	    					{
	    						mn_age[k][i][j] += age[k][i][j];
	    					}
	    				}}}}}

	    				//DT
#endif
	    if (flags[18])
		{
		for (k = 0; k < 2; k++)
		    for (i = 0; i < NXMEM; i++)
			for (j = 0; j < NYMEM; j++)
			    mn_rml[k][i][j] += rml[k][i][j];
		}


	    /* calculate the mean */

	    if (nmn == WRINT && itts == 1)
		{
		printf("***nmn= %i, itts= %i, nmnfirst= %i\n", nmn, itts,
			nmnfirst);
		frac = 1.0 / ((double) nmn * (double) NTSTEP);

		if (flags[8])
		    mult_fix_darray2d(mn_eaml, frac);
		if (flags[1])
		    mult_darray3d(mn_u, NZ, NXMEM, NYMEM, frac);
		if (flags[2])
		    mult_darray3d(mn_v, NZ, NXMEM, NYMEM, frac);
		if (flags[3])
		    mult_darray3d(mn_h, NZ, NXMEM, NYMEM, frac);
		if (flags[4])
		    mult_darray3d(mn_uhtm, NZ, NXMEM, NYMEM, frac);
		if (flags[5])
		    mult_darray3d(mn_vhtm, NZ, NXMEM, NYMEM, frac);
		if (flags[6])
		    mult_darray3d(mn_ea, NZ, NXMEM, NYMEM, frac);
		if (flags[7])
		    mult_darray3d(mn_eb, NZ, NXMEM, NYMEM, frac);
#ifdef AGE
		if (flags[9])
		    mult_darray3d(mn_age, NZ, NXMEM, NYMEM, frac);
#endif

		if (flags[18])
		    mult_darray3d_mv(mn_rml, 2, NXMEM, NYMEM, frac, D, misval);

		/*-----------------------------------
		 *
		 *     write tracer averages and reset to 0
		 *
		 *----------------------------------*/
		printf("Writing month %i variables out to netCDF\n\n", cmon);

		status = nc_open(output_filename, NC_WRITE, &cdfid);
		if (status != NC_NOERR)
		    {
		    strcpy(message, "Opening file");
		    strcat(message, output_filename);
		    handle_error(message, status);
		    }

		err = write_time(cdfid, fn, timeid[0], nrec, dy);
		if (err == -1)
		    printf("Error writing day.\n");

		for (m = 0; m < NOVARS; m++)
		    if (flags[m]==1)
			{
			printf("m = %d\n",m);
			err = write_field(cdfid, fn, vars[m],
				varinfo[varmap[m]], nrec, var[m]);
			if (err == -1)
			    printf("Error writing %s.\n", vars[m].name);
			}
		close_file(&cdfid, &fn);

		/*    reset all means to zero */
		nmn = 0;
		if (flags[8])
		    set_fix_darray2d_zero(mn_eaml);
		if (flags[1])
		    set_darray3d_zero(mn_u, NZ, NXMEM, NYMEM);
		if (flags[2])
		    set_darray3d_zero(mn_v, NZ, NXMEM, NYMEM);
		if (flags[3])
		    set_darray3d_zero(mn_h, NZ, NXMEM, NYMEM);
		if (flags[4])
		    set_darray3d_zero(mn_uhtm, NZ, NXMEM, NYMEM);
		if (flags[5])
		    set_darray3d_zero(mn_vhtm, NZ, NXMEM, NYMEM);
		if (flags[6])
		    set_darray3d_zero(mn_ea, NZ, NXMEM, NYMEM);
		if (flags[7])
		    set_darray3d_zero(mn_eb, NZ, NXMEM, NYMEM);
		if (flags[18])
		    set_darray3d_zero(mn_rml, 2, NXMEM, NYMEM);
#ifdef AGE
		if (flags[9])
		    set_darray3d_zero(mn_age, NZ, NXMEM, NYMEM);

#endif
		// begin ashao
		// end ashao

		printf("netcdf record = %d\n", nrec + 1);
		nrec++;

		} /*  end if nmn==WRITEINT */

	    /*-------------------------------------------------------------------*
	     *
	     *     end integration loop
	     *
	     *-------------------------------------------------------------------*/

	    } /* end itts loop over NTSTEP */
	} /* end while */

    //BX-a
    /*-----------------------------------
     *
     *     write restart file
     *
     *----------------------------------*/

    //   First write the up-to-date tracer values to the mean fields.
    //   In order to save memory the instantaneous values for the
    //   restart will be written on mean fields in the restart file.

    printf("start of array copying\n");
    //HF #ifdef SMOOTH_REST
    copy_fix_darray3d(mn_h, h, NZ, NXMEM, NYMEM);
    //HF #endif
#ifdef AGE
    copy_darray3d(mn_age, age, NZ, NXMEM, NYMEM);
#endif
    for (k = 0; k < NZ; k++)
	{
	for (i = 0; i < NXMEM; i++)
	    {
	    for (j = 0; j < NYMEM; j++)
		{
		} /* for j loop */
	    } /* for i loop */
	} /* for k loop */

    //  Second, create restart file name and open file

    sprintf(restart_filename, "restart.%s.%04d.nc", run_name, cmon);
    printf("Writing NetCDF restart file '%s'.\n\n", restart_filename);

    /* Copy the variable descriptions to a list of the actual restart variables. */
    nvar = 0;
    for (i = 0; i < NOVARS; i++)
	if (rflags[i] > 0)
	    {
	    var_out[nvar] = vars[i];
	    varmap[i] = nvar;
	    nvar++;
	    }

    // do NOT force float precision output with last argument
    create_file(restart_filename, NETCDF_FILE, var_out, nvar, &fn, &cdfid,
	    timeid, varinfo, 0);

    for (m = 0; m < NOVARS; m++)
	if (rflags[m])
	    {
	    err = write_field(cdfid, &fn, vars[m], varinfo[varmap[m]], 0,
		    var[m]);
	    if (err == -1)
		printf("Error writing %s.\n", vars[m].name);
	    }

    close_file(&cdfid, &fn);

    printf("\n programme termine normallement. \n");
    return (0);
    }
示例#10
0
int ReadCDFFile(char *name, InputSection section)
{
  int cdfid, i, j, *dimdim, dimfound, ndim, nvar, natt, recdim, *dim,
    nvarfound, bigdim = 0, coordfound = 0, mem, pointvalues;
  static int ncoord = 0;
  FILE *f;
  BOOL timedvar, noclose = FALSE;
  VarDesc *v, vh, *vo;
  Coordinate *coord = NULL;
  size_t start[1], count[1];
  ptrdiff_t stride[1], imap[1];
  const struct  {
    char name[5];
    Dimension dim;
    int *size;
  }  dimtab[] = {"X", X_DIM, &nxm, "Y", Y_DIM, &nym, "Z", Z_DIM, &nz, "Time", TIME_DIM, NULL,
  	         "CNT",
  	         COUNT_DIM,
  	         &ncoord};
  char txt[MAX_NC_NAME];
  BorderTimeDesc *bt;
  size_t *coords, len, *dimptr[5], lcoord[5], ntimes;
  long *timetable = NULL;
  double *doubtable;
  nc_type datatype;
  if (section == GRID || section == TIME || section == DEPOSITION)  {
    InputError(ERROR, "CDFIMPORT is not allowed in this section.");
    return (1);
  }
  if (!(f = fopen(name, "r")))  {
    InputError(ERROR, "Unable to open CDF-File \"%s\".", name);
    return (1);
  }
  fclose(f);
  if (nc_open(name, NC_NOWRITE, &cdfid))  {
    InputError(ERROR, "Unable to open CDF-File %s.", name);
    return (1);
  }
  nc_inq(cdfid, &ndim, &nvar, &natt, &recdim);
  dim = (int *)calloc(ndim, sizeof(int));
  dimdim = (int *)calloc(ndim, sizeof(int));
  nvarfound = dimfound = 0;
  for (i = ndim; i--; )  {
    nc_inq_dim(cdfid, i, txt, &len);
    for (j = 5; --j >= 0 && strcmp(txt, dimtab[j].name); );
    dimdim[i] = j;
    if (j >= 0 && dimtab[j].size)  {
      if (j < 2)  {
        if (len != *dimtab[j].size && len != *dimtab[j].size+2)  {
          InputError(WARNING, "\"%s\": Dimension %s has wrong size. Is %i should be %i or %i.",
             name, txt, len, *dimtab[j].size, *dimtab[j].size+2);
          dimdim[i] = -1;
        }
        else  {
          dimfound |= 1 << j;
          if (len == *dimtab[j].size+2)  bigdim |= 1 << j;
        }
      }
      else if (j < 4)  {
        if (len != *dimtab[j].size)  {
          InputError(WARNING, "\"%s\": Dimension %s has wrong size. Is %i should be %i.",
             name, txt, len, *dimtab[j].size);
          dimdim[i] = -1;
	}
	else  dimfound |= 1 << j;
      }
      else  {
        *dimtab[j].size = len;
        dimfound |= 1 << j;
      }
    }
    if (j == 3)  ntimes = len;
  }
  if (bigdim && bigdim != ((X_DIM | Y_DIM) & dimfound))  {
    InputError(ERROR, "Mismatch of X/Y-Dimension-sizes.");
    goto error_end;
  }
  bigdim = !!bigdim;
  for (i = nvar; i--; )  {
    nc_inq_var(cdfid, i, txt, &datatype, &ndim, dim, &natt);
    for (v = variable; v && strcmp(txt, v->name); v = v->next);
    if (v)  {
      vo = v;
      if (v->storetype == GRID_VAL &&
	  actualsection->id >= NORTH_BORDER && actualsection->id <= EAST_BORDER)
	v = BorderVariable(v, &vh);
      if (v->storetype == GRID_VAL && actualsection->id == EMISSIONS)  {
        pointvalues = (ndim < 3 && (dimdim[*dim] == 4 || dimdim[dim[1]] == 4) ? *dimtab[4].size : 0);
	if (pointvalues && !coord)  coord = AllocateCoordVar(pointvalues);
        v = EmissionVariable(v, pointvalues, 0, coord);
      }
      if (v->section == section)  {
	if (v->inputtype != NORMAL_NUM)  {
	  InputError(WARNING, "The Variable %s cannot be set via a CDF-File.\n",
	     inplineno, txt);
	  continue;
	}
	if (datatype != NC_DOUBLE && datatype != NC_FLOAT && datatype != NC_LONG)  {
	  InputError(ERROR, "\"%s\": The type of variable %s is not of appropriate type.",
	     name, txt);
	  goto error_end;
	}
	if (v->init == WAS_SET_BY_USER)  {
	  InputError(WARNING, "The variable \"%s\" found in file \"%s\" is already initialized.",
	     txt, name);
	  if (section == EMISSIONS)
	    InputError(WARNING, " ....so summing up emissions.\n");
	  else
	    continue;
	}
	if (v->init == CALCULATED_VALUES)  {
	  InputError(WARNING, "The variable \"%s\" found in file \"%s\" cannot be initialized.\n"
	             "         It's calculated by meteochem.", txt, name);
	  continue;
	}
	if ((v->option & STARTING_WITH_ZERO) && !bigdim)  {
	  InputError(ERROR, "Variable \"%s\" requires Dimensions X and Y to be two fields bigger",
	     v->name);
	  goto error_end;
	}
	memset(dimptr, 0, 5 * sizeof(*dimptr));
	for (j = ndim; --j >= 0 && dimdim[dim[j]] != 3; );
	if (timedvar = j >= 0)  {
	  if (actualsection->id < ENVIRONMENT || actualsection->id == INITIAL_DATA)  {
	    InputError(ERROR, "Time-dependent variables are not allowed in this section.");
	    goto error_end;
	  }
	  noclose = TRUE;
	  bt = (BorderTimeDesc *)malloc(sizeof(BorderTimeDesc));
	  if (v->dims == (X_DIM | Z_DIM))
	    bt->vartype = XWALL_VAR;
	  else if (v->dims == (Y_DIM | Z_DIM))
	    bt->vartype = WALL_VAR;
	  else if (v->dims == (X_DIM | Y_DIM))
	    bt->vartype = (v->storetype == GROUND_PARAM ? GROUND_VAR : LAYER_VAR);
	  else if (v->dims == Z_DIM)
	    bt->vartype = PROFILE_VAR;
	  else if (v->dims == ALL_DIM)
	    bt->vartype = MESH_VAR;
	  else if (v->dims == COUNT_DIM)
	    bt->vartype = COORD_VAR;
	  else  {
	    InputError(ERROR, "The variable \"%s\" must not be time-dependent.", v->name);
	    goto error_end;
	  }
	  bt->section = InputSection(actualsection->id);
	  bt->bigdim = bigdim;
	  bt->ntime = ntimes;
	  bt->itime = -1;
	  bt->actime = 0;
	  bt->cdfid = cdfid;
	  bt->vid = i;
	  bt->actualvar = *v;
	  bt->nextvar = *v;
	  bt->timetable = timetable;
	  coords = bt->coords;
	  bt->actualdata.d = v->v.d;
	  switch (bt->vartype)  {
	    case XWALL_VAR :
	       mem = xrow*nz;
	       break;
	    case WALL_VAR :
	       mem = row*nz;
	       break;
	    case GROUND_VAR :
	       bt->nextvar.storetype = DOUBLE_PTR;
	    case LAYER_VAR :
	       mem = layer;
	       break;
	    case PROFILE_VAR :
	       mem = nz;
	       break;
	    case MESH_VAR :
	       mem = mesh;
	       break;
	    case COORD_VAR :
	       mem = v->ncoord;
	       break;
	  }
	  bt->nextdata = (double *)calloc(mem, sizeof(double));
	  if (!(bt->nextvar.v.d = bt->nextdata))  {
	    InputError(ERROR, "Unable to allocate memory in Function \"ReadCDFFile\"");
	    goto error_end;
	  }
	  bt->next = bordertime;
	  bordertime = bt;
	}
	else  coords = lcoord;
	for (j = ndim; j--; )  {
	  if (dimdim[dim[j]] < 0)  {
	    nc_inq_dim(cdfid, dim[j], txt, &len);
	    InputError(ERROR, "\"%s\": Variable %s includes \"%s\", an unkown or unusable dimension.",
	       name, v->name, txt);
	    goto error_end;
	  }
	  dimptr[dimdim[dim[j]]] = coords + j;
	}
	for (j = 5; j--; )
	  if (!dimptr[j])  dimptr[j] = coords + ndim++;
	printf("Reading Variable %s from CDF-File \"%s\"\n", txt, name);
	*dimptr[3] = 0;
	nvarfound++;
	vo->init = WAS_SET_BY_USER;
	if (ReadVarFromCDF(cdfid, i, v, dimptr, coords, !!bigdim))  goto error_end;
	if (timedvar)  memcpy(bt->dimptr, dimptr, 5 * sizeof(long *));
      }
      else if (!strcmp(txt, "Time"))  {
        timetable = (long *)calloc(ntimes, sizeof(long));
        *lcoord = 0;
        if (nc_get_vara_long(cdfid, i, lcoord, &ntimes, timetable))  {
          InputError(ERROR, "A variable called \"Time\" was found, but I couldn't read it.");
        }
        else  {
          if (*timetable > tstart)
            InputError(WARNING, "The first time-slice for value for %s is later (%ld sec) than tstart(%ld sec).",
               v->name, *timetable, tstart);
          for (bt = bordertime; bt; bt = bt->next)
            if (!bt->timetable)  bt->timetable = timetable;
        }
      }
    }
    else if (!strcmp(txt, "XCoord") || !strcmp(txt, "YCoord") || !strcmp(txt, "ZCoord"))  {
      if (ndim == 1 && dimdim[*dim] == 4)  {
	if (!coord)  coord = AllocateCoordVar(*dimtab[4].size);
	*start = 0;
	*count = *dimtab[4].size;
	*stride = 1;
	*imap = &coord[1].x - &coord[0].x;
	nc_get_varm_float(cdfid, i, start, count, stride, imap,
	      &coord[0].x + (*txt - 'X'));
	coordfound |= 1 << (*txt - 'X');
      }
    }
  }
  if (coord)
    if (coordfound != 7)  {
      InputError(ERROR, "Not all necessary coordinates found in file \"%s\".", name);
      goto error_end;
    }
    else
      ConvertEmissionCoords(*dimtab[4].size, coord, 0);
  if (!noclose)  nc_close(cdfid);
  free(dim);
  if (!nvarfound)
    InputError(WARNING, "No usable Variable found in File \"%s\".", name);
  return (0);
error_end :
  nc_close(cdfid);
  free(dim); free(dimdim);
  return (1);
}
示例#11
0
int
Ensemble::getTimes(std::string &str)
{
  // reading netcdf files
  int ncid, dimid, varid, status;

  size_t recSize, len;
  size_t index=0;
  double val ;
  int retVal=0;

  std::string begStr;
  std::string endStr;

  for( size_t i=0 ; i < member.size() ; ++i )
  {
     if( nc_open( member[i]->getFile().c_str(), 0, &ncid) )
     {
       isInvalid = true;
       member[i]->state = "could not open file";
       continue;
     }

     nc_inq_unlimdim(ncid, &dimid) ;

     if( dimid == -1 )
        // try for a regular dimension time
        nc_inq_dimid(ncid, "time", &dimid);

     // no unlimited variable found; this is not
     // neccessarily an error.
     if( dimid == -1 )
     {
       isNoRec = true;
       nc_close(ncid);

       if( sz == 1 )
       	 return 0; // a single file
       else
         retVal=4;

       isInvalid = true;
       member[i]->state += "missing time dimension";
       continue;
     }

     if( (status = nc_inq_dimlen(ncid, dimid, &recSize) ) )
     {
       isInvalid = true;
       member[i]->state = "could not read time dimension";
       nc_close(ncid);
       continue;
     }

     if( status == 0 && recSize == 0 )
     {
       // this could be wrong
       // or just a fixed variable with time dimension defined.
       isNoRec = true;
       nc_close(ncid);

       if( sz == 1 )
      	  return 0;

       isInvalid = true;
       member[i]->state = "no time values available";
       continue;
     }

     if( (status = nc_inq_varid(ncid, "time", &varid) ) )
     {
       isNoRec = true;
       nc_close(ncid);

       if( sz == 1 )
      	  return 0;

       member[i]->state = "missing time variable";
       continue;
     }

     // reference calendar
     std::vector<std::string> vs;

     if( getAttText(ncid, varid, "calendar", vs) )
     {  // failure
       member[i]->state = "missing or invalid calendar attribute";
       nc_close(ncid);
       continue;
     }
     else
       // successful reading of calendar
       member[i]->refDate.setCalendar(vs[0]) ;

       // reference date
     if( getAttText(ncid, varid, "units", vs) )
     {  // failure
         member[i]->state = "missing or invalid units attribute";
         nc_close(ncid);
         continue;
     }
     else
     {
       if( vs[0].find("%Y") < std::string::npos )
          member[i]->refDate.setFormattedDate();
       else
          member[i]->refDate = vs[0] ;
     }

     // time values: fist and last
     index=0;
     if( (status = nc_get_var1_double(ncid, varid, &index, &val) ) )
     {
        if( sz > 1 )
        {
          isInvalid = true;
          member[i]->state = "could not read first time value";
          nc_close(ncid);
          continue;
        }
     }

     // any reasonable values available?
     nc_type var_type ;
     status = nc_inq_vartype(ncid, varid, &var_type) ;

     // return value type is double
     double fV;
     int noFill=0;
     int statusF = nc_inq_var_fill(ncid, varid, &noFill, &fV);

     if( noFill != 1 && (statusF || val == fV) )
     {
        isInvalid = true;
        member[i]->state = "first time value equals _FillValue";
        nc_close(ncid);
        continue;
     }

     if(member[i]->refDate.isValid(val))
       member[i]->setBegin( member[i]->refDate.getDate(val) );
     else
     {
       isInvalid=true;
       retVal=5;
       member[i]->putState("invalid data, found " + hdhC::double2String(val), false);
       nc_close(ncid);
       continue;
     }

     index=recSize-1;
     if( (status = nc_get_var1_double(ncid, varid, &index, &val) ) )
     {
        if( sz > 1 )
        {
          isInvalid = true;
          member[i]->putState("could not read last time value");
          nc_close(ncid);
        }
     }

     if( noFill != 1 && (statusF || val == fV) )
     {
        isInvalid = true;
        member[i]->putState("last time value equals _FillValue");
        nc_close(ncid);
        continue;
     }

     if(member[i]->refDate.isValid(val))
       member[i]->setEnd( member[i]->refDate.getDate(val) );
     else
     {
       isInvalid=true;
       retVal=5;
       member[i]->putState("invalid data, found " + hdhC::double2String(val), false);
     }

     nc_close(ncid);
  }

  // any serious conditions
  if( isInvalid )
  {
     // only files with annotations
     enablePrintOnlyMarked();
     str = getOutput();

    if( retVal )
      return retVal;
    else
      return 3 ;  // unspecific error
  }

  // get modification times of files
  for(size_t i=0 ; i < member.size() ; ++i )
    member[i]->getModificationTime() ;

  // sorted vector of pointers of dates
  sortDate();

  return 0;
}
示例#12
0
文件: file.c 项目: Unidata/netcdf-c
int
main()
{
   /* These are netCDF IDs for file, dimension, and variable. */
   int ncid, dimid, varid;

   /* This array will hold one ID for each dimension in the
      variable, in this case, one. */
   int dimids[NUMDIMS];

   /* This is some one-dimensional phoney data to write and read. */
   int data_out[] = {0,1,2,3,4,5,6,7,8,9};
   int data_in[DIMLEN];

   int i, res;

   /* Create a classic format netCDF file, overwritting any file of
      this name that may already exist. */
   if ((res = nc_create(FILENAME, NC_CLOBBER, &ncid)))
      BAIL(res);

   /* Define a dimension. The functions will return a dimension ID to
      dimid. */
   if ((res = nc_def_dim(ncid, DIMNAME, DIMLEN, &dimid)))
      BAIL(res);

   /* Define a variable. First we must specify which dimensions this
      variable uses, by adding their dimension IDs to the dimids array
      that we pass into nc_def_var. In this example, there is just one
      dimension. */
   dimids[0] = dimid;
   if ((res = nc_def_var(ncid, VARNAME, NC_INT, NUMDIMS, dimids, &varid)))
      BAIL(res);

   /* The enddef function tells the library that we are done with
      defining metadata in the newly-created file, and now want to
      write some data. */
   if ((res = nc_enddef(ncid)))
      BAIL(res);

   /* Write our phoney integer data. Since we've already specified the
      shape of this variable, we only need to provide a pointer to the
      start of the data. */
   if ((res = nc_put_var_int(ncid, varid, data_out)))
      BAIL(res);

   /* Close the file. This flushes all buffers and frees any resources
      associated with the file. We are closing the file here so that
      we can demonstrate nc_open. Usually we wouldn't close the file
      until done with it. */
   if ((res = nc_close(ncid)))
      BAIL(res);

   /* Now open the file for read-only access. */
   if ((res = nc_open(FILENAME, NC_NOWRITE, &ncid)))
      BAIL(res);

   /* Find the varid that represents our data. */
   if ((res = nc_inq_varid(ncid, VARNAME, &varid)))
      BAIL(res);

   /* Read the data, all in one lump. */
   if ((res = nc_get_var_int(ncid, varid, data_in)))
      BAIL(res);

   /* Ensure we got the data we expected. */
   for (i=0; i<DIMLEN; i++)
      if (data_in[i] != data_out[i])
      {
	 fprintf(stderr, "Unexpected value!\n");
	 return ERROR;
      }

   /* Close the file again. */
   if ((res = nc_close(ncid)))
      BAIL(res);

   return 0;
}
示例#13
0
int PIOc_openfile(const int iosysid, int *ncidp, int *iotype,
		  const char filename[], const int mode)
{
  int ierr;
  int msg;
  int mpierr;
  size_t len;
  iosystem_desc_t *ios;
  file_desc_t *file;

  ierr = PIO_NOERR;

  msg = PIO_MSG_OPEN_FILE;
  ios = pio_get_iosystem_from_id(iosysid);
  if(ios==NULL){
    printf("bad iosysid %d\n",iosysid);
    return PIO_EBADID;
  }

  file = (file_desc_t *) malloc(sizeof(*file));
  if(file==NULL){
    return PIO_ENOMEM;
  }
  file->iotype = *iotype;
  file->next = NULL;
  file->iosystem = ios;
  file->mode = mode;
  for(int i=0; i<PIO_MAX_VARS;i++){
    file->varlist[i].record = -1;
    file->varlist[i].ndims = -1;
#ifdef _PNETCDF
    file->varlist[i].request = NULL;
    file->varlist[i].nreqs=0;
#endif
    file->varlist[i].fillbuf = NULL;
    file->varlist[i].iobuf = NULL;
  }

  file->buffer.validvars=0;
  file->buffer.vid=NULL;
  file->buffer.data=NULL;
  file->buffer.next=NULL;
  file->buffer.frame=NULL;
  file->buffer.fillvalue=NULL;

  if(ios->async_interface && ! ios->ioproc){
    if(ios->comp_rank==0)
      mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm);
    len = strlen(filename);
    mpierr = MPI_Bcast((void *) filename,len, MPI_CHAR, ios->compmaster, ios->intercomm);
    mpierr = MPI_Bcast(&(file->iotype), 1, MPI_INT,  ios->compmaster, ios->intercomm);
    mpierr = MPI_Bcast(&(file->mode), 1, MPI_INT,  ios->compmaster, ios->intercomm);
  }

  if(ios->ioproc){

    switch(file->iotype){
#ifdef _NETCDF
#ifdef _NETCDF4

    case PIO_IOTYPE_NETCDF4P:
#ifdef _MPISERIAL
      ierr = nc_open(filename, file->mode, &(file->fh));
#else
      file->mode = file->mode |  NC_MPIIO;
      ierr = nc_open_par(filename, file->mode, ios->io_comm,ios->info, &(file->fh));
#endif
      break;

    case PIO_IOTYPE_NETCDF4C:
      file->mode = file->mode | NC_NETCDF4;
      // *** Note the INTENTIONAL FALLTHROUGH ***
#endif

    case PIO_IOTYPE_NETCDF:
      if(ios->io_rank==0){
	ierr = nc_open(filename, file->mode, &(file->fh));
      }
      break;
#endif

#ifdef _PNETCDF
    case PIO_IOTYPE_PNETCDF:
      ierr = ncmpi_open(ios->io_comm, filename, file->mode, ios->info, &(file->fh));

      // This should only be done with a file opened to append
      if(ierr == PIO_NOERR && (file->mode & PIO_WRITE)){
	if(ios->iomaster) printf("%d Setting IO buffer %ld\n",__LINE__,PIO_BUFFER_SIZE_LIMIT);
	ierr = ncmpi_buffer_attach(file->fh, PIO_BUFFER_SIZE_LIMIT );
      }
      break;
#endif

    default:
      ierr = iotype_error(file->iotype,__FILE__,__LINE__);
      break;
    }

    // If we failed to open a file due to an incompatible type of NetCDF, try it
    // once with just plain old basic NetCDF
#ifdef _NETCDF
    if(ierr == NC_ENOTNC && (file->iotype != PIO_IOTYPE_NETCDF)) {
        if(ios->iomaster) printf("PIO2 pio_file.c retry NETCDF\n");
	// reset ierr on all tasks
	ierr = PIO_NOERR;
	// reset file markers for NETCDF on all tasks
	file->iotype = PIO_IOTYPE_NETCDF;

	// open netcdf file serially on main task
        if(ios->io_rank==0){
	  ierr = nc_open(filename, file->mode, &(file->fh)); }

    }
#endif
  }

  ierr = check_netcdf(file, ierr, __FILE__,__LINE__);

  if(ierr==PIO_NOERR){
    mpierr = MPI_Bcast(&(file->mode), 1, MPI_INT,  ios->ioroot, ios->union_comm);
    pio_add_to_file_list(file);
    *ncidp = file->fh;
  }
  if(ios->io_rank==0){
    printf("Open file %s %d\n",filename,file->fh); //,file->fh,file->id,ios->io_rank,ierr);
//    if(file->fh==5) print_trace(stdout);
  }
  return ierr;
}
示例#14
0
int
main()
{
    int ncid, pres_varid, temp_varid;
    int lat_varid, lon_varid;

    /* We will read surface temperature and pressure fields. */
    float pres_in[NLAT][NLON];
    float temp_in[NLAT][NLON];

    /* For the lat lon coordinate variables. */
    float lats_in[NLAT], lons_in[NLON];

    /* To check the units attributes. */
    char pres_units_in[MAX_ATT_LEN], temp_units_in[MAX_ATT_LEN];
    char lat_units_in[MAX_ATT_LEN], lon_units_in[MAX_ATT_LEN];

    /* We will learn about the data file and store results in these
       program variables. */
    int ndims_in, nvars_in, ngatts_in, unlimdimid_in;

    /* Loop indexes. */
    int lat, lon;

    /* Error handling. */
    int retval;

    /* Open the file. */
    if ((retval = nc_open(FILE_NAME, NC_NOWRITE, &ncid)))
        ERR(retval);

    /* There are a number of inquiry functions in netCDF which can be
       used to learn about an unknown netCDF file. NC_INQ tells how
       many netCDF variables, dimensions, and global attributes are in
       the file; also the dimension id of the unlimited dimension, if
       there is one. */
    if ((retval = nc_inq(ncid, &ndims_in, &nvars_in, &ngatts_in,
                         &unlimdimid_in)))
        ERR(retval);

    /* In this case we know that there are 2 netCDF dimensions, 4
       netCDF variables, no global attributes, and no unlimited
       dimension. */
    if (ndims_in != 2 || nvars_in != 4 || ngatts_in != 0 ||
            unlimdimid_in != -1) return 2;

    /* Get the varids of the latitude and longitude coordinate
     * variables. */
    if ((retval = nc_inq_varid(ncid, LAT_NAME, &lat_varid)))
        ERR(retval);
    if ((retval = nc_inq_varid(ncid, LON_NAME, &lon_varid)))
        ERR(retval);

    /* Read the coordinate variable data. */
    if ((retval = nc_get_var_float(ncid, lat_varid, &lats_in[0])))
        ERR(retval);
    if ((retval = nc_get_var_float(ncid, lon_varid, &lons_in[0])))
        ERR(retval);

    /* Check the coordinate variable data. */
    for (lat = 0; lat < NLAT; lat++)
        if (lats_in[lat] != START_LAT + 5.*lat)
            return 2;
    for (lon = 0; lon < NLON; lon++)
        if (lons_in[lon] != START_LON + 5.*lon)
            return 2;

    /* Get the varids of the pressure and temperature netCDF
     * variables. */
    if ((retval = nc_inq_varid(ncid, PRES_NAME, &pres_varid)))
        ERR(retval);
    if ((retval = nc_inq_varid(ncid, TEMP_NAME, &temp_varid)))
        ERR(retval);

    /* Read the data. Since we know the contents of the file we know
     * that the data arrays in this program are the correct size to
     * hold all the data. */
    if ((retval = nc_get_var_float(ncid, pres_varid, &pres_in[0][0])))
        ERR(retval);
    if ((retval = nc_get_var_float(ncid, temp_varid, &temp_in[0][0])))
        ERR(retval);

    /* Check the data. */
    for (lat = 0; lat < NLAT; lat++)
        for (lon = 0; lon < NLON; lon++)
            if (pres_in[lat][lon] != SAMPLE_PRESSURE + (lon * NLAT + lat) ||
                    temp_in[lat][lon] != SAMPLE_TEMP + .25 * (lon * NLAT + lat))
                return 2;

    /* Each of the netCDF variables has a "units" attribute. Let's read
       them and check them. */
    if ((retval = nc_get_att_text(ncid, lat_varid, UNITS, lat_units_in)))
        ERR(retval);
    if (strncmp(lat_units_in, LAT_UNITS, strlen(LAT_UNITS)))
        return 2;

    if ((retval = nc_get_att_text(ncid, lon_varid, UNITS, lon_units_in)))
        ERR(retval);
    if (strncmp(lon_units_in, LON_UNITS, strlen(LON_UNITS)))
        return 2;

    if ((retval = nc_get_att_text(ncid, pres_varid, UNITS, pres_units_in)))
        ERR(retval);
    if (strncmp(pres_units_in, PRES_UNITS, strlen(PRES_UNITS)))
        return 2;

    if ((retval = nc_get_att_text(ncid, temp_varid, UNITS, temp_units_in)))
        ERR(retval);
    if (strncmp(temp_units_in, TEMP_UNITS, strlen(TEMP_UNITS))) return 2;

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

    printf("*** SUCCESS reading example file sfc_pres_temp.nc!\n");
    return 0;
}
示例#15
0
int
test_redef(int format)
{
   int ncid, varid, dimids[REDEF_NDIMS], dimids_in[REDEF_NDIMS];
   int ndims, nvars, natts, unlimdimid;
   int dimids_var[REDEF_NDIMS], var_type;
   int cflags = 0;
   size_t dim_len;
   char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
   float float_in;
   double double_out = 99E99;
   int int_in;
   unsigned char uchar_in, uchar_out = 255;
   short short_out = -999;
   nc_type xtype_in;
   size_t cache_size_in, cache_nelems_in;
   int cache_size_int_in, cache_nelems_int_in;
   int cache_preemption_int_in;
   float cache_preemption_in;
   int ret;

   if (format == NC_FORMAT_64BIT_OFFSET)
      cflags |= NC_64BIT_OFFSET;
   else if (format == NC_FORMAT_CDF5)
      cflags |= NC_CDF5;
   else if (format == NC_FORMAT_NETCDF4_CLASSIC)
      cflags |= (NC_NETCDF4|NC_CLASSIC_MODEL);
   else if (format == NC_FORMAT_NETCDF4)
      cflags |= NC_NETCDF4;

   /* Change chunk cache. */
   if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS,
                          NEW_CACHE_PREEMPTION)) ERR;

   /* Create a file with two dims, two vars, and two atts. */
   if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR;

   /* Retrieve the chunk cache settings, just for fun. */
   if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in,
                          &cache_preemption_in)) ERR;
   if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS ||
       cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;
   cache_size_in = 0;
   if (nc_get_chunk_cache(&cache_size_in, NULL, NULL)) ERR;
   if (cache_size_in != NEW_CACHE_SIZE) ERR;
   cache_nelems_in = 0;   
   if (nc_get_chunk_cache(NULL, &cache_nelems_in, NULL)) ERR;
   if (cache_nelems_in != NEW_CACHE_NELEMS) ERR;
   cache_preemption_in = 0;   
   if (nc_get_chunk_cache(NULL, NULL, &cache_preemption_in)) ERR;
   if (cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;

   /* Retrieve the chunk cache settings as integers, like the fortran API. */
   if (nc_get_chunk_cache_ints(&cache_size_int_in, &cache_nelems_int_in,
                               &cache_preemption_int_in)) ERR;
   if (cache_size_int_in != NEW_CACHE_SIZE || cache_nelems_int_in != NEW_CACHE_NELEMS ||
       cache_preemption_int_in != (int)(NEW_CACHE_PREEMPTION * 100)) ERR;
   if (nc_get_chunk_cache_ints(NULL, NULL, NULL)) ERR;
   cache_size_int_in = 0;
   if (nc_get_chunk_cache_ints(&cache_size_int_in, NULL, NULL)) ERR;
   if (cache_size_int_in != NEW_CACHE_SIZE) ERR;
   cache_nelems_int_in = 0;
   if (nc_get_chunk_cache_ints(NULL, &cache_nelems_int_in, NULL)) ERR;
   if (cache_nelems_int_in != NEW_CACHE_NELEMS) ERR;
   cache_preemption_int_in = 0;
   if (nc_get_chunk_cache_ints(NULL, NULL, &cache_preemption_int_in)) ERR;
   if (cache_preemption_int_in != (int)(NEW_CACHE_PREEMPTION * 100)) ERR;

   /* These won't work. */
   if (nc_set_chunk_cache_ints(-1, NEW_CACHE_NELEMS_2,
                               (int)(NEW_CACHE_PREEMPTION_2 * 100)) != NC_EINVAL) ERR;
   if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, 0,
                               (int)(NEW_CACHE_PREEMPTION_2 * 100)) != NC_EINVAL) ERR;
   if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, NEW_CACHE_NELEMS_2,
                               -1) != NC_EINVAL) ERR;
   if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, NEW_CACHE_NELEMS_2,
                               101) != NC_EINVAL) ERR;
   

   /* Change chunk cache again. */
   if (nc_set_chunk_cache_ints(NEW_CACHE_SIZE_2, NEW_CACHE_NELEMS_2,
                               (int)(NEW_CACHE_PREEMPTION_2 * 100))) ERR;
   if (nc_get_chunk_cache_ints(&cache_size_int_in, &cache_nelems_int_in,
                               &cache_preemption_int_in)) ERR;
   if (cache_size_int_in != NEW_CACHE_SIZE_2 || cache_nelems_int_in != NEW_CACHE_NELEMS_2 ||
       cache_preemption_int_in != (int)(NEW_CACHE_PREEMPTION_2 * 100)) ERR;
   

   /* This will fail, except for netcdf-4/hdf5, which permits any
    * name. */
   if (format != NC_FORMAT_NETCDF4)
      if (nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN,
                     &dimids[1]) != NC_EBADNAME) ERR;

   if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR;
   if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR;
   if (nc_def_var(ncid, REDEF_VAR1_NAME, NC_INT, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR2_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_put_att_double(ncid, NC_GLOBAL, REDEF_ATT1_NAME, NC_DOUBLE, 1, &double_out)) ERR;
   if (nc_put_att_short(ncid, NC_GLOBAL, REDEF_ATT2_NAME, NC_SHORT, 1, &short_out)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* Close it up. */
   if (format != NC_FORMAT_NETCDF4)
      if (nc_enddef(ncid)) ERR;
   if (nc_close(ncid)) ERR;

   /* Reopen as read only - make sure it doesn't let us change file. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* This will fail. */
   ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS,
                    dimids, &varid);
   if(format == NC_FORMAT_NETCDF4) {
      if(ret != NC_EPERM) {
         ERR;
      }
   } else {
      if(ret != NC_ENOTINDEFINE) {
         ERR;
      }
   }
   /* This will fail. */
   if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR;
   if (nc_close(ncid)) ERR;

   /* Make sure we can't redef a file opened for NOWRITE. */
   if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_redef(ncid) != NC_EPERM) ERR;

   /* Check it out again. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   if (nc_close(ncid)) ERR;

   /* Reopen the file and check it, add a variable and attribute. */
   if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;

   /* Add var. */
   if ((format != NC_FORMAT_NETCDF4) && nc_redef(ncid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR3_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;

   /* Add att. */
   ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out);
   if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
   {
      if (ret != NC_ERANGE) ERR;
   }
   else if (ret) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 3 || natts != 3 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS ||
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;

   if (nc_close(ncid)) ERR;

   /* Reopen it and check each dim, var, and att. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM1_LEN || strcmp(dim_name, REDEF_DIM1_NAME)) ERR;
   if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM2_LEN || strcmp(dim_name, REDEF_DIM2_NAME)) ERR;
   if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR1_NAME) || var_type != NC_INT ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR2_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_get_att_float(ncid, NC_GLOBAL, REDEF_ATT1_NAME, &float_in) != NC_ERANGE) ERR;
   if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR;
   if (int_in != short_out) ERR;
   ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in);
   if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_64BIT_DATA)
   {
      if (ret != NC_ERANGE) ERR;
   }
   else if (ret) ERR;

   if (uchar_in != uchar_out) ERR;
   if (nc_close(ncid)) ERR;
   return NC_NOERR;
}
示例#16
0
int ex_open_int (const char  *path,
		 int    mode,
		 int   *comp_ws,
		 int   *io_ws,
		 float *version,
		 int    run_version)
{
  int exoid;
  int status, stat_att, stat_dim;
  nc_type att_type = NC_NAT;
  size_t att_len = 0;
  int old_fill;
  int file_wordsize;
  int dim_str_name;
  int int64_status = 0;
  
  char errmsg[MAX_ERR_LENGTH];

  exerrval = 0; /* clear error code */
 
  /* set error handling mode to no messages, non-fatal errors */
  ex_opts(exoptval);    /* call required to set ncopts first time through */

  if (run_version != EX_API_VERS_NODOT && warning_output == 0) {
    int run_version_major = run_version / 100;
    int run_version_minor = run_version % 100;
    int lib_version_major = EX_API_VERS_NODOT / 100;
    int lib_version_minor = EX_API_VERS_NODOT % 100;
    fprintf(stderr, "EXODUS: Warning: This code was compiled with exodus version %d.%02d,\n          but was linked with exodus library version %d.%02d\n          This is probably an error in the build process of this code.\n",
	    run_version_major, run_version_minor, lib_version_major, lib_version_minor);
    warning_output = 1;
  }
  

  if ((mode & EX_READ) && (mode & EX_WRITE)) {
    exerrval = EX_BADFILEMODE;
    sprintf(errmsg,"Error: Cannot specify both EX_READ and EX_WRITE");
    ex_err("ex_open",errmsg,exerrval); 
    return (EX_FATAL);
  }

  /* The EX_READ mode is the default if EX_WRITE is not specified... */
  if (!(mode & EX_WRITE)) { /* READ ONLY */
#if defined(__LIBCATAMOUNT__)
    if ((status = nc_open (path, NC_NOWRITE, &exoid)) != NC_NOERR)
#else
      if ((status = nc_open (path, NC_NOWRITE|NC_SHARE, &exoid)) != NC_NOERR)
#endif
	{
	  /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
	  if (status == 0) {
	    exerrval = EX_FATAL;
	  }
	  else {
	    /* It is possible that the user is trying to open a netcdf4
	       file, but the netcdf4 capabilities aren't available in the
	       netcdf linked to this library. Note that we can't just use a
	       compile-time define since we could be using a shareable
	       netcdf library, so the netcdf4 capabilities aren't known
	       until runtime...
	  
	       Netcdf-4.X does not (yet?) have a function that can be
	       queried to determine whether the library being used was
	       compiled with --enable-netcdf4, so that isn't very
	       helpful.. 

	       At this time, query the beginning of the file and see if it
	       is an HDF-5 file and if it is assume that the open failure
	       is due to the netcdf library not enabling netcdf4 features...
	    */
	    int type = 0;
	    ex_check_file_type(path, &type);
	  
	    if (type == 5) {
	      /* This is an hdf5 (netcdf4) file. Since the nc_open failed,
		 the assumption is that the netcdf doesn't have netcdf4
		 capabilities enabled.  Tell the user...
	      */
	      fprintf(stderr,
		      "EXODUS: Error: Attempting to open the netcdf-4 file:\n\t'%s'\n\twith a netcdf library that does not support netcdf-4\n",
		      path);
	    }
	    exerrval = status;
	  }
	  sprintf(errmsg,"Error: failed to open %s read only",path);
	  ex_err("ex_open",errmsg,exerrval); 
	  return(EX_FATAL);
	} 
  }
  else /* (mode & EX_WRITE) READ/WRITE */
    {
#if defined(__LIBCATAMOUNT__)
      if ((status = nc_open (path, NC_WRITE, &exoid)) != NC_NOERR)
#else
	if ((status = nc_open (path, NC_WRITE|NC_SHARE, &exoid)) != NC_NOERR)
#endif
	  {
	    /* NOTE: netCDF returns an id of -1 on an error - but no error code! */
	    if (status == 0)
	      exerrval = EX_FATAL;
	    else
	      exerrval = status;
	    sprintf(errmsg,"Error: failed to open %s write only",path);
	    ex_err("ex_open",errmsg,exerrval); 
	    return(EX_FATAL);
	  } 

      /* turn off automatic filling of netCDF variables */
      if ((status = nc_set_fill (exoid, NC_NOFILL, &old_fill)) != NC_NOERR) {
	exerrval = status;
	sprintf(errmsg,
		"Error: failed to set nofill mode in file id %d",
		exoid);
	ex_err("ex_open", errmsg, exerrval);
	return (EX_FATAL);
      }

      stat_att = nc_inq_att(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, &att_type, &att_len);
      stat_dim = nc_inq_dimid(exoid, DIM_STR_NAME, &dim_str_name);
      if(stat_att != NC_NOERR || stat_dim != NC_NOERR) {
	if ((status=nc_redef (exoid)) != NC_NOERR) {
	  exerrval = status;
	  sprintf(errmsg,"Error: failed to place file id %d into define mode",exoid);
	  ex_err("ex_open",errmsg,exerrval);
	  return (EX_FATAL);
	}

	if (stat_att != NC_NOERR) {
	  int max_so_far = 32;
	  nc_put_att_int(exoid, NC_GLOBAL, ATT_MAX_NAME_LENGTH, NC_INT, 1, &max_so_far);
	}

	/* If the DIM_STR_NAME variable does not exist on the database, we need to add it now. */
	if(stat_dim != NC_NOERR) {
	  /* Not found; set to default value of 32+1. */
	  int max_name = ex_default_max_name_length < 32 ? 32 : ex_default_max_name_length;
	  if ((status = nc_def_dim(exoid, DIM_STR_NAME, max_name+1, &dim_str_name)) != NC_NOERR) {
	    exerrval = status;
	    sprintf(errmsg,
		    "Error: failed to define string name dimension in file id %d",
		    exoid);
	    ex_err("ex_open",errmsg,exerrval);
	    return (EX_FATAL);
	  }
	}
	if ((exerrval=nc_enddef (exoid)) != NC_NOERR) {
	  sprintf(errmsg,
		  "Error: failed to complete definition in file id %d", 
		  exoid);
	  ex_err("ex_open",errmsg,exerrval);
	  return (EX_FATAL);
	}
      }
    }

  /* determine version of EXODUS II file, and the word size of
   * floating point and integer values stored in the file
   */

  if ((status = nc_get_att_float(exoid, NC_GLOBAL, ATT_VERSION, version)) != NC_NOERR) {
    exerrval  = status;
    sprintf(errmsg,"Error: failed to get database version for file id: %d",
	    exoid);
    ex_err("ex_open",errmsg,exerrval);
    return(EX_FATAL);
  }
   
  /* check ExodusII file version - old version 1.x files are not supported */
  if (*version < 2.0) {
    exerrval  = EX_FATAL;
    sprintf(errmsg,"Error: Unsupported file version %.2f in file id: %d",
	    *version, exoid);
    ex_err("ex_open",errmsg,exerrval);
    return(EX_FATAL);
  }
   
  if (nc_get_att_int (exoid, NC_GLOBAL, ATT_FLT_WORDSIZE, &file_wordsize) != NC_NOERR)
    {  /* try old (prior to db version 2.02) attribute name */
      if (nc_get_att_int (exoid,NC_GLOBAL,ATT_FLT_WORDSIZE_BLANK,&file_wordsize) != NC_NOERR)
	{
	  exerrval  = EX_FATAL;
	  sprintf(errmsg,"Error: failed to get file wordsize from file id: %d",
		  exoid);
	  ex_err("ex_open",errmsg,exerrval);
	  return(exerrval);
	}
    }

  /* See if int64 status attribute exists and if so, what data is stored as int64 
   * Older files don't have the attribute, so it is not an error if it is missing
   */
  if (nc_get_att_int (exoid, NC_GLOBAL, ATT_INT64_STATUS, &int64_status) != NC_NOERR) {
    int64_status = 0; /* Just in case it gets munged by a failed get_att_int call */
  }
  
  /* Merge in API int64 status flags as specified by caller of function... */
  int64_status |= (mode & EX_ALL_INT64_API);
  
  /* initialize floating point and integer size conversion. */
  if (ex_conv_ini(exoid, comp_ws, io_ws, file_wordsize, int64_status, 0) != EX_NOERR ) {
    exerrval = EX_FATAL;
    sprintf(errmsg,
	    "Error: failed to initialize conversion routines in file id %d",
            exoid);
    ex_err("ex_open", errmsg, exerrval);
    return (EX_FATAL);
  }

  return (exoid);
}
示例#17
0
文件: tst_udf.c 项目: dschwen/libmesh
int
main(int argc, char **argv)
{
   printf("\n*** Testing user-defined formats.\n");
   printf("*** testing simple user-defined format...");
   {
      int ncid;
      NC_Dispatch *disp_in;
      int i;
      
      /* Create an empty file to play with. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Test all available user-defined format slots. */
      for (i = 0; i < NUM_UDFS; i++)
      {
         /* Add our user defined format. */
         if (nc_def_user_format(mode[i], &tst_dispatcher, NULL)) ERR;

         /* Check that our user-defined format has been added. */
         if (nc_inq_user_format(mode[i], &disp_in, NULL)) ERR;
         if (disp_in != &tst_dispatcher) ERR;
         
         /* Open file with our defined functions. */
         if (nc_open(FILE_NAME, mode[i], &ncid)) ERR;
         if (nc_close(ncid)) ERR;
         
         /* Open file again and abort, which is the same as closing it. */
         if (nc_open(FILE_NAME, mode[i], &ncid)) ERR;
         if (nc_inq_format(ncid, NULL) != TEST_VAL_42) ERR;
         if (nc_inq_format_extended(ncid, NULL, NULL) != TEST_VAL_42) ERR;
         if (nc_abort(ncid) != TEST_VAL_42) ERR;
      }
   }
   SUMMARIZE_ERR;
   printf("*** testing user-defined format with magic number...");
   {
      int ncid;
      NC_Dispatch *disp_in;
      char magic_number[5] = "1111";
      char dummy_data[11] = "0123456789";
      char magic_number_in[NC_MAX_MAGIC_NUMBER_LEN];
      FILE *FP;
      int i;
      
      /* Create a file with magic number at start. */
      if (!(FP = fopen(FILE_NAME, "w"))) ERR;
      if (fwrite(magic_number, sizeof(char), strlen(magic_number), FP)
          != strlen(magic_number)) ERR;
      if (fwrite(dummy_data, sizeof(char), strlen(dummy_data), FP)
          != strlen(dummy_data)) ERR;
      if (fclose(FP)) ERR;
      
      /* Test all available user-defined format slots. */
      for (i = 0; i < NUM_UDFS; i++)
      {
         /* Add our test user defined format. */
         if (nc_def_user_format(mode[i], &tst_dispatcher, magic_number)) ERR;
         
         /* Check that our user-defined format has been added. */
         if (nc_inq_user_format(mode[i], &disp_in, magic_number_in)) ERR;
         if (disp_in != &tst_dispatcher) ERR;
         if (strncmp(magic_number, magic_number_in, strlen(magic_number))) ERR;

         /* Open file with our defined functions. */
         if (nc_open(FILE_NAME, mode[i], &ncid)) ERR;
         if (nc_close(ncid)) ERR;
         
         /* Open file again and abort, which is the same as closing
          * it. This time we don't specify a mode, because the magic
          * number is used to identify the file. */
         if (nc_open(FILE_NAME, 0, &ncid)) ERR;
         if (nc_inq_format(ncid, NULL) != TEST_VAL_42) ERR;
         if (nc_inq_format_extended(ncid, NULL, NULL) != TEST_VAL_42) ERR;
         if (nc_abort(ncid) != TEST_VAL_42) ERR;
      }
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
示例#18
0
int
main(int argc, char **argv)
{
    int i;
    char* filename = "tst_diskless.nc";

    /* Set defaults */
    persist = 0;
    usenetcdf4 = 0;
    mmap = 0;

    for(i=1;i<argc;i++) {
	if(strcmp(argv[i],"netcdf4")==0) usenetcdf4=1;
	else if(strcmp(argv[i],"persist")==0) persist=1;
	else if(strcmp(argv[i],"mmap")==0) mmap=1;
	/* ignore anything not recognized */
    }

#ifndef USE_NETCDF4
    usenetcdf4 = 0;
#endif

    if(mmap)
	usenetcdf4 = 0;

    flags = usenetcdf4?FLAGS4:FLAGS3;
    if(persist) flags |= PERSIST;
    if(mmap) flags |= NC_MMAP;

printf("\n*** Testing the diskless API.\n");
printf("*** testing diskless file with scalar vars...");
{
    int ncid, varid0, varid1, varid2;
    int ndims_in, nvars_in, natts_in, unlimdimid_in;
    char name_in[NC_MAX_NAME + 1];
    nc_type type_in;
    float float_data = 3.14, float_data_in;
    int int_data = 42, int_data_in;
    short short_data = 2, short_data_in;

    removefile(persist,filename);

    /* Create a netCDF file (which exists only in memory). */
    if (nc_create(filename, flags, &ncid)) ERR;

    /* Create some variables. */
    if (nc_def_var(ncid, RESISTOR, NC_INT, 0, NULL, &varid0)) ERR;
    if (nc_def_var(ncid, CAPACITOR, NC_FLOAT, 0, NULL, &varid1)) ERR;
    if (nc_def_var(ncid, NUM555, NC_SHORT, 0, NULL, &varid2)) ERR;
    if (nc_enddef(ncid)) ERR;

    /* Write some data to this file. */
    if (nc_put_vara_int(ncid, varid0, NULL, NULL, &int_data)) ERR;
    if (nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data)) ERR;
    if (nc_put_vara_short(ncid, varid2, NULL, NULL, &short_data)) ERR;

    /* Now check the phony file. */
    if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
    if (ndims_in != 0 || nvars_in != 3 || natts_in != 0 || unlimdimid_in != -1) ERR;

    /* Check variables. */
    if (nc_inq_var(ncid, varid0, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR;
    if (strcmp(name_in, RESISTOR) || type_in != NC_INT || ndims_in != 0 ||
    natts_in != 0) ERR;
    if (nc_inq_var(ncid, varid1, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR;
    if (strcmp(name_in, CAPACITOR) || type_in != NC_FLOAT || ndims_in != 0 ||
    natts_in != 0) ERR;
    if (nc_inq_var(ncid, varid2, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR;
    if (strcmp(name_in, NUM555) || type_in != NC_SHORT || natts_in != 0) ERR;

    /* Read my absolutely crucial data. */
    if (nc_get_vara_int(ncid, varid0, NULL, NULL, &int_data_in)) ERR;
    if (int_data_in != int_data) ERR;
    if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR;
    if (float_data_in != float_data) ERR;
    if (nc_get_vara_short(ncid, varid2, NULL, NULL, &short_data_in)) ERR;
    if (short_data_in != short_data) ERR;

    /* Close the file. */
    if (nc_close(ncid))
	abort(); //ERR;
    }
    SUMMARIZE_ERR;

    if(!usenetcdf4 && persist) {
        int ncid, varid0, varid1, varid2;
        float float_data = 3.14, float_data_in;
        int int_data = 42, int_data_in;
        short short_data = 2, short_data_in;

        printf("*** testing diskless open of previously created file...");

        if (nc_open(filename, flags, &ncid)) ERR;

	/* Read and compare */
        if (nc_inq_varid(ncid, RESISTOR, &varid0)) ERR;
        if (nc_inq_varid(ncid, CAPACITOR, &varid1)) ERR;
        if (nc_inq_varid(ncid, NUM555, &varid2)) ERR;

        if (nc_get_vara_int(ncid, varid0, NULL, NULL, &int_data_in)) ERR;
        if (int_data_in != int_data) ERR;
        if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR;
        if (float_data_in != float_data) ERR;
        if (nc_get_vara_short(ncid, varid2, NULL, NULL, &short_data_in)) ERR;
        if (short_data_in != short_data) ERR;

	nc_close(ncid);
    }
    SUMMARIZE_ERR;

    printf("*** testing creation of simple diskless file...");
    {
    #define NDIMS 2
    #define DIM0_NAME "Fun"
    #define DIM1_NAME "Money"
    #define DIM1_LEN 200
    #define ATT0_NAME "home"
    #define ATT0_TEXT "earthship"
    #define VAR0_NAME "nightlife"
    #define VAR1_NAME "time"
    #define VAR2_NAME "taxi_distance"

    int ncid, dimid[NDIMS], dimid_in[NDIMS], varid0, varid1, varid2;
    int ndims_in, nvars_in, natts_in, unlimdimid_in;
    char name_in[NC_MAX_NAME + 1], att0_in[NC_MAX_NAME + 1];
    nc_type type_in;
    size_t len_in;
    short short_data[DIM1_LEN];
    size_t start[1] = {0};
    size_t count[1] = {DIM1_LEN};
    int i;
    float float_data = 42.22, float_data_in;

    /* This is some really important data that I want to save. */
    for (i = 0; i < DIM1_LEN; i++)
    short_data[i] = i;

    removefile(persist,filename);

    /* Create a netCDF file (which exists only in memory). I am
    * confident that the world-famous netCDF format is the way to
    * store my data! */
    if (nc_create(filename, flags, &ncid)) ERR;

    /* Create some atts. They will help document my data forever. */
    if (nc_put_att_text(ncid, NC_GLOBAL, ATT0_NAME,
    sizeof(ATT0_TEXT) + 1, ATT0_TEXT)) ERR;

    /* Create dimensions: money is limited, but fun is not! */
    if (nc_def_dim(ncid, DIM0_NAME, NC_UNLIMITED, &dimid[0])) ERR;
    if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimid[1])) ERR;

    /* Create some variables. The data they hold must persist
    * through the ages. */
    if (nc_def_var(ncid, VAR0_NAME, NC_INT, NDIMS, dimid, &varid0)) ERR;
    if (nc_def_var(ncid, VAR1_NAME, NC_FLOAT, 0, NULL, &varid1)) ERR;
    if (nc_def_var(ncid, VAR2_NAME, NC_SHORT, 1, &dimid[1], &varid2)) ERR;
    if (nc_enddef(ncid)) ERR;

    /* Write some data to this file. I'm glad I'm saving this
    * important data in such a safe format! */
    if (nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data)) ERR;
    if (nc_put_vara_short(ncid, varid2, start, count, short_data)) ERR;

    /* Now check the phony file. Is my data safe? */
    if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
    if (ndims_in != 2 || nvars_in != 3 || natts_in != 1 || unlimdimid_in != 0) ERR;

    /* Check attributes - they will be needed by future generations
    * of scientists to understand my data. */
    if (nc_get_att_text(ncid, NC_GLOBAL, ATT0_NAME, att0_in)) ERR;
    if (strcmp(att0_in, ATT0_TEXT)) ERR;

    /* Check dimensions. */
    if (nc_inq_dim(ncid, dimid[0], name_in, &len_in)) ERR;
    if (strcmp(name_in, DIM0_NAME) || len_in != 0) ERR;
    if (nc_inq_dim(ncid, dimid[1], name_in, &len_in)) ERR;
    if (strcmp(name_in, DIM1_NAME) || len_in != DIM1_LEN) ERR;

    /* Check variables. */
    if (nc_inq_var(ncid, varid0, name_in, &type_in, &ndims_in, dimid_in, &natts_in)) ERR;
    if (strcmp(name_in, VAR0_NAME) || type_in != NC_INT || ndims_in != NDIMS ||
    dimid_in[0] != 0 || dimid_in[1] != 1 || natts_in != 0) ERR;
    if (nc_inq_var(ncid, varid1, name_in, &type_in, &ndims_in, dimid_in, &natts_in)) ERR;
    if (strcmp(name_in, VAR1_NAME) || type_in != NC_FLOAT || ndims_in != 0 ||
    natts_in != 0) ERR;
    if (nc_inq_var(ncid, varid2, name_in, &type_in, &ndims_in, dimid_in, &natts_in)) ERR;
    if (strcmp(name_in, VAR2_NAME) || type_in != NC_SHORT || ndims_in != 1 ||
    dimid_in[0] != 1 || natts_in != 0) ERR;

    /* Read my absolutely crucial data. */
    if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR;
    if (float_data_in != float_data) ERR;

    /* Close the file, losing all information. Hey! What kind of
    * storage format is this, anyway? */
    if (nc_close(ncid))
	abort(); //ERR;
    }
    SUMMARIZE_ERR;
    printf("*** testing diskless file with scalar vars and type conversion...");
    {
    #define DUNE "dune"
    #define STAR_TREK "capacitor_value"
    #define STAR_WARS "number_of_555_timer_chips"

    int ncid, varid0, varid1, varid2;
    int ndims_in, nvars_in, natts_in, unlimdimid_in;
    char name_in[NC_MAX_NAME + 1];
    nc_type type_in;
    float float_data = 3.14, float_data_in;
    int int_data = 42, int_data_in;
    short short_data = 2, short_data_in;

    removefile(persist,filename);

    /* Create a netCDF file (which exists only in memory). */
    if (nc_create(filename, flags, &ncid)) ERR;

    /* Create some variables. */
    if (nc_def_var(ncid, DUNE, NC_INT, 0, NULL, &varid0)) ERR;
    if (nc_def_var(ncid, STAR_TREK, NC_FLOAT, 0, NULL, &varid1)) ERR;
    if (nc_def_var(ncid, STAR_WARS, NC_SHORT, 0, NULL, &varid2)) ERR;
    if (nc_enddef(ncid)) ERR;

    /* Write some data to this file. */
    if (nc_put_vara_int(ncid, varid0, NULL, NULL, &int_data)) ERR;
    if (nc_put_vara_float(ncid, varid1, NULL, NULL, &float_data)) ERR;
    if (nc_put_vara_short(ncid, varid2, NULL, NULL, &short_data)) ERR;

    /* Now check the phony file. */
    if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
    if (ndims_in != 0 || nvars_in != 3 || natts_in != 0 || unlimdimid_in != -1) ERR;

    /* Check variables. */
    if (nc_inq_var(ncid, varid0, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR;
    if (strcmp(name_in, DUNE) || type_in != NC_INT || ndims_in != 0 ||
    natts_in != 0) ERR;
    if (nc_inq_var(ncid, varid1, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR;
    if (strcmp(name_in, STAR_TREK) || type_in != NC_FLOAT || ndims_in != 0 ||

    natts_in != 0) ERR;
    if (nc_inq_var(ncid, varid2, name_in, &type_in, &ndims_in, NULL, &natts_in)) ERR;
    if (strcmp(name_in, STAR_WARS) || type_in != NC_SHORT || natts_in != 0) ERR;

    /* Read my absolutely crucial data. */
    if (nc_get_vara_int(ncid, varid0, NULL, NULL, &int_data_in)) ERR;
    if (int_data_in != int_data) ERR;
    if (nc_get_vara_float(ncid, varid1, NULL, NULL, &float_data_in)) ERR;
    if (float_data_in != float_data) ERR;
    if (nc_get_vara_short(ncid, varid2, NULL, NULL, &short_data_in)) ERR;
    if (short_data_in != short_data) ERR;

    /* Close the file. */
    if (nc_close(ncid))
	abort(); //ERR;
    }
    SUMMARIZE_ERR;
    FINAL_RESULTS;

    /* Unnecessary exit(0), FINAL_RESULTS returns. */
    //exit(0);
}
示例#19
0
int main(int argc, char** argv) {
    char filename[256];
    int i, j, k, err, nerrs=0, ncid, varid[2], dimid[2], *buf;
    size_t start[2], count[2];
    int formats[5]={NC_FORMAT_CLASSIC, NC_FORMAT_64BIT_OFFSET, NC_FORMAT_CDF5,
                    NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};

    if (argc > 2) {
        printf("Usage: %s [filename]\n",argv[0]);
        return 1;
    }
    if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
    else           strcpy(filename, "tst_def_var_fill.nc");

    char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
    sprintf(cmd_str, "*** TESTING C   %s for def_var_fill ", argv[0]);
    printf("%-66s ------ ", cmd_str); fflush(stdout);
    free(cmd_str);

    buf = (int*) malloc(NY*NX * sizeof(int));

    for (k=0; k<5; k++) {
#ifndef ENABLE_CDF5
        if (formats[k] == NC_FORMAT_CDF5) continue;
#endif
#ifndef USE_NETCDF4
        if (formats[k] == NC_FORMAT_NETCDF4 ||
            formats[k] == NC_FORMAT_NETCDF4_CLASSIC)
            continue;
#endif
        nc_set_default_format(formats[k], NULL);

        /* create a new file for writing ------------------------------------*/
        err = nc_create(filename, NC_CLOBBER, &ncid); CHECK_ERR

        /* define dimension */
        err = nc_def_dim(ncid, "Y", NY, &dimid[0]); CHECK_ERR
        err = nc_def_dim(ncid, "X", NX, &dimid[1]); CHECK_ERR

        /* define variables */
        err = nc_def_var(ncid, "var_nofill", NC_INT, 2, dimid, &varid[0]); CHECK_ERR
        err = nc_def_var(ncid, "var_fill",   NC_INT, 2, dimid, &varid[1]); CHECK_ERR

        /* set fill mode for variables */
        err = nc_def_var_fill(ncid, NC_GLOBAL, 0, NULL); EXP_ERR(NC_EGLOBAL)
        err = nc_def_var_fill(ncid, varid[0], 1, NULL); CHECK_ERR
        err = nc_def_var_fill(ncid, varid[1], 0, NULL); CHECK_ERR

        err = nc_enddef(ncid); CHECK_ERR

        /* write a subarray to both variables */
        for (i=0; i<NY*NX; i++) buf[i] = 5;
        start[0] = 0;
        start[1] = 2;
        count[0] = NY;
        count[1] = 2;
        err = nc_put_vara_int(ncid, varid[0], start, count, buf); CHECK_ERR
        err = nc_put_vara_int(ncid, varid[1], start, count, buf); CHECK_ERR
        err = nc_close(ncid); CHECK_ERR

        /* Now, reopen the file and read variables back */
        err = nc_open(filename, NC_WRITE, &ncid); CHECK_ERR

        /* get variable IDs */
        err = nc_inq_varid(ncid, "var_nofill", &varid[0]); CHECK_ERR
        err = nc_inq_varid(ncid, "var_fill",   &varid[1]); CHECK_ERR

        /* read variable "var_nofill" and check contents */
        for (i=0; i<NY*NX; i++) buf[i] = -1;
        err = nc_get_var_int(ncid, varid[0], buf); CHECK_ERR
        for (i=0; i<NY; i++) {
            for (j=0; j<NX; j++) {
                if (2 <= j && j < 4) {
                    if (buf[i*NX+j] != 5) {
                        printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
                               __LINE__,__FILE__,i*NX+j, 5, buf[i*NX+j]);
                        nerrs++;
                    }
                }
                else if (buf[i*NX+j] == NC_FILL_INT) {
                    printf("Warning at line %d in %s: get buf[%d] same as NC_FILL_INT\n",
                           __LINE__,__FILE__,i*NX+j);
                }
            }
        }

        /* read variable "var_fill" and check contents */
        for (i=0; i<NY*NX; i++) buf[i] = -1;
        err = nc_get_var_int(ncid, varid[1], buf); CHECK_ERR
        for (i=0; i<NY; i++) {
            for (j=0; j<NX; j++) {
                int expect = NC_FILL_INT;
                if (2 <= j && j< 4) expect = 5;

                if (buf[i*NX+j] != expect) {
                    printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
                           __LINE__,__FILE__,i*NX+j, expect, buf[i*NX+j]);
                    nerrs++;
                }
            }
        }

        err = nc_close(ncid); CHECK_ERR
    }
    free(buf);

    if (nerrs) printf("fail with %d mismatches\n",nerrs);
    else       printf("pass\n");

    return (nerrs > 0);
}
示例#20
0
int main() {

  int ncid, dimid;
  int le_float_varid;
  int be_float_varid;
  int le_int_varid;
  int be_int_varid;
  int le_dbl_varid;
  int be_dbl_varid;
  int ed;
  int failures = 0;
  int retval = 0;

  printf("* Checking that endianness is properly read from file.\n");
  printf("** Generating test files.\n");
  /*
   * 1. Create a netcdf file with endianness as desired.
   */
  {

    printf("*** Creating a file via netcdf API: %s.\n",FILE_NAME_NC);
    retval = nc_create(FILE_NAME_NC, NC_NETCDF4 | NC_CLOBBER, &ncid);

    retval = nc_def_dim(ncid, DIM_NAME, NDIM, &dimid);

    /* Little-Endian Float */
    retval = nc_def_var(ncid, LE_FLOAT_VARNAME, NC_FLOAT, 1, &dimid, &le_float_varid);
    retval = nc_def_var_endian(ncid, le_float_varid, NC_ENDIAN_LITTLE);

    /* Big-Endian Float */
    retval = nc_def_var(ncid, BE_FLOAT_VARNAME, NC_FLOAT, 1, &dimid, &be_float_varid);
    retval = nc_def_var_endian(ncid, be_float_varid, NC_ENDIAN_BIG);

    /* Little-Endian Int */
    retval = nc_def_var(ncid, LE_INT_VARNAME, NC_INT, 1, &dimid, &le_int_varid);
    retval = nc_def_var_endian(ncid, le_int_varid, NC_ENDIAN_LITTLE);

    /* Big-Endian Int */
    retval = nc_def_var(ncid, BE_INT_VARNAME, NC_INT, 1, &dimid, &be_int_varid);
    retval = nc_def_var_endian(ncid, be_int_varid, NC_ENDIAN_BIG);

    /* Little-Endian Double */
    retval = nc_def_var(ncid, LE_DBL_VARNAME, NC_DOUBLE, 1, &dimid, &le_dbl_varid);
    retval = nc_def_var_endian(ncid, le_dbl_varid, NC_ENDIAN_LITTLE);

    /* Big-Endian Double */
    retval = nc_def_var(ncid, BE_DBL_VARNAME, NC_DOUBLE, 1, &dimid, &be_dbl_varid);
    retval = nc_def_var_endian(ncid, be_dbl_varid, NC_ENDIAN_BIG);


    retval = nc_close(ncid);
  }

  /*
   * 2. Reopen netcdf-generated file, check to see if the endianness attribute
   *    exists.
   */
  printf("** Checking test files.\n");
  {
    ncid = 0;
    le_float_varid = 0;
    be_float_varid = 0;
    le_int_varid = 0;
    be_int_varid = 0;
    le_dbl_varid = 0;
    be_dbl_varid = 0;

    printf("*** %s\n",FILE_NAME_NC);
    retval = nc_open(FILE_NAME_NC, NC_NETCDF4 | NC_NOWRITE, &ncid);

    retval = nc_inq_varid(ncid,LE_FLOAT_VARNAME,&le_float_varid);
    retval = nc_inq_varid(ncid,BE_FLOAT_VARNAME,&be_float_varid);
    retval = nc_inq_varid(ncid,LE_INT_VARNAME,&le_int_varid);
    retval = nc_inq_varid(ncid,BE_INT_VARNAME,&be_int_varid);
    retval = nc_inq_varid(ncid,LE_DBL_VARNAME,&le_dbl_varid);
    retval = nc_inq_varid(ncid,BE_DBL_VARNAME,&be_dbl_varid);

    printf("\tLittle-Endian Float...\t");
    retval = nc_inq_var_endian(ncid,le_float_varid,&ed);
    if(ed == NC_ENDIAN_LITTLE) printf("passed\n"); else {printf("failed\n"); failures++;}

    printf("\tBig-Endian Float...\t");
    retval = nc_inq_var_endian(ncid,be_float_varid,&ed);
    if(ed == NC_ENDIAN_BIG) printf("passed\n"); else {printf("failed\n"); failures++;}

    printf("\tLittle-Endian Int...\t");
    retval = nc_inq_var_endian(ncid,le_int_varid,&ed);
    if(ed == NC_ENDIAN_LITTLE) printf("passed\n"); else {printf("failed\n"); failures++;}

    printf("\tBig-Endian Int...\t");
    retval = nc_inq_var_endian(ncid,be_int_varid,&ed);
    if(ed == NC_ENDIAN_BIG) printf("passed\n"); else {printf("failed\n"); failures++;}

    printf("\tLittle-Endian Double...\t");
    retval = nc_inq_var_endian(ncid,le_dbl_varid,&ed);
    if(ed == NC_ENDIAN_LITTLE) printf("passed\n"); else {printf("failed\n"); failures++;}

    printf("\tBig-Endian Double...\t");
    retval = nc_inq_var_endian(ncid,be_dbl_varid,&ed);
    if(ed == NC_ENDIAN_BIG) printf("passed\n"); else {printf("failed\n"); failures++;}

    retval = nc_close(ncid);
  }

  printf("** Failures Returned: [%d]\n",failures);
  return failures;
}
示例#21
0
void process_auswave(e *E){

  // netcdf vars
  int ncid;
  int varid;
  int retval;
  size_t attlen = 0;
  size_t from[3];
  size_t to[3];

  // for time conversion
  static char *calendar = "Standard";
  ut_system *u_system;
  double sec;
  int ierr, yr, mo, day, hr, min;

  int i,j,t;
  int count;


  // read in the auswave data so we can estimate wave setup
  //time = UNLIMITED ; // (192 currently)
  //lat = 411 ;
  //lon = 441 ;
  // open the file
  if((retval = nc_open(E->wave_input, NC_NOWRITE, &ncid)))
          fail("failed to open wave setup input file: error is %d\n",retval);

  // get the time data
  if((retval = nc_inq_dimid(ncid, "time", &varid)))
          fail("failed to get auswave dimid: error is %d\n",retval);

  if((retval = nc_inq_dimlen(ncid,varid,&E->nTimeWaves)))
          fail("failed to get auswave lat dimlen: error is %d\n",retval);

  //printf("aus waves_times = %zu\n", E->nTimeWaves);

  // get the auswave lat data
  if((retval = nc_inq_dimid(ncid, "lat", &varid)))
          fail("failed to get auswave lat dimid: error is %d\n",retval);

  if((retval = nc_inq_dimlen(ncid,varid,&E->nLatWaves)))
          fail("failed to get auswave lat dimlen: error is %d\n",retval);

  //printf("auswave lat = %zu\n", E->nLatWaves);

  // get the auswave lon data
  if((retval = nc_inq_dimid(ncid, "lon", &varid)))
          fail("failed to get auswave lon dimid: error is %d\n",retval);

  if((retval = nc_inq_dimlen(ncid,varid,&E->nLonWaves)))
          fail("failed to get auswave lon dimlen: error is %d\n",retval);

  //printf("auswave lat = %zu\n", E->nLonWaves);

  // process spatial dimensions
  // malloc room for the dim variable arrays
  E->wavesLat = malloc(E->nLatWaves*sizeof(double));
  E->wavesLon = malloc(E->nLonWaves*sizeof(double));

  nc_inq_varid(ncid, "lat", &varid);
  if((retval = nc_get_var_double(ncid, varid, &E->wavesLat[0])))
          fail("failed to read waves lat data: error is %d\n", retval);

  //printf("waves lat[0] = %f\n", E->wavesLat[0]);
  nc_inq_varid(ncid, "lon", &varid);
  if((retval = nc_get_var_double(ncid, varid, &E->wavesLon[0])))
          fail("failed to read waves lon data: error is %d\n", retval);

  //printf("waves lon[0] = %f\n", E->wavesLon[0]);

  // find the dimension indexes that cover the spatial region we need
  int lat_end;
  double dLatWaves, dLonWaves; // grid spacings for lat, lon for auswave
  dLatWaves = fabs(E->wavesLat[1] - E->wavesLat[0])*2.0;
  dLonWaves = fabs(E->wavesLon[1] - E->wavesLon[0])*2.0;
  for(i=0; i<E->nLatWaves; i++) {
          if(E->wavesLat[i] > (E->roms_min_lat-dLatWaves)) // greater than because auswave lat is monotonically decreasing
                  lat_end = i;
  }
  int lat_start;
  for(i=E->nLatWaves-1; i>=0; i--) {
          if(E->wavesLat[i] < (E->roms_max_lat+dLatWaves)) // less than because auswave lat is monotonically decreasing
                  lat_start = i;
  }
  //printf("wave data start lat = %f (%d), end lat = %f (%d)\n", E->wavesLat[lat_start],lat_start, E->wavesLat[lat_end],lat_end);
  int lon_start;
  for(i=0; i<E->nLonWaves; i++) {
          if(E->wavesLon[i] < (E->roms_min_lon-dLonWaves))
                  lon_start = i;
  }
  int lon_end;
  for(i=E->nLonWaves-1; i>=0; i--) {
          if(E->wavesLon[i] > (E->roms_max_lon+dLonWaves))
                  lon_end = i;
  }

  //printf("wave data start lon = %f, end lon = %f\n", E->wavesLon[lon_start], E->wavesLon[lon_end]);

  // TODO: add some error checking to the bounds code.
  // for example, if the spatial extent does not overlap then throw an exception

  // now just read in what we want from the files

  // reading in the whole dataset to avoid gaps in the interpolation
  lat_start = 0;
  lat_end = E->nLatWaves-1;
  lon_start = 0;
  lon_end = E->nLonWaves-1;

  free(E->wavesLat);
  free(E->wavesLon);
  E->nLatWaves = (lat_end - lat_start);
  E->nLonWaves = (lon_end - lon_start);
  E->wavesLat = malloc(E->nLatWaves*sizeof(double));
  E->wavesLon = malloc(E->nLonWaves*sizeof(double));
  // now re-read the lat and lon data
  size_t spatial_from[1], spatial_to[1];
  spatial_from[0] = lat_start;    spatial_to[0] = lat_end-lat_start;
  nc_inq_varid(ncid, "lat", &varid);
  if((retval = nc_get_vara_double(ncid, varid, spatial_from, spatial_to, &E->wavesLat[0])))
          fail("failed to read waves lat data: error is %d\n", retval);
  spatial_from[0] = lon_start;    spatial_to[0] = lon_end-lon_start;
  nc_inq_varid(ncid, "lon", &varid);
  if((retval = nc_get_vara_double(ncid, varid, spatial_from, spatial_to, &E->wavesLon[0])))
          fail("failed to read waves lon data: error is %d\n", retval);

  // process time
  E->wavesTime = malloc(E->nTimeWaves*sizeof(double));
  // read the data from the waves output file
  nc_inq_varid(ncid, "time", &varid);
  if((retval = nc_get_var_double(ncid, varid, &E->wavesTime[0])))
          fail("failed to read auswave time data: error is %d\n", retval);

  // normalize the time information between the roms_his file
  // and the tide data file
  // get everything in ROMS ocean_time
  // get the time metadata units
  nc_inq_attlen (ncid, varid, "units", &attlen);
  E->waves_time_units = (char *) malloc(attlen + 1); /* + 1 for trailing null */
  E->waves_time_units[attlen] = '\x0';
  nc_get_att_text(ncid, varid, "units", E->waves_time_units);
  //printf("waves time units = %s\n", E->waves_time_units);

  //printf("wavesTime[0] = %f\n", E->wavesTime[0]);
  // Make the Calendar calls
  //tval = 86460.0;	/* in seconds, this is 1 day and 1 minute */
  //tval = 8580;


  // Parse the units strings
  if( (E->waves_ref_time = ut_parse( E->u_system, E->waves_time_units, UT_ASCII )) == NULL ) {
          fprintf( stderr, "Error parsing units string \"%s\"\n", E->waves_time_units );
          exit(-1);
  }

  /*
     if( (ierr = utCalendar2_cal( E->wavesTime[0], E->waves_ref_time, &yr, &mo, &day, &hr, &min, &sec, calendar )) != 0 ) {
        fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr );
        exit(-1);
        }
     printf( "this date is %04d-%02d-%02d %02d:%02d:%06.3lf\n",yr, mo, day, hr, min, sec );
   */

  // put the waves time on the same time units as the roms time
  for(t=0; t<E->nTimeWaves; t++) {

          //printf("PRE: waveTimes[t] = %f  ", E->wavesTime[t]);
          // convert tide time into year, month, day, hour, minute and seconds
          if( (ierr = utCalendar2_cal( E->wavesTime[t], E->waves_ref_time, &yr, &mo, &day, &hr, &min, &sec, E->calendar )) != 0 ) {
                  fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr );
                  exit(-1);
          }
          //printf( "this date is %04d-%02d-%02d %02d:%02d:%06.3lf\n",yr, mo, day, hr, min, sec );

          // convert this date to be on the same units as the roms time
          if( (ierr = utInvCalendar2_cal( yr, mo, day, hr, min, sec, E->roms_ref_time, &E->wavesTime[t], E->calendar )) != 0 ) {
                  fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr );
                  exit(-1);
          }
          //printf( "POST: %04d-%02d-%02d %02d:%02d:%06.3lf is %lf %s in the %s calendar\n",
          //	yr, mo, day, hr, min, sec, E->wavesTime[t], E->roms_time_units, E->calendar );
  }


  // find the index bounds where the waves time overlaps the roms time
  // the waves times should fully cover the roms times
  E->waves_start_time_index = -1;
  E->start_time_roms = E->romsTime[0];

  // get the time start index for the tide file
  for(t=0; t<E->nTimeWaves; t++) {
          if(E->wavesTime[t]<=E->start_time_roms)
                  E->waves_start_time_index = t;
  }
  if(E->waves_start_time_index == -1) {
          fprintf(stderr,"couldn't find a matching start time in the waves file.\n");
          fprintf(stderr,"check to make sure the waves file times sufficiently overlap\n");
          fprintf(stderr,"the ROMS times.\n\n");
          exit(1);
  }

  // get the end index for the tide file
  E->waves_end_time_index = -1;
  E->end_time_roms = E->romsTime[E->nTimeRoms-1];
  for(t=E->nTimeWaves-1; t>=0; t--) {
          //printf("t = %d, wave_time = %f\n",t,E->wavesTime[t]);
          if(E->wavesTime[t] >= E->end_time_roms)
                  E->waves_end_time_index = t;
  }

  if(E->waves_end_time_index == -1) {
          fprintf(stderr,"couldn't find a matching end time in the waves file.\n");
          fprintf(stderr,"check to make sure the wave file times sufficiently overlap\n");
          fprintf(stderr,"the ROMS times.\n\n");
          fprintf(stderr,"end time ROMS = %f\n", E->end_time_roms);
          fprintf(stderr,"end time waves = %f\n", E->wavesTime[E->nTimeWaves-1]);
          exit(1);
  }

  //printf("start index = %d\n", E->waves_start_time_index);
  //printf("end index = %d\n", E->waves_end_time_index);
  E->nTimeWavesSubset = (E->waves_end_time_index - E->waves_start_time_index)+1;
  // malloc enough room for the variable arrays
  //sig_wav_ht(time, lat, lon)
  E->Hs = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves);
  E->Tp = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves);

  // make the time vector for the output file
  E->waves_interp_time = malloc(E->nTimeWavesSubset*sizeof(double));
  count=0;
  for(t=E->waves_start_time_index; t<=E->waves_end_time_index; t++) {
          E->waves_interp_time[count] = E->wavesTime[t];
          count++;
  }


  // get the sig wave height
  nc_inq_varid(ncid, "sig_wav_ht", &varid);
  //if((retval = nc_get_var_double(ncid, varid, &E->Hs[0][0][0])))
  //	fail("failed to read waves setup data: error is %d\n", retval);

  from[0] = E->waves_start_time_index;    to[0] = E->nTimeWavesSubset;
  from[1] = lat_start;                    to[1] = lat_end - lat_start;
  from[2] = lon_start;                    to[2] = lon_end - lon_start;
  if((retval = nc_get_vara_double(ncid, varid, from, to, &E->Hs[0][0][0])))
          fail("failed to read waves Hs data: error is %d\n", retval);

  //printf("sig_wave_ht[0][0][0] = %f\n", E->Hs[0][0][0]);

  // get the peak period
  nc_inq_varid(ncid, "pk_wav_per", &varid);
  if((retval = nc_get_vara_double(ncid, varid, from, to, &E->Tp[0][0][0])))
          fail("failed to read waves Hs data: error is %d\n", retval);

  //printf("pk_wav_per[0][0][0] = %f\n", E->Tp[0][0][0]);

  // close the file
  nc_close(ncid);



  // flip the auswave data so the lat vector is monotonically increasing
  double ***flipData = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves);
  double  *flipLat = malloc(E->nLatWaves*sizeof(double));
  // flip the lat vector
  for(i=0; i<E->nLatWaves; i++) {
          flipLat[i] = E->wavesLat[E->nLatWaves-1-i];
  }
  // copy the flipped data back
  for(i=0; i<E->nLatWaves; i++) {
          E->wavesLat[i] = flipLat[i];
  }
  // flip the Hs data array
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          flipData[t][i][j] = E->Hs[t][E->nLatWaves-1-i][j];
                  }
          }
  }
  // copy it back
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          E->Hs[t][i][j] = flipData[t][i][j];
                  }
          }
  }
  // flip the Tp data array
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          flipData[t][i][j] = E->Tp[t][E->nLatWaves-1-i][j];
                  }
          }
  }
  // copy it back
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          E->Tp[t][i][j] = flipData[t][i][j];
                  }
          }
  }
  free(flipData);
  free(flipLat);

#ifdef CHECK
  // temporarily mess with this input data to check!
  for(t=0; t<E->nTimeWavesSubset; t++) {
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          E->Tp[t][i][j] = (double)t;
                          E->Hs[t][i][j] = (double)t;
                  }
          }
  }
#endif

  // malloc room for the output nearest neighbor interp auswave  data
  // target grid for auswave data data

  // do a natural neighbour interpolation on the tide data we just read in
  // to fill in the land masked values before interpolating onto the ROMS grid

  E->Hs_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho);
  E->Tp_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho);
  // just for writing the netcdf file - trash this!
  //double *time_vector = malloc(E->nTimeWavesSubset*sizeof(double));
  //printf("(E->waves_end_time_index-E->waves_start_time_index) = %d\n", E->nTimeWavesSubset);


  // set up variables for the lib-nn calls
  // nn optimized
  E->pin = malloc(E->nLonWaves * E->nLatWaves * sizeof(point));
  E->zin = malloc(E->nLonWaves * E->nLatWaves * sizeof(double));

  E->xout = malloc(E->nLonRho * E->nLatRho * sizeof(double));
  E->yout = malloc(E->nLonRho * E->nLatRho * sizeof(double));
  E->zout = malloc(E->nLonRho * E->nLatRho * sizeof(double));



  // find out how many valid data points we have
  // and setup the input array for lib-nn
  //time_vector[t] = (double)t;
  //printf("setting up source grid for nn...\n");
  E->nin = 0;
  for(i=0; i<E->nLatWaves; i++) {
          for(j=0; j<E->nLonWaves; j++) {
                  if(E->Hs[0][i][j] > -999.0) {
                          E->pin[E->nin].x = E->wavesLon[j];
                          E->pin[E->nin].y = E->wavesLat[i];
                          //E->nn_diff[E->nn_n].z = E->Hs[t][i][j];
                          //printf("i = %d, j = %d, lat = %.15g lon = %.15g Hs = %.15g\n", E->nn_diff[E->nn_n].x, E->nn_diff[E->nn_n].y, E->nn_diff[E->nn_n].z);
                          E->nin++;
                  }
          }
  }
  //printf("done\n");fflush(stdout);


  // now set up the output array for the nn interpolation
  // this is the roms grid

  E->nout = 0;
  for(i=0; i<E->nLonRho; i++) {
          for(j=0; j<E->nLatRho; j++) {
                E->xout[E->nout] = E->lon_rho[i][j];
                E->yout[E->nout] = E->lat_rho[i][j];
                E->zout[E->nout] = NaN;
                E->nout++;
          }
  }
  //printf("done\n");fflush(stdout);

  // setup the natural neighbour interpolation
  // only need to do this once
  E->d = delaunay_build(E->nin, E->pin, 0, NULL, 0, NULL);

  // create interpolator
  E->nn = nnai_build(E->d, E->nout, E->xout, E->yout);

  // for each time level
  for(t=0; t<E->nTimeWavesSubset; t++) {
      //printf("Hs: t = %d\n",t);
          // setup nodal values for the nn interps
          E->nin = 0;
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          if(E->Hs[t][i][j] > -999.0) {
                                  E->pin[E->nin].z = E->Hs[t][i][j];
                                  E->zin[E->nin] = E->pin[E->nin].z;
                                  E->nin++;
                          }
                  }
          }

          // do the interpolation
          nnai_interpolate(E->nn, E->zin, E->zout);

          // splat interpolated values onto the roms grid and apply land-sea mask
          count = 0;
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {
                          if(E->mask_rho[i][j] == 0){
                                  E->Hs_on_roms[t][i][j] = NC_FILL_DOUBLE;
                          }
                          else{
                                  E->Hs_on_roms[t][i][j] = E->zout[count];
                          }
                          count++;
                  }
          }

          /*
             // write it out to check
             //E->nn_nx * E->nn_ny, E->nn_interp,
             int lat_dimid, lon_dimid, time_dimid, dimIds[2];
             int lat_varid, lon_varid, time_varid, interp_varid;
             // create the file
             nc_create("hs_interp.nc", NC_CLOBBER, &ncid);
             // def dimensions
             nc_def_dim(ncid, "lat", E->nLonRho, &lat_dimid);
             nc_def_dim(ncid, "lon", E->nLatRho, &lon_dimid);
             // def vars
             dimIds[0] = lat_dimid;
             dimIds[1] = lon_dimid;
             //nc_def_var(ncid, "lat", NC_DOUBLE, 1, &dimIds[0], &lat_varid);
             //nc_def_var(ncid, "lon", NC_DOUBLE, 1, &dimIds[1], &lon_varid);
             nc_def_var(ncid, "hs_interp_on_roms", NC_DOUBLE, 2, dimIds, &interp_varid);
             nc_enddef(ncid);
             // write the data
             //nc_put_var_double(ncid, lat_varid, &E->wavesLat[0]);
             //nc_put_var_double(ncid, lon_varid, &E->wavesLon[0]);
             nc_put_var_double(ncid, interp_varid, &E->Hs_on_roms[0][0][0]);
             // close the file
             nc_close(ncid);
             exit(1);
        */

  } // end of loop over Hs time levels


  // now interp the Tp variable

  // for each time level
  for(t=0; t<E->nTimeWavesSubset; t++) {
        //printf("Tp: t = %d\n", t);
          E->nin = 0;
          for(i=0; i<E->nLatWaves; i++) {
                  for(j=0; j<E->nLonWaves; j++) {
                          if(E->Tp[t][i][j] > -999.0) {
                                  E->pin[E->nin].z = E->Tp[t][i][j];
                                  E->zin[E->nin] = E->pin[E->nin].z;
                                  E->nin++;
                          }
                  }
          }

          // do the interpolation
          nnai_interpolate(E->nn, E->zin, E->zout);

          // splat interpolated values onto the roms grid and apply land-sea mask
          count = 0;
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {
                          if(E->mask_rho[i][j] == 0){
                                  E->Tp_on_roms[t][i][j] = NC_FILL_DOUBLE;
                          }
                          else{
                                  E->Tp_on_roms[t][i][j] = E->zout[count];
                          }
                          count++;
                  }
          }

          /*
          // write it out to check
          //E->nn_nx * E->nn_ny, E->nn_interp,
          int lat_dimid, lon_dimid, time_dimid, dimIds[2];
          int lat_varid, lon_varid, time_varid, interp_varid;
          // create the file
          nc_create("tp_interp.nc", NC_CLOBBER, &ncid);
          // def dimensions
          nc_def_dim(ncid, "lat", E->nLonRho, &lat_dimid);
          nc_def_dim(ncid, "lon", E->nLatRho, &lon_dimid);
          // def vars
          dimIds[0] = lat_dimid;
          dimIds[1] = lon_dimid;
          //nc_def_var(ncid, "lat", NC_DOUBLE, 1, &dimIds[0], &lat_varid);
          //nc_def_var(ncid, "lon", NC_DOUBLE, 1, &dimIds[1], &lon_varid);
          nc_def_var(ncid, "tp_interp_on_roms", NC_DOUBLE, 2, dimIds, &interp_varid);
          nc_enddef(ncid);
          // write the data
          //nc_put_var_double(ncid, lat_varid, &E->wavesLat[0]);
          //nc_put_var_double(ncid, lon_varid, &E->wavesLon[0]);
          nc_put_var_double(ncid, interp_varid, &E->Tp_on_roms[0][0][0]);
          // close the file
          nc_close(ncid);
          exit(1);
          */



  } // end of loop over Tp time levels

  free(E->pin);
  free(E->zin);

  free(E->xout);
  free(E->yout);
  free(E->zout);

  free(E->d);
  free(E->nn);

  //printf("done nn interp for waves\n");

  // estimate wave setup on roms
  // setup is only calculates at the coastal points
  // to calculate setup, we need Hs, Tp and slope at coastal pointers

  // read in the slope data
  //printf("calculating wave setup...");
  get_coastal_slope(E);

  // malloc room for the setup field
  // jNOTE: fix up the size of the time dimension here!
  E->setup_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho);
  // malloc room for the time interpolated data


  // assign closest slope value to costline derived from the roms rho_mask
  double this_time;
  double this_lat;
  double this_lon;
  int **nearest_index = malloc2d_int(E->nLonRho, E->nLatRho);

  // first get the index mapping for each coastal cell
  for(i=0; i<E->nLonRho; i++) {
          for(j=0; j<E->nLatRho; j++) {
                  if(E->coastline_mask[i][j] == 1) { // if this point is a coastal point
                          // get longitude and latitude of the point
                          this_time = t;
                          this_lat = E->lat_rho[i][j];
                          this_lon = E->lat_rho[i][j];
                          nearest_index[i][j] = get_nearest_slope_index(E, this_lat, this_lon, E->slopeLat, E->slopeLon);
                  }
                  else{
                          //printf("fill it: i = %d, j = %d\n",i,j);
                          nearest_index[i][j] = -999;
                  }
          }
  }


  for(t=0; t<E->nTimeWavesSubset; t++) {
          //printf("#### t = %d\n",t);
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {

                          if(E->coastline_mask[i][j] == 1.0) { // if this point is a coastal point
                                  /*
                                     // get longitude and latitude of the point
                                     this_time = t;
                                     this_lat = E->lat_rho[i][j];
                                     this_lon = E->lon_rho[i][j];
                                     E->setup_on_roms[t][i][j] = get_nearest_setup(E, this_time, this_lat, this_lon, E->setup, E->wavesLat, E->wavesLon);
                                     //exit(1);
                                   */
                                   // some cases for Hs and Tp are zero.
                                   // don't call get_setup() for these because it will divide by zero
                                  if( (E->Hs_on_roms[t][i][j] == 0.0) || (E->Tp_on_roms[t][i][j] == 0.0))
                                    E->setup_on_roms[t][i][j] = 0.0;
                                  else
                                    E->setup_on_roms[t][i][j] = get_setup(E->Hs_on_roms[t][i][j], E->Tp_on_roms[t][i][j], E->slope[nearest_index[i][j]]);

              #ifdef CHECK
                                  // temporarily splat with Hs to check
                                  E->setup_on_roms[t][i][j] = E->Hs_on_roms[t][i][j];
              #endif
                          }
                          else{
                                  //printf("fill it: i = %d, j = %d\n",i,j);
                                  E->setup_on_roms[t][i][j] = NC_FILL_DOUBLE;
                          }
                  }
          }
  }
  //printf("...done\n");

  // time interpolate the wavesetup data onto the roms time vector
  //printf("creating %d interpolated time levels for the setup field\n", E->nTimeRoms);
  E->setup_on_roms_time_interp = malloc3d_double(E->nTimeRoms, E->nLonRho, E->nLatRho);
  // initialize this array
  for(t=0; t<E->nTimeRoms; t++) {
          for(i=0; i<E->nLonRho; i++) {
                  for(j=0; j<E->nLatRho; j++) {
                          E->setup_on_roms_time_interp[t][i][j] = NC_FILL_DOUBLE;
                  }
          }
  }
  // target time vector = E->romsTime
  // source time vector = E->wavesTime
  // y value vector
  double *ypts = malloc(E->nTimeWavesSubset*sizeof(double));
  double *interp_y = malloc(E->nTimeRoms*sizeof(double));
  for(i=0; i<E->nLonRho; i++) {
          for(j=0; j<E->nLatRho; j++) {
                  if(E->setup_on_roms[0][i][j] != NC_FILL_DOUBLE) {
                          for(t=0; t<E->nTimeWavesSubset; t++) {
                                  // get the wave setup vector at this location
                                  ypts[t] = E->setup_on_roms[t][i][j];
                          }
                          time_interp_field(&E->wavesTime[E->waves_start_time_index], &ypts[0], E->nTimeWavesSubset, &E->romsTime[0], &interp_y[0], E->nTimeRoms);

                          // now put this data into the time interp array
                          for(t=0; t<E->nTimeRoms; t++) {
                                  // get the wave setup vector at this location
                                  E->setup_on_roms_time_interp[t][i][j] = interp_y[t];
                          }
                  }
          }
  }
  //printf("done\n");
  free(ypts);
  free(interp_y);

  free(E->Hs);
  free(E->Tp);
  free(E->Hs_on_roms);
  free(E->Tp_on_roms);
  free(E->wavesLon);
  free(E->wavesLat);
  free(E->setup_on_roms);

  free(E->slope);
  free(E->slopeLat);
  free(E->slopeLon);
}
示例#22
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing HDF5/NetCDF-4 interoperability...\n");
   printf("*** testing HDF5 compatibility...");
   {
#define GRPA_NAME "grpa"
#define VAR_NAME "vara"
#define NDIMS 2
      int nrowCur = 7;               /* current size */
      int ncolCur = 3;
      int nrowMax = nrowCur + 0;     /* maximum size */
      int ncolMax = ncolCur + 0;

      hid_t xdimId;
      hid_t ydimId;
      hsize_t xscaleDims[1];
      hsize_t yscaleDims[1];
      hid_t xdimSpaceId, spaceId;
      hid_t fileId;
      hid_t fapl;
      hsize_t curDims[2];
      hsize_t maxDims[2];
      hid_t dataTypeId, dsPropertyId, grpaId, grpaPropId, dsId;
      hid_t ydimSpaceId;
      const char * dimNameBase
	 = "This is a netCDF dimension but not a netCDF variable.";
      char dimNameBuf[1000];
      char *varaName = "/grpa/vara";
      short amat[nrowCur][ncolCur];
      int ii, jj;

      xscaleDims[0] = nrowCur;
      yscaleDims[0] = ncolCur;
      if ((xdimSpaceId = H5Screate_simple(1, xscaleDims, NULL)) < 0) ERR;

      /* With the SEMI close degree, the HDF5 file close will fail if
       * anything is left open. */
      if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
      if (H5Pset_fclose_degree(fapl, H5F_CLOSE_SEMI)) ERR;

      /* Create file */
      if((fileId = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC,
			     H5Pcreate(H5P_FILE_CREATE), fapl)) < 0) ERR;
      if (H5Pclose(fapl) < 0) ERR;

      /* Create data space */
      curDims[0] = nrowCur;
      curDims[1] = ncolCur;
      maxDims[0] = nrowMax;
      maxDims[1] = ncolMax;
      if ((spaceId = H5Screate_simple(2, curDims, maxDims)) < 0) ERR;

      if ((dataTypeId = H5Tcopy(H5T_NATIVE_SHORT)) < 0) ERR;

      if ((dsPropertyId = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;

      if ((grpaPropId = H5Pcreate(H5P_GROUP_CREATE)) < 0) ERR;
      if ((grpaId = H5Gcreate2(fileId, GRPA_NAME, H5P_DEFAULT,
			       grpaPropId, H5P_DEFAULT)) < 0) ERR;
      if (H5Pclose(grpaPropId) < 0) ERR;

      /* Create vara dataset */
      if ((dsId = H5Dcreate2(fileId, varaName, dataTypeId, spaceId,
			     H5P_DEFAULT, dsPropertyId,
			     H5P_DEFAULT)) < 0) ERR;

      if (H5Pclose(dsPropertyId) < 0) ERR;
      if (H5Tclose(dataTypeId) < 0) ERR;
      if ((ydimSpaceId = H5Screate_simple(1, yscaleDims, NULL)) < 0) ERR;

      /* Create xdim dimension dataset */
      if ((xdimId = H5Dcreate2(fileId, "/xdim", H5T_IEEE_F32BE,
			       xdimSpaceId, H5P_DEFAULT, H5P_DEFAULT,
			       H5P_DEFAULT)) < 0) ERR;

      if (H5Sclose(xdimSpaceId) < 0) ERR;

      /* Create ydim dimension dataset */
      if ((ydimId = H5Dcreate2(fileId, "/ydim", H5T_IEEE_F32BE,
			       ydimSpaceId, H5P_DEFAULT, H5P_DEFAULT,
			       H5P_DEFAULT)) < 0) ERR;
      if (H5Sclose(ydimSpaceId) < 0) ERR;

      /* Create xdim scale */
      sprintf(dimNameBuf, "%s%10d", dimNameBase, nrowCur);
      if (H5DSset_scale(xdimId, dimNameBuf) < 0) ERR;

      /* Create ydim scale */
      sprintf(dimNameBuf, "%s%10d", dimNameBase, ncolCur);
      if (H5DSset_scale(ydimId, dimNameBuf) < 0) ERR;

      /* Attach dimension scales to the dataset */
      if (H5DSattach_scale(dsId, xdimId, 0) < 0) ERR;

      if (H5DSattach_scale(dsId, ydimId, 1) < 0) ERR;

      /* Close stuff. */
      if (H5Dclose(xdimId) < 0) ERR;
      if (H5Dclose(ydimId) < 0) ERR;
      if (H5Dclose(dsId) < 0) ERR;
      if (H5Gclose(grpaId) < 0) ERR;
      if (H5Sclose(spaceId) < 0) ERR;
      if (H5Fclose(fileId) < 0) ERR;

      /* Create some data */
      for (ii = 0; ii < nrowCur; ii++)
	 for (jj = 0; jj < ncolCur; jj++)
	    amat[ii][jj] = 100 * ii + jj;

      /* Re-open file */
      if ((fileId = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
      if ((grpaId = H5Gopen2(fileId, GRPA_NAME, H5P_DEFAULT)) < 0) ERR;
      if ((dsId = H5Dopen2(grpaId, varaName,  H5P_DEFAULT)) < 0) ERR;

      /* Write dataset */
      if (H5Dwrite(dsId, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
		   amat) < 0) ERR;

      /* Write dimension values for both xdim, ydim */
      {
      short xydimMat[ nrowCur >= ncolCur ? nrowCur : ncolCur];
      for (ii = 0; ii < nrowCur; ii++)
	 xydimMat[ii] = 0;    /*#### 100 * ii; */

      /* Write xdim */
      if ((xdimId = H5Dopen2(fileId, "/xdim", H5P_DEFAULT)) < 0) ERR;
      if (H5Dwrite(xdimId, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL,
		   H5P_DEFAULT, xydimMat) < 0) ERR;
      if (H5Dclose(xdimId) < 0) ERR;

      /* Write ydim */
      if ((ydimId = H5Dopen2(fileId, "/ydim", H5P_DEFAULT)) < 0) ERR;
      if (H5Dwrite(ydimId, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL,
		   H5P_DEFAULT, xydimMat) < 0) ERR;
      if (H5Dclose(ydimId) < 0) ERR;
      }

      if (H5Dclose(dsId) < 0) ERR;
      if (H5Gclose(grpaId) < 0) ERR;
      if (H5Fclose(fileId) < 0) ERR;

      {
	 int ncid, grpid, nvars, ngatts, ndims, unlimdimid, ngrps;
	 char name_in[NC_MAX_NAME + 1];
	 nc_type xtype_in;
	 int ndims_in, natts_in, dimid_in[NDIMS];

/*	 nc_set_log_level(5);*/
	 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
	 if (ndims != 2 || nvars != 0 || ngatts != 0 || unlimdimid != -1) ERR;
	 if (nc_inq_grps(ncid, &ngrps, &grpid)) ERR;
	 if (ngrps != 1) ERR;
	 if (nc_inq(grpid, &ndims, &nvars, &ngatts, &unlimdimid)) ERR;
	 if (ndims != 0 || nvars != 1 || ngatts != 0 || unlimdimid != -1) ERR;

	 if (nc_inq_var(grpid, 0, name_in, &xtype_in, &ndims_in, dimid_in,
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_NAME) || xtype_in != NC_SHORT || ndims_in != NDIMS ||
	     dimid_in[0] != 0 || dimid_in[1] != 1 || natts_in != 0) ERR;

	 if (nc_close(ncid)) ERR;
      }
   }
   SUMMARIZE_ERR;
#ifdef USE_SZIP
   printf("*** testing HDF5 compatibility with szip...");
   {

#define DEFLATE_LEVEL 9
#define MAX_NAME 100
#define NUM_CD_ELEM 10
/* HDF5 defines this... */
#define DEFLATE_NAME "deflate"
#define DIM1_LEN 3000
#define GRP_NAME "George_Washington"
#define BATTLE_RECORD "Battle_Record"

      hid_t fileid, grpid, spaceid, datasetid;
      int data_out[DIM1_LEN], data_in[DIM1_LEN];
      hsize_t dims[1] = {DIM1_LEN};
      hid_t propid;
      char name_in[MAX_NAME + 1];
      int ncid, ndims_in, nvars_in, ngatts_in, unlimdimid_in, ngrps_in;
      int nc_grpid;
      int dimid_in[1], natts_in;

      nc_type xtype_in;
      int i;

      for (i = 0; i < DIM1_LEN; i++)
	 data_out[i] = i;

      /* Open file and create group. */
      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
			      H5P_DEFAULT)) < 0) ERR;
      if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR;

      /* Write an array of bools, with szip compression. */
      if ((propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
      if (H5Pset_layout(propid, H5D_CHUNKED)) ERR;
      if (H5Pset_chunk(propid, 1, dims)) ERR;
      if (H5Pset_szip(propid, H5_SZIP_EC_OPTION_MASK, 32)) ERR;
      if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      if ((datasetid = H5Dcreate(grpid, BATTLE_RECORD, H5T_NATIVE_INT,
				 spaceid, propid)) < 0) ERR;
      if (H5Dwrite(datasetid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT,
		   data_out) < 0) ERR;
      if (H5Dclose(datasetid) < 0 ||
	  H5Pclose(propid) < 0 ||
	  H5Sclose(spaceid) < 0 ||
	  H5Gclose(grpid) < 0 ||
	  H5Fclose(fileid) < 0)
	 ERR;

      /* Open the file with netCDF and check it. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &ngatts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 0 || nvars_in != 0 || ngatts_in != 0 || unlimdimid_in != -1) ERR;
      if (nc_inq_grps(ncid, &ngrps_in, &nc_grpid)) ERR;
      if (ngrps_in != 1) ERR;
      if (nc_inq(nc_grpid, &ndims_in, &nvars_in, &ngatts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || ngatts_in != 0 || unlimdimid_in != -1) ERR;

      /* Check the variable. */
      if (nc_inq_var(nc_grpid, 0, name_in, &xtype_in, &ndims_in, dimid_in,
      		     &natts_in)) ERR;
      if (strcmp(name_in, BATTLE_RECORD) || xtype_in != NC_INT || ndims_in != 1 ||
      	  dimid_in[0] != 0 || natts_in != 0) ERR;

      /* Check the data. */
      if (nc_get_var(nc_grpid, 0, data_in)) ERR;
      for (i = 0; i < DIM1_LEN; i++)
	 if (data_in[i] != data_out[i]) ERR;

      if (nc_close(ncid)) ERR;

   }
   SUMMARIZE_ERR;
#endif /* USE_SZIP */
   FINAL_RESULTS;
}
示例#23
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 dimensions.\n");
   printf("*** Checking that netcdf-4 dimids inq works on netcdf-3 file...");
   {
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];

      /* Create a netcdf-3 file with one dim. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_dimids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Checking that netcdf-4 dimids inq works on more complex netcdf-3 file...");
   {
      int ncid, dimid;
      int lon_dimid;
      int ndims_in, dimids_in[MAX_DIMS];

      /* Create a netcdf-3 file with three dim. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR;
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_dimids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 3 || dimids_in[0] != 0 || dimids_in[1] != 1 ||
	 dimids_in[2] != 2) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing file with just one dimension...");
   {
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int varid_in;

      /* Create a file with one dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &dimid)) ERR;

      /* Check out what we've got. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing renaming of one dimension...");
   {
      int ncid, dimid, varid_in;
      char name_in[NC_MAX_NAME + 1];
      size_t len_in;
      int ndims_in, dimids_in[MAX_DIMS];

      /* Reopen the file with one dim, and change the name of the dim. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_rename_dim(ncid, 0, BUBBA)) ERR;

      /* Check out what we've got. */
      dimid = 0;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (dimids_in[0] != 0) ERR;
      if (nc_inq_dimid(ncid, BUBBA, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen and check out what we've got again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_dimid(ncid, BUBBA, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_dimname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, BUBBA)) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != LAT_LEN) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing file with just one unlimited dimension...");
   {
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      int nunlimdims_in;

      /* Create a file with one unlimied dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR;

      /* Check it out before the enddef. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      
      /* Automatically enddef and close. */
      if (nc_close(ncid)) ERR;

      /* Reopen and check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define ROMULUS "Romulus"
#define REMUS "Remus"
#define DIMS2 2   
   printf("*** Testing file with two unlimited dimensions...");
   {
      int ncid, dimid[DIMS2];
      int ndims_in, dimids_in[DIMS2];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in[DIMS2];
      int nunlimdims_in;

      /* Create a file with one unlimied dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, REMUS, NC_UNLIMITED, &dimid[0])) ERR;
      if (nc_def_dim(ncid, ROMULUS, NC_UNLIMITED, &dimid[1])) ERR;

      /* Check it out before the enddef. */
      if (nc_inq_dim(ncid, dimid[0], name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, REMUS)) ERR;
      if (nc_inq_dim(ncid, dimid[1], name_in, &len_in)) ERR;
      if (len_in != NC_UNLIMITED || strcmp(name_in, ROMULUS)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in[0])) ERR;
      if (unlimdimid_in[0] != 1) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, unlimdimid_in)) ERR;
      if (nunlimdims_in != 2 || unlimdimid_in[0] != 1 || unlimdimid_in[1] != 0) ERR;
      
      /* Automatically enddef and close. */
      if (nc_close(ncid)) ERR;

      /* Reopen and check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing ordering of dimensions...");
   {
#define A_NAME "a"
#define B_NAME "b"
#define A_LEN 50
#define B_LEN 92
#define A_DIMID 1
#define B_DIMID 0

      int ncid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int dimid_a, dimid_b;

      /* Create a file with two dims and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, B_NAME, B_LEN, &dimid_b)) ERR;
      if (nc_def_dim(ncid, A_NAME, A_LEN, &dimid_a)) ERR;
      if (dimid_b != B_DIMID || dimid_a != A_DIMID) ERR;

      /* Check out what we've got. */
      if (nc_inq_dim(ncid, dimid_a, name_in, &len_in)) ERR;
      if (len_in != A_LEN || strcmp(name_in, A_NAME)) ERR;
      if (nc_inq_dim(ncid, dimid_b, name_in, &len_in)) ERR;
      if (len_in != B_LEN || strcmp(name_in, B_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 2 || dimids_in[0] != 0 || dimids_in[1] != 1) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq_dim(ncid, B_DIMID, name_in, &len_in)) ERR;
      if (len_in != B_LEN || strcmp(name_in, B_NAME)) ERR;
      if (nc_inq_dim(ncid, A_DIMID, name_in, &len_in)) ERR;
      if (len_in != A_LEN || strcmp(name_in, A_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 2 || dimids_in[0] != 0 ||
	  dimids_in[1] != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing file with just one unlimited dimension and one var...");
   {
      int ncid, dimid, dimids[MAX_DIMS];
      int level_varid;
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      size_t start[MAX_DIMS], count[MAX_DIMS];
      int varid_in, nvars_in, nunlimdims_in;
      unsigned long long uint64_data[1] = {42};

      /* Create a file with one unlimied dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (dimid != 0) ERR;
      dimids[0] = dimid;
      if (nc_def_var(ncid, LEVEL_NAME, NC_UINT64, 1, dimids, &level_varid)) ERR;
      if (level_varid != 0) ERR;

      /* Check it out before enddef. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != 0 || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR;
      if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME)) ERR;

      /* Now write one record of data to the var. */
      start[0] = 0;
      count[0] = 1;
      if (nc_put_vara_ulonglong(ncid, 0, start, count, uint64_data)) ERR;

      /* Check dimension informaiton again. Now the length of this
       * dimension should be one. */
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
      if (len_in != 1) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR;
      if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME)) ERR;

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

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_unlimdim(ncid, &unlimdimid_in)) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &nunlimdims_in, &unlimdimid_in)) ERR;
      if (nunlimdims_in != 1 || unlimdimid_in != 0) ERR;
      if (unlimdimid_in != 0) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 || unlimdimid_in != 0) ERR;
      if (nc_inq_varid(ncid, LEVEL_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME) || xtype_in != NC_UINT64 || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;
      if (nc_inq_varname(ncid, 0, name_in)) ERR;
      if (strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing adding a coordinate var to file with dimension...");
   {
      int ncid, dimid, dimids[MAX_DIMS];
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      int nvars_in, dim5_varid;

      /* Create a file with one dim and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimid)) ERR;

      /* Check out what we've got. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 0 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 0 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;

      /* Add a coordinate var for this dimension. */
      dimids[0] = 0;
      if (nc_def_var(ncid, DIM5_NAME, NC_FLOAT, 1, dimids, &dim5_varid)) ERR;

      /* Check it out. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != -1) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != DIM5_LEN || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Testing adding a coordinate var to file with unlimited dimension...");
   {
      int ncid, dimid, dimids[MAX_DIMS];
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int unlimdimid_in;
      size_t start[MAX_DIMS], count[MAX_DIMS], index[MAX_DIMS];
      unsigned short data[2] = {42, 24}, data_in[2];
      int nvars_in, hp_varid, dim5_varid;

      /* Create a file with one dim and one var. This time make
       * it an unlimited dim. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, NC_UNLIMITED, &dimid)) ERR;
      if (dimid != 0) ERR;
      dimids[0] = dimid;
      if (nc_def_var(ncid, HP_NAME, NC_USHORT, 1, dimids, &hp_varid)) ERR;
      if (hp_varid != 0) ERR;

      /* Check out what we've got. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 0 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, HP_NAME) || xtype_in != NC_USHORT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      /* Add a record to the HP variable. */
      start[0] = 0;
      count[0] = 1;
      if (nc_put_vara(ncid, hp_varid, start, count, data)) ERR;

      /* Check to ensure dimension grew. */
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;

      /* Reread the value just written. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, hp_varid, index, data_in)) ERR;
      if (data_in[0] != data[0]) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 1 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;

      /* Add a coordinate var for this dimension. */
      dimids[0] = 0;
      if (nc_def_var(ncid, DIM5_NAME, NC_FLOAT, 1, dimids, &dim5_varid)) ERR;

      /* Check it out. */
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 2 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, dim5_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;

      /* Reopen and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
      if (ndims_in != 1 || nvars_in != 2 || natts_in != 0 ||
	 unlimdimid_in != 0) ERR;
      if (nc_inq_dim(ncid, 0, name_in, &len_in)) ERR;
      if (len_in != 1 || strcmp(name_in, DIM5_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1 || dimids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, dim5_varid, name_in, &xtype_in, &ndims_in, dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, DIM5_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != 0 || natts_in != 0) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Creating file with 1 data var, 2 dims, and 2 coord. vars...");

   {
      int ncid, dimids[MAX_DIMS];
      int lat_dimid, lon_dimid, lat_varid, lon_varid;
      int pres_varid;
      char name_in[NC_MAX_NAME + 1];
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      float lat[LAT_LEN], lon[LON_LEN];
      float lat_in[LAT_LEN], lon_in[LON_LEN];
      double pres[LAT_LEN][LON_LEN], pres_in[LAT_LEN][LON_LEN];
      int i, j;

      /* Lats and lons suitable for some South American data. */
      for (lat[0] = 40.0, i = 1; i < LAT_LEN; i++)
	 lat[i] = lat[i - 1] + .5;
      for (lon[0] = 20.0, i = 1; i < LON_LEN; i++)
	 lon[i] = lon[i - 1] + 1.5;

      /* Some phoney 2D pressure data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    pres[i][j] = 1013.1 + j;
   
      /* Create a file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define lat and lon dimensions, with associated variables. */
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)) ERR;
      dimids[0] = lat_dimid;
      if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)) ERR;
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR;
      dimids[0] = lon_dimid;
      if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)) ERR;

      /* Define a 2D variable called pressure, with NC_DOUBLE on a lat
       * lon grid. */
      dimids[0] = lat_dimid;
      dimids[1] = lon_dimid;
      if (nc_def_var(ncid, PRES_NAME, NC_DOUBLE, 2, dimids, &pres_varid)) ERR;

      /* Check our dimensions. */
      if (nc_inq_dim(ncid, lat_dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dim(ncid, lon_dimid, name_in, &len_in)) ERR;
      if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR;
      if (nc_inq_var(ncid, lat_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lat_dimid || natts_in != 0) ERR;
      if (nc_inq_var(ncid, lon_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lon_dimid || natts_in != 0) ERR;

      /* Check our data variable. */
      if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 2 ||
	  dimids_in[0] != lat_dimid || dimids_in[1] != lon_dimid || natts_in != 0) ERR;
      
      /* Write our latitude and longitude values. This writes all
       * metadata to disk too. */
      if (nc_put_var_float(ncid, lat_varid, lat)) ERR;
      if (nc_put_var_float(ncid, lon_varid, lon)) ERR;

      /* Write our 2D pressure values. */
      if (nc_put_var_double(ncid, pres_varid, (double *)pres)) ERR;

      /* Check our latitude and longitude values. */
      if (nc_get_var(ncid, lat_varid, lat_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 if (lat[i] != lat_in[i]) ERR;
      if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR;
      for (i = 0; i < LON_LEN; i++)
	 if (lon[i] != lon_in[i]) ERR;

      /* Check our pressure values. */
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (pres[i][j] != pres_in[i][j]) ERR;

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

      /* Reopen the file and check it out again. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check our dimensions. */
      if (nc_inq_dim(ncid, lat_dimid, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dim(ncid, lon_dimid, name_in, &len_in)) ERR;
      if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR;
      if (nc_inq_var(ncid, lat_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lat_dimid || natts_in != 0) ERR;
      if (nc_inq_var(ncid, lon_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != lon_dimid || natts_in != 0) ERR;

      /* Check our data variable. */
      if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 2 ||
	  dimids_in[0] != lat_dimid || dimids_in[1] != lon_dimid || natts_in != 0) ERR;
      
      /* Check our latitude and longitude values. */
      if (nc_get_var(ncid, lat_varid, lat_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 if (lat[i] != lat_in[i]) ERR;
      if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR;
      for (i = 0; i < LON_LEN; i++)
	 if (lon[i] != lon_in[i]) ERR;

      /* Check our pressure values. */
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (pres[i][j] != pres_in[i][j]) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Creating file with 3 data vars, 4 dims, and 2 coord. vars...");

   {
      int ncid, lat_dimid, dimids[MAX_DIMS];
      int level_dimid, time_dimid, elev_varid;
      int lat_varid, lon_dimid, lon_varid, pres_varid, hp_varid;
      double pres[LAT_LEN][LON_LEN][LEVEL_LEN][TIME_LEN];
      double pres_in[LAT_LEN][LON_LEN][LEVEL_LEN][TIME_LEN];
      unsigned short hp[LAT_LEN][LON_LEN][TIME_LEN];
      unsigned short hp_in[LAT_LEN][LON_LEN][TIME_LEN];
      unsigned long long elev[LAT_LEN][LON_LEN], elev_in[LAT_LEN][LON_LEN];
      size_t start[4], count[4];
      int nvars, ndims, natts, unlimdimid;
      int natts_in, ndims_in, dimids_in[MAX_DIMS];
      nc_type xtype_in;
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      float lat[LAT_LEN], lon[LON_LEN];
      float lat_in[LAT_LEN], lon_in[LON_LEN];
      int i, j, k, l;

      /* Some phony 4D pressure data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (k = 0; k < LEVEL_LEN; k++)
	       for (l = 0; l <TIME_LEN; l++)
		  pres[i][j][k][l] = 1013.1 + j;
   
      /* Some phony 3D hp data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (l = 0; l <TIME_LEN; l++)
	       hp[i][j][l] = 100 + l;
   
      /* Some phony 2D elevaton data. */
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    elev[i][j] = 1010101022223333ULL  + i + j;

      /* Some phony 1D lats and lons. */
      for (i = 0; i < LAT_LEN; i++)
	 lat[i] = i * 5.;
      for (i = 0; i < LON_LEN; i++)
	 lon[i] = i * 5.;

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define lat, lon, level, and timestep dimensions, with
       * associated coordinate variables for lat and lon only. Time is
       * an unlimited dimension. */
      if (nc_def_dim(ncid, LAT_NAME, LAT_LEN, &lat_dimid)) ERR;
      if (lat_dimid != LAT_DIMID) ERR;
      dimids[0] = lat_dimid;
      if (nc_def_var(ncid, LAT_NAME, NC_FLOAT, 1, dimids, &lat_varid)) ERR;
      if (lat_varid != LAT_VARID) ERR;
      if (nc_def_dim(ncid, LON_NAME, LON_LEN, &lon_dimid)) ERR;
      if (lon_dimid != LON_DIMID) ERR;
      dimids[0] = lon_dimid;
      if (nc_def_var(ncid, LON_NAME, NC_FLOAT, 1, dimids, &lon_varid)) ERR;
      if (lon_varid != LON_VARID) ERR;
      if (nc_def_dim(ncid, LEVEL_NAME, LEVEL_LEN, &level_dimid)) ERR;
      if (level_dimid != LEVEL_DIMID) ERR;
      if (nc_def_dim(ncid, TIME_NAME, NC_UNLIMITED, &time_dimid)) ERR;
      if (time_dimid != TIME_DIMID) ERR;

      /* Define a 4D NC_DOUBLE variable called pressure. */
      dimids[0] = lat_dimid;
      dimids[1] = lon_dimid;
      dimids[2] = level_dimid;
      dimids[3] = time_dimid;
      if (nc_def_var(ncid, PRES_NAME, NC_DOUBLE, 4, dimids, &pres_varid)) ERR;
      if (pres_varid != PRES_VARID) ERR;

      /* Define a 2D variable for surface elevation. Use NC_INT64
       * because our units for this is Angstroms from Earth's
       * Center. */
      if (nc_def_var(ncid, ELEV_NAME, NC_INT64, 2, dimids, &elev_varid)) ERR;
      if (elev_varid != ELEV_VARID) ERR;
      
      /* Define a 3D NC_USHORT variable to store the number of Harry
       * Potter books in this grid square at this time (ignore HP
       * books in airplanes, dirigibles, hot air balloons, space
       * capsules, hang-gliders, parachutes, and flying on brooms). */
      dimids[2] = time_dimid;
      if (nc_def_var(ncid, HP_NAME, NC_USHORT, 3, dimids, &hp_varid)) ERR;
      if (hp_varid != HP_VARID) ERR;

      /* Did all our stuff make it into the internal metadata model
       * intact? */
      /* Check our dimensions. */
      if (nc_inq_dim(ncid, LAT_DIMID, name_in, &len_in)) ERR;
      if (len_in != LAT_LEN || strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dim(ncid, LON_DIMID, name_in, &len_in)) ERR;
      if (len_in != LON_LEN || strcmp(name_in, LON_NAME)) ERR;
      if (nc_inq_dim(ncid, LEVEL_DIMID, name_in, &len_in)) ERR;
      if (len_in != LEVEL_LEN || strcmp(name_in, LEVEL_NAME)) ERR;
      if (nc_inq_dim(ncid, TIME_DIMID, name_in, &len_in)) ERR;
      if (len_in != 0 || strcmp(name_in, TIME_NAME)) ERR;

      /* Check our coordinate variables. */
      if (nc_inq_var(ncid, LAT_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LAT_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != LAT_DIMID || natts_in != 0) ERR;
      if (nc_inq_var(ncid, LON_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, LON_NAME) || xtype_in != NC_FLOAT || ndims_in != 1 ||
	  dimids_in[0] != LON_DIMID || natts_in != 0) ERR;

      /* Check our data variables. */
      if (nc_inq_var(ncid, PRES_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, PRES_NAME) || xtype_in != NC_DOUBLE || ndims_in != 4 ||
	  dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID ||
	  dimids_in[2] != LEVEL_DIMID || dimids_in[3] != TIME_DIMID ||
	  natts_in != 0) ERR;
      if (nc_inq_var(ncid, ELEV_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, ELEV_NAME) || xtype_in != NC_INT64 || ndims_in != 2 ||
	  dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID ||
	  natts_in != 0) ERR;
      if (nc_inq_var(ncid, HP_VARID, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (strcmp(name_in, HP_NAME) || xtype_in != NC_USHORT || ndims_in != 3 ||
	  dimids_in[0] != LAT_DIMID || dimids_in[1] != LON_DIMID ||
	  dimids_in[2] != TIME_DIMID || natts_in != 0) ERR;
      
      /* Write our latitude and longitude values. This writes all
       * metadata to disk too. */
      if (nc_put_var_float(ncid, lat_varid, lat)) ERR;
      if (nc_put_var_float(ncid, lon_varid, lon)) ERR;

      /* Write our 4D pressure, elevation, and hp data. But this
       * should do nothing for pressure and hp, because these are
       * record vars, and nc_put_var_* doesn't do anything to record
       * vars, because it doesn't know how big the var is supposed to
       * be. */
      if (nc_put_var_double(ncid, pres_varid, (double *)pres)) ERR;
      if (nc_put_var_ulonglong(ncid, elev_varid, (unsigned long long *)elev)) ERR;
      if (nc_put_var_ushort(ncid, hp_varid, (unsigned short *)hp)) ERR;

      /* Check our latitude and longitude values. */
      if (nc_get_var(ncid, lat_varid, lat_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 if (lat[i] != lat_in[i]) ERR;
      if (nc_get_var_float(ncid, lon_varid, lon_in)) ERR;
      for (i = 0; i < LON_LEN; i++)
	 if (lon[i] != lon_in[i]) ERR;

      /* Make sure our pressure and hp variables are still
       * empty. get_var calls will return no error, but fetch no
       * data. */
      if (nc_inq_var(ncid, pres_varid, name_in, &xtype_in, &ndims_in,
		     dimids_in, &natts_in)) ERR;
      if (nc_inq_dim(ncid, dimids_in[3], NULL, &len_in)) ERR;
      if (len_in != 0) ERR;
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in) !=
	  NC_EINVALCOORDS) ERR;
      if (nc_inq_var(ncid, hp_varid, NULL, NULL, &ndims_in,
		     dimids_in, NULL)) ERR;
      if (nc_inq_dim(ncid, dimids_in[2], NULL, &len_in)) ERR;
      if (len_in != 0) ERR;
      if (nc_get_var_ushort(ncid, hp_varid, (unsigned short *)hp_in) !=
	  NC_EINVALCOORDS) ERR;

      /* Now use nc_put_vara to really write pressure and hp
       * data. Write TIME_LEN (4) records of each. */
      start[0] = start[1] = start[2] = start[3] = 0;
      count[0] = LAT_LEN;
      count[1] = LON_LEN;
      count[2] = LEVEL_LEN;
      count[3] = TIME_LEN;
      if (nc_put_vara(ncid, pres_varid, start, count,
		      (double *)pres)) ERR;
      count[2] = TIME_LEN;
      if (nc_put_vara(ncid, hp_varid, start, count,
		      (double *)hp)) ERR;

      /* Check our pressure values. */
      if (nc_get_var_double(ncid, pres_varid, (double *)pres_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (k = 0; k < LEVEL_LEN; k++)
	       for (l = 0; l <TIME_LEN; l++)
		  if (pres[i][j][k][l] != pres_in[i][j][k][l]) ERR;

      /* Check our elevation values. */
      if (nc_get_var_ulonglong(ncid, elev_varid, (unsigned long long *)elev_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    if (elev[i][j] != elev_in[i][j]) ERR;

      /* Check our hp values. */
      if (nc_get_var_ushort(ncid, hp_varid, (unsigned short *)hp_in)) ERR;
      for (i = 0; i < LAT_LEN; i++)
	 for (j = 0; j < LON_LEN; j++)
	    for (l = 0; l <TIME_LEN; l++)
	       if (hp[i][j][l] != hp_in[i][j][l]) ERR;

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

      /* Reopen the file and check it out again. At the moment, we
       * can't count on the varids and dimids being the same. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 4 || nvars != 5 || natts != 0) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Checking file with dims and only some coordinate vars...");
#define NDIMS_EX 4
#define NLAT 6
#define NLON 12
#define LAT_NAME_EX "latitude"
#define LON_NAME_EX "longitude"
#define NREC 2
#define REC_NAME "time"
#define LVL_NAME "level"
#define NLVL 2

/* Names of things. */
#define PRES_NAME "pressure"
#define TEMP_NAME "temperature"
#define UNITS "units"
#define DEGREES_EAST "degrees_east"
#define DEGREES_NORTH "degrees_north"

/* There are 4 vars, two for data, two for coordinate data. */
#define NVARS_EX 4

/* These are used to construct some example data. */
#define SAMPLE_PRESSURE 900
#define SAMPLE_TEMP 9.0
#define START_LAT 25.0
#define START_LON -125.0

/* For the units attributes. */
#define UNITS "units"
#define PRES_UNITS "hPa"
#define TEMP_UNITS "celsius"
#define LAT_UNITS "degrees_north"
#define LON_UNITS "degrees_east"
#define MAX_ATT_LEN 80
   {
      /* IDs for the netCDF file, dimensions, and variables. */
      int ncid, lon_dimid, lat_dimid;
      int lon_varid;
      int ndims_in;
      int dimid[NDIMS_EX];
      char dim_name_in[NDIMS_EX][NC_MAX_NAME];
      int i;

      /* Create the file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;

      /* Define the dimensions. */
      if (nc_def_dim(ncid, LAT_NAME_EX, NLAT, &lat_dimid)) ERR;
      if (nc_def_dim(ncid, LON_NAME_EX, NLON, &lon_dimid)) ERR;

      /* Define a coordinate var. */
      if (nc_def_var(ncid, LON_NAME_EX, NC_FLOAT, 1, &lon_dimid,
			       &lon_varid)) ERR;

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

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

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

      /* Close the file. */
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing file with just one very long dimension...");
   {
#define VERY_LONG_LEN (size_t)4500000000LL
      int ncid, dimid;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int varid_in;

      if (SIZEOF_SIZE_T == 8)
      {
	 /* Create a file with one dim and nothing else. */
	 if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
	 if (nc_def_dim(ncid, LAT_NAME, VERY_LONG_LEN, &dimid)) ERR;

	 /* Check it out. */
	 if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT) || 
	     strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
	 if (ndims_in != 1) ERR;
	 if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT)) ERR;
	 if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
	 if (ndims_in != 0) ERR;
	 if (nc_close(ncid)) ERR;

	 /* Reopen and check it out again. */
	 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	 /* Check it out. */
	 if (nc_inq_dim(ncid, dimid, name_in, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT) || 
	     strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
	 if (ndims_in != 1) ERR;
	 if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_dimname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, LAT_NAME)) ERR;
	 if (nc_inq_dimlen(ncid, 0, &len_in)) ERR;
	 if (len_in != ((SIZEOF_SIZE_T == 8) ? VERY_LONG_LEN : NC_MAX_UINT)) ERR;
	 if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
	 if (ndims_in != 0) ERR;
	 if (nc_close(ncid)) ERR;
      }
   }
   SUMMARIZE_ERR;
   printf("*** Testing reference file with just one very long dimension...");
   {
#define REF_FILE_NAME "ref_tst_dims.nc"
      int ncid, dimid = 0;
      int ndims_in, dimids_in[MAX_DIMS];
      size_t len_in;
      char name_in[NC_MAX_NAME + 1];
      int varid_in;
      char file_in[NC_MAX_NAME + 1];
      int ret;

      strcpy(file_in, "");
      if (getenv("srcdir"))
      {
	 strcat(file_in, getenv("srcdir"));
	 strcat(file_in, "/");
      } 
      strcat(file_in, REF_FILE_NAME);

      /* Reopen and check it out again. */
      if (nc_open(file_in, NC_NOWRITE, &ncid)) ERR;

      /* Check it out. */
      ret = nc_inq_dim(ncid, dimid, name_in, &len_in);
      if ((SIZEOF_SIZE_T >= 8 && ret) ||
	  (SIZEOF_SIZE_T < 8 && ret != NC_EDIMSIZE)) ERR;
      if (SIZEOF_SIZE_T < 8)
      {
	 if (len_in != NC_MAX_UINT) ERR;
      }
      else
      {
	 if (len_in != VERY_LONG_LEN) ERR;
      }
      if (strcmp(name_in, LAT_NAME)) ERR;
      if (nc_inq_dimids(ncid, &ndims_in, dimids_in, 0)) ERR;
      if (ndims_in != 1) ERR;
      if (nc_inq_dimid(ncid, LAT_NAME, &varid_in)) ERR;
      if (varid_in != 0) ERR;
      if (nc_inq_unlimdims(ncid, &ndims_in, dimids_in)) ERR;
      if (ndims_in != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
示例#24
0
int
main(int argc, char **argv)
{
#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif

   printf("\n*** Testing netcdf-4 string type.\n");
   printf("*** testing string variable...");
   {
      int var_dimids[NDIMS];
      int ndims, nvars, natts, unlimdimid;
      nc_type var_type;
      char var_name[NC_MAX_NAME + 1];
      int var_natts, var_ndims;
      int ncid, varid, i, dimids[NDIMS];
      char *data_in[DIM_LEN];
      char *data[DIM_LEN] = {"Let but your honour know",
			     "Whom I believe to be most strait in virtue", 
			     "That, in the working of your own affections", 
			     "Had time cohered with place or place with wishing", 
			     "Or that the resolute acting of your blood",
			     "Could have attain'd the effect of your own purpose",
			     "Whether you had not sometime in your life",
			     "Err'd in this point which now you censure him", 
			     "And pull'd the law upon you."};
   
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, dimids)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_STRING, NDIMS, dimids, &varid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_var(ncid, varid, var_name, &var_type, &var_ndims,
		     var_dimids, &var_natts)) ERR;
      if (var_type != NC_STRING || strcmp(var_name, VAR_NAME) || var_ndims != NDIMS ||
	  var_dimids[0] != dimids[0]) ERR;
      if (nc_put_var(ncid, varid, data)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_var(ncid, varid, var_name, &var_type, &var_ndims,
		     var_dimids, &var_natts)) ERR;
      if (var_type != NC_STRING || strcmp(var_name, VAR_NAME) || var_ndims != NDIMS ||
	  var_dimids[0] != dimids[0]) ERR;
      if (nc_get_var(ncid, varid, data_in)) ERR;
      for (i=0; i<DIM_LEN; i++)
	 if (strcmp(data_in[i], data[i])) ERR;
      for (i = 0; i < DIM_LEN; i++)
	 free(data_in[i]);
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing string attribute...");
   {
      
      size_t att_len;
      int ndims, nvars, natts, unlimdimid;
      nc_type att_type;
      int ncid, i;
      char *data_in[DIM_LEN];
      char *data[DIM_LEN] = {"Let but your honour know",
			     "Whom I believe to be most strait in virtue", 
			     "That, in the working of your own affections", 
			     "Had time cohered with place or place with wishing", 
			     "Or that the resolute acting of your blood",
			     "Could have attain'd the effect of your own purpose",
			     "Whether you had not sometime in your life",
			     "Err'd in this point which now you censure him", 
			     "And pull'd the law upon you."};
   

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, NC_STRING, DIM_LEN, data)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR;
      if (att_type != NC_STRING || att_len != DIM_LEN) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR;
      if (att_type != NC_STRING || att_len != DIM_LEN) ERR;
      if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR; 
      for (i = 0; i < att_len; i++)
	 if (strcmp(data_in[i], data[i])) ERR;
      if (nc_free_string(att_len, (char **)data_in)) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing string var functions...");

   {
#define MOBY_LEN 16
      int ncid, varid, i, dimids[NDIMS];
      char *data[] = {"Perhaps a very little thought will now enable you to account for ",
		      "those repeated whaling disasters--some few of which are casually ",
		      "chronicled--of this man or that man being taken out of the boat by ",
		      "the line, and lost.",
		      "For, when the line is darting out, to be seated then in the boat, ",
		      "is like being seated in the midst of the manifold whizzings of a ",
		      "steam-engine in full play, when every flying beam, and shaft, and wheel, ",
		      "is grazing you.",
		      "It is worse; for you cannot sit motionless in the heart of these perils, ",
		      "because the boat is rocking like a cradle, and you are pitched one way and ",
		      "the other, without the slightest warning;",
		      "But why say more?",
		      "All men live enveloped in whale-lines.",
		      "All are born with halters round their necks; but it is only when caught ",
		      "in the swift, sudden turn of death, that mortals realize the silent, subtle, ",
		      "ever-present perils of life."};
      char *data_in[MOBY_LEN];

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, MOBY_LEN, dimids)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_STRING, NDIMS, dimids, &varid)) ERR;
      if (nc_put_var_string(ncid, varid, (const char **)data)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Check it out. */
     if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
     if (nc_get_var_string(ncid, varid, data_in)) ERR;
     for (i=0; i<MOBY_LEN; i++)
	if (strcmp(data_in[i], data[i])) ERR;
     if (nc_free_string(MOBY_LEN, (char **)data_in)) ERR;
     if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

   printf("*** testing string attributes...");
   {
#define SOME_PRES 16
#define NDIMS_PRES 1
#define ATT2_NAME "presidents"

      int ncid, i;
      char *data[SOME_PRES] = {"Washington", "Adams", "Jefferson", "Madison",
			       "Monroe", "Adams", "Jackson", "VanBuren",
			       "Harrison", "Tyler", "Polk", "Tayor", 
			       "Fillmore", "Peirce", "Buchanan", "Lincoln"};
      char *data_in[SOME_PRES];

      /* Create a file with string attribute. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_string(ncid, NC_GLOBAL, ATT2_NAME, SOME_PRES, (const char **)data)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_get_att_string(ncid, NC_GLOBAL, ATT2_NAME, (char **)data_in)) ERR;
      for (i=0; i < SOME_PRES; i++)
	 if (strcmp(data_in[i], data[i])) ERR;
      
      /* Must free your data! */
      if (nc_free_string(SOME_PRES, (char **)data_in)) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing string fill value...");

   {
#define NUM_PRES 43
#define SOME_PRES 16
#define NDIMS_PRES 1

      int ncid, varid, i, dimids[NDIMS_PRES];
      size_t start[NDIMS_PRES], count[NDIMS_PRES];
      char *data[SOME_PRES] = {"Washington", "Adams", "Jefferson", "Madison",
			       "Monroe", "Adams", "Jackson", "VanBuren",
			       "Harrison", "Tyler", "Polk", "Tayor", 
			       "Fillmore", "Peirce", "Buchanan", "Lincoln"};
      char *data_in[NUM_PRES];

      /* Create a file with NUM_PRES strings, and write SOME_PRES of
       * them. */
      /*      nc_set_log_level(4);*/
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, NUM_PRES, dimids)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_STRING, NDIMS_PRES, dimids, &varid)) ERR;
      start[0] = 0;
      count[0] = SOME_PRES;
      if (nc_put_vara_string(ncid, varid, start, count, (const char **)data)) ERR;
      if (nc_close(ncid)) ERR;
      
      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_get_var_string(ncid, varid, data_in)) ERR;
      for (i=0; i < NUM_PRES; i++)
      {
	 if (i < SOME_PRES && strcmp(data_in[i], data[i])) ERR;
	 if (i >= SOME_PRES && strcmp(data_in[i], "")) ERR;
      }
      
      /* Must free your data! */
      if (nc_free_string(SOME_PRES, (char **)data_in)) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   FINAL_RESULTS;
#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   
}
示例#25
0
/* import variable given file id and variable name */
str
NCDFimportVariable(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	mvc *m = NULL;
	sql_schema *sch = NULL;
	sql_table *tfiles = NULL, *arr_table = NULL;
	sql_column *col;

	str msg = MAL_SUCCEED, vname = *(str*)getArgReference(stk, pci, 2);
	str fname = NULL, dimtype = NULL, aname_sys = NULL;
	int fid = *(int*)getArgReference(stk, pci, 1);
	int varid, vndims, vnatts, i, j, retval;
	char buf[BUFSIZ], *s= buf, aname[256], **dname;
	oid rid = oid_nil;
	int vdims[NC_MAX_VAR_DIMS];
	nc_type vtype;
	int ncid;   /* dataset id */
	size_t dlen;
	bat vbatid = 0, *dim_bids;
	BAT *vbat = NULL, *dimbat;

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

	sch = mvc_bind_schema(m, "sys");
	if ( !sch )
		return createException(MAL, "netcdf.importvar", "Cannot get schema sys\n");

	tfiles = mvc_bind_table(m, sch, "netcdf_files");
	if (tfiles == NULL)
		return createException(MAL, "netcdf.importvar", "Catalog table missing\n");

	/* get the name of the attached NetCDF file */
	col = mvc_bind_column(m, tfiles, "file_id");
	if (col == NULL)
		return createException(MAL, "netcdf.importvar", "Could not find \"netcdf_files\".\"file_id\"\n");
	rid = table_funcs.column_find_row(m->session->tr, col, (void *)&fid, NULL);
	if (rid == oid_nil)
		return createException(MAL, "netcdf.importvar", "File %d not in the NetCDF vault\n", fid);


	col = mvc_bind_column(m, tfiles, "location");
	fname = (str)table_funcs.column_find_value(m->session->tr, col, rid);

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

	/* Get info for variable vname from NetCDF file */
	if ( (retval = nc_inq_varid(ncid, vname, &varid)) )
		return createException(MAL, "netcdf.importvar",
			   "Cannot read variable %s: %s",
			   vname, nc_strerror(retval));
	if ( (retval = nc_inq_var(ncid, varid, vname, &vtype, &vndims, vdims, &vnatts)))
		return createException(MAL, "netcdf.importvar",
				"Cannot read variable %d : %s",
				varid, nc_strerror(retval));

	/* compose 'create table' statement in the buffer */
	dname = (char **) GDKzalloc( sizeof(char *) * vndims);
	for (i = 0; i < vndims; i++)
		dname[i] = (char *) GDKzalloc(NC_MAX_NAME + 1);

	snprintf(aname, 256, "%s%d", vname, fid);

	j = snprintf(buf, BUFSIZ,"create table %s.%s( ", sch->base.name, aname);

	for (i = 0; i < vndims; i++){
		if ((retval = nc_inq_dim(ncid, vdims[i], dname[i], &dlen)))
			return createException(MAL, "netcdf.importvar",
								   "Cannot read dimension %d : %s",
								   vdims[i], nc_strerror(retval));

		if ( dlen <= (int) GDK_bte_max )
			dimtype = "TINYINT";
		else if ( dlen <= (int) GDK_sht_max )
			dimtype = "SMALLINT";
		else
			dimtype = "INT";

		(void)dlen;
		j += snprintf(buf + j, BUFSIZ - j, "%s %s, ", dname[i], dimtype);
	}

	j += snprintf(buf + j, BUFSIZ - j, "value %s);", NCDF2SQL(vtype));

/* execute 'create table ' */
	msg = SQLstatementIntern(cntxt, &s, "netcdf.importvar", TRUE, FALSE, NULL);
	if (msg != MAL_SUCCEED)
		return msg;

/* load variable data */
	dim_bids = (bat *)GDKmalloc(sizeof(bat) * vndims);

	msg = NCDFloadVar(&dim_bids, &vbatid, ncid, varid, vtype, vndims, vdims);
	if ( msg != MAL_SUCCEED )
		return msg;

	/* associate columns in the table with loaded variable data */
	aname_sys = toLower(aname);
	arr_table = mvc_bind_table(m, sch, aname_sys);
	if (arr_table == NULL)
		return createException(MAL, "netcdf.importvar", "netcdf table %s missing\n", aname_sys);

	col = mvc_bind_column(m, arr_table, "value");
	if (col == NULL)
		return createException(MAL, "netcdf.importvar", "Cannot find column %s.value\n", aname_sys);

	vbat = BATdescriptor(vbatid);
	store_funcs.append_col(m->session->tr, col, vbat, TYPE_bat);
	BBPunfix(vbatid);
	BBPdecref(vbatid, 1);
	vbat = NULL;

	/* associate dimension bats  */
	for (i = 0; i < vndims; i++){
		col = mvc_bind_column(m, arr_table, dname[i]);
		if (col == NULL)
			return createException(MAL, "netcdf.importvar", "Cannot find column %s.%s\n", aname_sys, dname[i]);

		dimbat = BATdescriptor(dim_bids[i]);
		store_funcs.append_col(m->session->tr, col, dimbat, TYPE_bat);
		BBPunfix(dim_bids[i]); /* phys. ref from BATdescriptor */
		BBPdecref(dim_bids[i], 1); /* log. ref. from loadVar */
		dimbat = NULL;
	}

	for (i = 0; i < vndims; i++)
        	GDKfree(dname[i]);
	GDKfree(dname);
	GDKfree(dim_bids);

	nc_close(ncid);

	return msg;
}
示例#26
0
int
main(int argc, char **argv)
{
   int ncid, dimid, varid;
   int dimids[NDIMS];

   /* unnormalized UTF-8 encoding for Unicode 8-character "Hello" in Greek: */
   unsigned char uname_utf8[] = {
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x80,		/* COMBINING GRAVE ACCENT */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x81,		/* COMBINING ACUTE ACCENT */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x82,		/* COMBINING CIRCUMFLEX ACCENT */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x83,		/* COMBINING TILDE */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x88,		/* COMBINING DIAERESIS */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x8A,		/* COMBINING RING ABOVE */
       0x43,			/* LATIN CAPITAL LETTER C */
       0xCC, 0xA7,		/* COMBINING CEDILLA */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x80,		/* COMBINING GRAVE ACCENT */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x81,		/* COMBINING ACUTE ACCENT */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x82,		/* COMBINING CIRCUMFLEX ACCENT */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x88,		/* COMBINING DIAERESIS */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x80,		/* COMBINING GRAVE ACCENT */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x81,		/* COMBINING ACUTE ACCENT */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x82,		/* COMBINING CIRCUMFLEX ACCENT */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x88,		/* COMBINING DIAERESIS */
       0x4E,			/* LATIN CAPITAL LETTER N */
       0xCC, 0x83,		/* COMBINING TILDE */
       0x00
   };

   /* NFC normalized UTF-8 encoding for same Unicode string: */
   unsigned char nname_utf8[] = {
       0xC3, 0x80,	        /* LATIN CAPITAL LETTER A WITH GRAVE */
       0xC3, 0x81,	        /* LATIN CAPITAL LETTER A WITH ACUTE */
       0xC3, 0x82,	        /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
       0xC3, 0x83,	        /* LATIN CAPITAL LETTER A WITH TILDE */
       0xC3, 0x84,		/* LATIN CAPITAL LETTER A WITH DIAERESIS */
       0xC3, 0x85,		/* LATIN CAPITAL LETTER A WITH RING ABOVE */
       0xC3, 0x87,		/* LATIN CAPITAL LETTER C WITH CEDILLA */
       0xC3, 0x88,		/* LATIN CAPITAL LETTER E WITH GRAVE */
       0xC3, 0x89,		/* LATIN CAPITAL LETTER E WITH ACUTE */
       0xC3, 0x8A,		/* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
       0xC3, 0x8B,		/* LATIN CAPITAL LETTER E WITH DIAERESIS */
       0xC3, 0x8C,		/* LATIN CAPITAL LETTER I WITH GRAVE */
       0xC3, 0x8D,		/* LATIN CAPITAL LETTER I WITH ACUTE */
       0xC3, 0x8E,		/* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
       0xC3, 0x8F,		/* LATIN CAPITAL LETTER I WITH DIAERESIS */
       0xC3, 0x91,	        /* LATIN CAPITAL LETTER N WITH TILDE */
       0x00
   };

/* Unnormalized name used for dimension, variable, and attribute value */
#define UNAME ((char *) uname_utf8)
#define UNAMELEN (sizeof uname_utf8)
/* Normalized name */
#define NNAME ((char *) nname_utf8)
#define NNAMELEN (sizeof nname_utf8)

   char name_in[UNAMELEN + 1], strings_in[UNAMELEN + 1];
   nc_type att_type;
   size_t att_len;
   int res;
   int dimid_in, varid_in, attnum_in;
   int attvals[] = {42};
#define ATTNUM ((sizeof attvals)/(sizeof attvals[0]))

   printf("\n*** testing UTF-8 normalization...");
   if((res = nc_create(FILE7_NAME, NC_CLOBBER, &ncid)))
       ERR;

   /* Define dimension with unnormalized Unicode UTF-8 encoded name */
   if ((res = nc_def_dim(ncid, UNAME, NX, &dimid)))
       ERR;
   dimids[0] = dimid;

   /* Define variable with same name */
   if ((res = nc_def_var(ncid, UNAME, NC_CHAR, NDIMS, dimids, &varid)))
       ERR;

   /* Create string attribute with same value */
   if ((res = nc_put_att_text(ncid, varid, UNITS, UNAMELEN, UNAME)))
       ERR;

   /* Create int attribute with same name */
   if ((res = nc_put_att_int(ncid, varid, UNAME, NC_INT, ATTNUM, attvals)))
       ERR;

   /* Try to create dimension and variable with NFC-normalized
    * version of same name.  These should fail, as unnormalized name
    * should have been normalized in library, so these are attempts to
    * create duplicate netCDF objects. */
   if ((res = nc_def_dim(ncid, NNAME, NX, &dimid)) 
       != NC_ENAMEINUSE) ERR;
   if ((res = nc_def_var(ncid, NNAME, NC_CHAR, NDIMS, dimids, &varid)) 
       != NC_ENAMEINUSE) ERR;
   if ((res = nc_enddef(ncid)))
       ERR;

   /* Write string data, UTF-8 encoded, to the file */
   if ((res = nc_put_var_text(ncid, varid, UNAME)))
       ERR;
   if ((res = nc_close(ncid)))
       ERR;

   /* Check it out. */
   if ((res = nc_open(FILE7_NAME, NC_NOWRITE, &ncid)))
       ERR;
   if ((res = nc_inq_varid(ncid, UNAME, &varid)))
       ERR;
   if ((res = nc_inq_varname(ncid, varid, name_in)))
       ERR;
   if ((res = strncmp(NNAME, name_in, NNAMELEN)))
       ERR;
   if ((res = nc_inq_varid(ncid, NNAME, &varid_in)) || varid != varid_in)
       ERR;
   if ((res = nc_inq_dimid(ncid, UNAME, &dimid_in)) || dimid != dimid_in)
       ERR;
   if ((res = nc_inq_dimid(ncid, NNAME, &dimid_in)) || dimid != dimid_in)
       ERR;
   if ((res = nc_inq_att(ncid, varid, UNITS, &att_type, &att_len)))
       ERR;
   if ((res = att_type != NC_CHAR || att_len != UNAMELEN))
       ERR;
   if ((res = nc_get_att_text(ncid, varid, UNITS, strings_in)))
       ERR;
   strings_in[UNAMELEN] = '\0';
   if ((res = strncmp(UNAME, strings_in, UNAMELEN)))
       ERR;
   if ((res = nc_inq_attid(ncid, varid, UNAME, &attnum_in)) || ATTNUM != attnum_in)
       ERR;
   if ((res = nc_inq_attid(ncid, varid, NNAME, &attnum_in)) || ATTNUM != attnum_in)
       ERR;
   if ((res = nc_close(ncid)))
       ERR;

   SUMMARIZE_ERR;
   FINAL_RESULTS;
   return 0;
}
示例#27
0
int main (int argc, char** argv)
{
	//define some generic loop indices
	int i, j;
	
	//make sure a filename was provided
	if (argc < 2)
	{
		puts("NetCDF filename argument required");
		return -1;
	}
	
	//loop through every input file
	int argIndex;
	for (argIndex = 1; argIndex < argc; argIndex++)
	{
		char* filename = argv[argIndex];
		size_t filenameLength = strlen(filename);
		
		//allocate space for the flt.dat filename, plus some room for the longer extension, etc
		char *fltDatFilename = malloc((filenameLength + 7)*sizeof(char));
		strcpy(fltDatFilename, filename);
		char *periodLocation = strrchr(fltDatFilename, '.');
		*periodLocation = '\0';
		strcat(fltDatFilename, "flt.dat");
		
		//open the NetCDF file/dataset
		int datasetID;
		int ncResult;
		ncResult = nc_open(filename, NC_NOWRITE, &datasetID);
		if (ncResult != NC_NOERR) HandleNCError("nc_open", ncResult);
		
		printf("opened NetCDF file: %s", filename);
		printf("output flt.dat filename: %s\n", fltDatFilename);
		
		//get basic information about the NetCDF file
		int numDims, numVars, numGlobalAtts, unlimitedDimID;
		ncResult = nc_inq(datasetID, &numDims, &numVars, &numGlobalAtts, &unlimitedDimID);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq", ncResult);
		int formatVersion;
		ncResult = nc_inq_format(datasetID, &formatVersion);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_format", ncResult);
		
		if (numDims != 1)
		{
			puts("error: only 1-dimensional NetCDF files are supported for now");
			return -1;
		}
		
		//show some of the NetCDF file information on the console
		printf("# dims: %d\n# vars: %d\n# global atts: %d\n", numDims, numVars, numGlobalAtts);
		if (unlimitedDimID != -1) puts("contains unlimited dimension");
		switch (formatVersion)
		{
			case NC_FORMAT_CLASSIC:
				puts("classic file format");
				break;
			case NC_FORMAT_64BIT:
				puts("64-bit file format");
				break;
			case NC_FORMAT_NETCDF4:
				puts("netcdf4 file format");
				break;
			case NC_FORMAT_NETCDF4_CLASSIC:
				puts("netcdf4 classic format");
				break;
			default:
				puts("unrecognized file format");
				return -1;
				break;
		}
		
		//int dimID;
		//for (dimID = 0; dimID < numDims; dimID++)
		//{
		//get dimension names and lengths
		char dimName[NC_MAX_NAME+1];
		size_t dimLength;
		ncResult = nc_inq_dim(datasetID, 0, dimName, &dimLength);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_dim", ncResult);
		
		printf("dimension: %s length: %d\n", dimName, dimLength);
		//}
		
		//open/create the flt.dat file for outputting data
		//todo: better file name
		FILE *fltFile = fopen(fltDatFilename, "w");
		
		//get the current GMT date/time
		time_t currentTime;
		time(&currentTime);
		struct tm *currentTimeStruct = gmtime(&currentTime);
		
		printf("current gmt time: %d/%d/%d %d:%d:%d\n", currentTimeStruct->tm_year+1900, currentTimeStruct->tm_mon+1, currentTimeStruct->tm_mday, 
			currentTimeStruct->tm_hour, currentTimeStruct->tm_min, currentTimeStruct->tm_sec);
		
		//get the launch date/time attribute
		char launchTimeStr[100];
		ncResult = nc_get_att_text(datasetID, NC_GLOBAL, "g.Ascent.StartTime", launchTimeStr);
		if (ncResult != NC_NOERR) HandleNCError("nc_get_att_text", ncResult);
		//split the launch date/time string into token strings
		char yearStr[10];
		substr(yearStr, launchTimeStr, 0, 4);
		char monStr[10];
		substr(monStr, launchTimeStr, 5, 2);
		char dayStr[10];
		substr(dayStr, launchTimeStr, 8, 2);
		char hourStr[10];
		substr(hourStr, launchTimeStr, 11, 2);
		char minStr[10];
		substr(minStr, launchTimeStr, 14, 2);
		char secStr[10];
		substr(secStr, launchTimeStr, 17, 2);
		//convert the launch date/time into a tm structure
		struct tm launchTimeStruct;
		int launchYear = atoi(yearStr);
		int launchMonth = atoi(monStr);
		int launchDay = atoi(dayStr);
		int launchHour = atoi(hourStr);
		int launchMinute = atoi(minStr);
		int launchSecond = atoi(secStr);
		
		printf("launch gmt time: %d/%d/%d %d:%d:%d\n", launchYear, launchMonth, launchDay, launchHour, launchMinute, launchSecond);
		
		//output the flt.dat header
		fprintf(fltFile, "Extended NOAA/GMD preliminary data %02d-%02d-%04d %02d:%02d:%02d [GMT], nc2fltdat version %.3f\r\n", 
			currentTimeStruct->tm_mday, currentTimeStruct->tm_mon+1, currentTimeStruct->tm_year+1900, currentTimeStruct->tm_hour, currentTimeStruct->tm_min, currentTimeStruct->tm_sec, VERSION);
		
		fprintf(fltFile, "Software written by Allen Jordan, NOAA\r\n");
		fprintf(fltFile, "               Header lines = 16\r\n");
		fprintf(fltFile, "               Data columns = 12\r\n");
		fprintf(fltFile, "                 Date [GMT] = %02d-%02d-%04d\r\n", launchDay, launchMonth, launchYear);
		fprintf(fltFile, "                 Time [GMT] = %02d:%02d:%02d\r\n", launchHour, launchMinute, launchSecond);
		fprintf(fltFile, "            Instrument type = Vaisala RS92\r\n");
		fprintf(fltFile, "\r\n\r\n");
		fprintf(fltFile, "    THE DATA CONTAINED IN THIS FILE ARE PRELIMINARY\r\n");
		fprintf(fltFile, "     AND SUBJECT TO REPROCESSING AND VERIFICATION\r\n");
		fprintf(fltFile, "\r\n\r\n\r\n");
		fprintf(fltFile, "      Time,     Press,       Alt,      Temp,        RH,     TFp V,   GPS lat,   GPS lon,   GPS alt,      Wind,  Wind Dir,        Fl\r\n");
		fprintf(fltFile, "     [min],     [hpa],      [km],   [deg C],       [%%],   [deg C],     [deg],     [deg],      [km],     [m/s],     [deg],        []\r\n");
		
		//storage for all variables in the NetCDF file
		//todo: watch out for segfaults, maybe use nc_get_vara_ to get pieces instead of whole variables
		VariableData **variableDataList = (VariableData **)malloc(numVars * sizeof(VariableData*));
		char **standardNameList = (char **)malloc(numVars * sizeof(char*));
		//char **longNameList = (char **)malloc(numVars * sizeof(char*));
		//char **unitStringList = (char **)malloc(numVars * sizeof(char*));
		
		//loop through all the variables
		int varID;
		for (varID=0; varID<numVars; varID++)
		{
			//get information about the variable
			char varName[NC_MAX_NAME+1];
			nc_type varType;
			int numVarDims;
			int varDimIDs[NC_MAX_VAR_DIMS];
			int numVarAtts;
			ncResult = nc_inq_var(datasetID, varID, varName, &varType, &numVarDims, varDimIDs, &numVarAtts);
			if (ncResult != NC_NOERR) HandleNCError("nc_inq_var", ncResult);
			
			//output variable info to console
			printf("variable: %s # dims: %d # atts: %d type: %d\n", varName, numVarDims, numVarAtts, (int)varType);
			
			//output variable name to the flt.dat file
			//fprintf(fltFile, "%s", varName);
			//if (varID != (numVars-1)) fprintf(fltFile, ", ");
			
			/*//see if there is an attribute for the variable standard name, and store it if there is
			int standardNameAttLen = 0;
			ncResult = nc_inq_attlen(datasetID, varID, "standard_name", &standardNameAttLen);
			if (ncResult == NC_NOERR)
			{
				//allocate enough space for the units string
				char *standardNameValueStr = (char *) malloc(standardNameAttLen + 1);
				ncResult = nc_get_att_text(datasetID, varID, "standard_name", standardNameValueStr);
				if (ncResult != NC_NOERR) HandleNCError("nc_get_att_text", ncResult);
				//make sure the string is null terminated (sometimes it won't be, apparently)
				standardNameValueStr[standardNameAttLen] = '\0';
				standardNameList[varID] = standardNameValueStr;
			}
			else
			{
				char *emptyHeapStr = malloc(1*sizeof(char));
				emptyHeapStr[0] = '\0';
				standardNameList[varID] = emptyHeapStr;
			}
			
			//see if there is an attribute for the variable long name, and store it if there is
			int longNameAttLen = 0;
			ncResult = nc_inq_attlen(datasetID, varID, "long_name", &longNameAttLen);
			if (ncResult == NC_NOERR)
			{
				//allocate enough space for the units string
				char *longNameValueStr = (char *) malloc(longNameAttLen + 1);
				ncResult = nc_get_att_text(datasetID, varID, "long_name", longNameValueStr);
				if (ncResult != NC_NOERR) HandleNCError("nc_get_att_text", ncResult);
				//make sure the string is null terminated (sometimes it won't be, apparently)
				longNameValueStr[longNameAttLen] = '\0';
				longNameList[varID] = longNameValueStr;
			}
			else
			{
				char *emptyHeapStr = malloc(1*sizeof(char));
				emptyHeapStr[0] = '\0';
				longNameList[varID] = emptyHeapStr;
			}
			
			//see if there is an attribute for the variable units description, and store it if there is
			int unitsAttLen = 0;
			ncResult = nc_inq_attlen(datasetID, varID, "units", &unitsAttLen);
			if (ncResult == NC_NOERR)
			{
				//allocate enough space for the units string
				char *unitsValueStr = (char *) malloc(unitsAttLen + 1);
				ncResult = nc_get_att_text(datasetID, varID, "units", unitsValueStr);
				if (ncResult != NC_NOERR) HandleNCError("nc_get_att_text", ncResult);
				//make sure the string is null terminated (sometimes it won't be, apparently)
				unitsValueStr[unitsAttLen] = '\0';
				unitStringList[varID] = unitsValueStr;
			}
			else
			{
				char *emptyHeapStr = malloc(1*sizeof(char));
				emptyHeapStr[0] = '\0';
				unitStringList[varID] = emptyHeapStr;
			}*/
			
			
			//make sure the variable only has 1 dimension
			if (numVarDims != 1) puts("warning: only 1-dimensional variables are supported for now... skipping");
			else
			{
				//storage for this variable's data structure
				VariableData *variableData = (VariableData *)malloc(sizeof(VariableData));
				variableData->type = varType;
				
				//depending on the type, allocate storage for this variable's raw data contained in the structure
				switch (varType)
				{
					case NC_BYTE:
					{
						variableData->data = malloc(dimLength * sizeof(unsigned char));
						ncResult = nc_get_var_uchar(datasetID, varID, (unsigned char*)variableData->data);
						if (ncResult != NC_NOERR) HandleNCError("nc_get_var", ncResult);
						break;
					}
					case NC_CHAR:
					{
						variableData->data = malloc(dimLength * sizeof(char));
						ncResult = nc_get_var_text(datasetID, varID, (char*)variableData->data);
						if (ncResult != NC_NOERR) HandleNCError("nc_get_var", ncResult);
						break;
					}
					case NC_SHORT:
					{
						variableData->data = malloc(dimLength * sizeof(short));
						ncResult = nc_get_var_short(datasetID, varID, (short*)variableData->data);
						if (ncResult != NC_NOERR) HandleNCError("nc_get_var", ncResult);
						break;
					}
					case NC_INT:
					{
						variableData->data = malloc(dimLength * sizeof(int));
						ncResult = nc_get_var_int(datasetID, varID, (int*)variableData->data);
						if (ncResult != NC_NOERR) HandleNCError("nc_get_var", ncResult);
						break;
					}
					case NC_FLOAT:
					{
						variableData->data = malloc(dimLength * sizeof(float));
						ncResult = nc_get_var_float(datasetID, varID, (float*)variableData->data);
						if (ncResult != NC_NOERR) HandleNCError("nc_get_var", ncResult);
						break;
					}
					case NC_DOUBLE:
					{
						variableData->data = malloc(dimLength * sizeof(double));
						ncResult = nc_get_var_double(datasetID, varID, (double*)variableData->data);
						if (ncResult != NC_NOERR) HandleNCError("nc_get_var", ncResult);
						break;
					}
					default:
					{
						puts("warning: invalid variable type");
						break;
					}
				}//end of type switch
				
				//store the variable data structure in the list of all variable data structures, to be used later when outputting
				variableDataList[varID] = variableData;
				
			}//end of num var dimensions check
		}//end of variable loop
		
		//output a newline after the variable names flt.dat header line
		//fprintf(fltFile, "\r\n");
		
		/*//output the variable standard names
		for (i=0; i<numVars; i++)
		{
			fprintf(fltFile, "%s", standardNameList[i]);
			if (i != (numVars-1)) fprintf(fltFile, ", ");
		}
		fprintf(fltFile, "\r\n");
		
		//output the variable long names
		for (i=0; i<numVars; i++)
		{
			fprintf(fltFile, "%s", longNameList[i]);
			if (i != (numVars-1)) fprintf(fltFile, ", ");
		}
		fprintf(fltFile, "\r\n");
		
		//output the variable units
		for (i=0; i<numVars; i++)
		{
			char *unitsName = unitStringList[i];
			if (unitsName[0] != '[')
				fprintf(fltFile, "[");
			
			fprintf(fltFile, "%s", unitsName);
			
			if (unitsName[strlen(unitsName)-1] != ']')
				fprintf(fltFile, "]");
			
			if (i != (numVars-1)) fprintf(fltFile, ", ");
		}
		fprintf(fltFile, "\r\n");*/
		
		
		
		
		
		
		
		int timeIndex;
		ncResult = nc_inq_varid(datasetID, "time", &timeIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (time)", ncResult);
		int pressureIndex;
		ncResult = nc_inq_varid(datasetID, "press", &pressureIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (press)", ncResult);
		int temperatureIndex;
		ncResult = nc_inq_varid(datasetID, "temp", &temperatureIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (temp)", ncResult);
		int vaisRHIndex;
		ncResult = nc_inq_varid(datasetID, "rh", &vaisRHIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (rh)", ncResult);
		int windDirIndex;
		ncResult = nc_inq_varid(datasetID, "wdir", &windDirIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (wdir)", ncResult);
		int windSpeedIndex;
		ncResult = nc_inq_varid(datasetID, "wspeed", &windSpeedIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (wspeed)", ncResult);
		int geopotAltIndex;
		ncResult = nc_inq_varid(datasetID, "geopot", &geopotAltIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (geopot)", ncResult);
		int lonIndex;
		ncResult = nc_inq_varid(datasetID, "lon", &lonIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (lon)", ncResult);
		int latIndex;
		ncResult = nc_inq_varid(datasetID, "lat", &latIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (lat)", ncResult);
		int gpsAltIndex;
		ncResult = nc_inq_varid(datasetID, "alt", &gpsAltIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (alt)", ncResult);
		int vaisFPIndex;
		ncResult = nc_inq_varid(datasetID, "FP", &vaisFPIndex);
		if (ncResult != NC_NOERR) HandleNCError("nc_inq_varid (FP)", ncResult);
		
		for (i = 0; i < dimLength; i++)
		{
			if (variableDataList[timeIndex]->type != NC_FLOAT) 
			{
				printf("Invalid NetCDF type for outputting to flt.dat: %d\r\n", variableDataList[timeIndex]->type);
			}
			fprintf(fltFile, "%10.5f,%10.2f,%10.4f,%10.2f,%10.2f,%10.2f,%10.5f,%10.5f,%10.4f,%10.2f,%10.2f,%10d\r\n", 
				((float*)variableDataList[timeIndex]->data)[i] / 60.0, ((float*)variableDataList[pressureIndex]->data)[i], ((float*)variableDataList[geopotAltIndex]->data)[i] / 1000,
				((float*)variableDataList[temperatureIndex]->data)[i] - 273.15, ((float*)variableDataList[vaisRHIndex]->data)[i]*100, ((float*)variableDataList[vaisFPIndex]->data)[i] - 273.15,
				((float*)variableDataList[latIndex]->data)[i], ((float*)variableDataList[lonIndex]->data)[i], ((float*)variableDataList[gpsAltIndex]->data)[i]/1000, ((float*)variableDataList[windSpeedIndex]->data)[i], ((float*)variableDataList[windDirIndex]->data)[i], 1);
		}
		
		/*
		//output variable data to the flt.dat file
		for (i=0; i<dimLength; i++)
		{
			for (j=0; j<numVars; j++)
			{
				VariableData *variableData = variableDataList[j];
				//write data in the correct format for the variable's type
				switch (variableData->type)
				{
					case NC_BYTE:
					{
						unsigned char *byteList = (unsigned char *)variableData->data;
						fprintf(fltFile, "%u", byteList[i]);
						break;
					}
					case NC_CHAR:
					{
						char *byteList = (char *)variableData->data;
						fprintf(fltFile, "%c", byteList[i]);
						break;
					}
					case NC_SHORT:
					{
						short *byteList = (short *)variableData->data;
						fprintf(fltFile, "%d", byteList[i]);
						break;
					}
					case NC_INT:
					{
						int *byteList = (int *)variableData->data;
						fprintf(fltFile, "%d", byteList[i]);
						break;
					}
					case NC_FLOAT:
					{
						float *byteList = (float *)variableData->data;
						fprintf(fltFile, "%f", byteList[i]);
						break;
					}
					case NC_DOUBLE:
					{
						double *byteList = (double *)variableData->data;
						fprintf(fltFile, "%f", byteList[i]);
						break;
					}
					default:
						break;
				}
				
				if (j != (numVars-1)) fprintf(fltFile, ", ");
			}
			fprintf(fltFile, "\r\n");
		}*/
		
		//free up heap memory
		/*for (i=0; i<numVars; i++)
		{
			free(standardNameList[i]);
		}
		free(standardNameList);
		for (i=0; i<numVars; i++)
		{
			free(longNameList[i]);
		}
		free(longNameList);
		for (i=0; i<numVars; i++)
		{
			free(unitStringList[i]);
		}
		free(unitStringList);*/
		for (i=0; i<numVars; i++)
		{
			free(variableDataList[i]->data);
		}
		free(variableDataList);
		free(fltDatFilename);
		
		//close the flt.dat file
		fclose(fltFile);
		
		//close the NetCDF file
		ncResult = nc_close(datasetID);
		if (ncResult != NC_NOERR) HandleNCError("nc_close", ncResult);
		
		printf("\r\n");
		
	}//end of input file for loop
	
	/*DIR *dp;
	struct dirent *ep;
	dp = opendir ("./");

	if (dp != NULL)
	{
		while (ep = readdir (dp))
			puts (ep->d_name);
		
		(void) closedir (dp);
	}
	else
	perror ("Couldn't open the directory");*/

	return 0;
}
示例#28
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 file functions.\n");
   {
      char str[NC_MAX_NAME+1];

      /* Actually we never make any promises about the length of the
       * version string, but it is always smaller than NC_MAX_NAME. */
      if (strlen(nc_inq_libvers()) > NC_MAX_NAME) ERR;
      strcpy(str, nc_inq_libvers());
      printf("*** testing version %s...", str);
   }
   SUMMARIZE_ERR;
   printf("*** testing with bad inputs...");
   {
      int ncid;

      /* Create an empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* These will all fail due to incorrect mode flag combinations. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_NETCDF4, &ncid) != NC_EINVAL) ERR;
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CDF5, &ncid) != NC_EINVAL) ERR;
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CDF5, &ncid) != NC_EINVAL) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing simple opens and creates...");
   {
      int ncid, ncid2, ncid3, varid, dimids[2];
      int ndims, nvars, natts, unlimdimid;
      int dimids_var[1], var_type;
      size_t dim_len;
      char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
      unsigned char uchar_out[DIM1_LEN] = {0, 128, 255};

      /* Open and close empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it again. */
      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, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Then define a new variable. Since it's
       * netcdf-4, nc_enddef isn't required - it's called
       * automatically. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open three copies of the same file. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_open(FILE_NAME, NC_WRITE, &ncid2)) ERR;
      if (nc_open(FILE_NAME, NC_WRITE, &ncid3)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq(ncid2, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq(ncid3, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 3 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;
      if (nc_close(ncid2)) ERR;
      if (nc_close(ncid3)) ERR;

      /* Open and close empty file. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a file with one dimension and nothing else. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 0 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a simple file, and write some data to it. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_put_var_uchar(ncid, varid, uchar_out) != NC_ERANGE) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_BYTE ||
          dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate the file. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_BYTE, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_put_var_uchar(ncid, varid, uchar_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it, then make sure NOCLOBBER works. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_close(ncid)) ERR;
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_NOCLOBBER, &ncid) != NC_EEXIST) ERR;

      /* Recreate it again. */
      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, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Then define a new variable. Since it's
       * netcdf-4, nc_enddef isn't required - it's called
       * automatically. */
      if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_redef(ncid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_def_var(ncid, VAR3_NAME, NC_INT, 2, dimids, &varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Recreate it again with netcdf-3 rules turned on. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR1_NAME, NC_INT, 1, dimids, &varid)) ERR;
      if (nc_enddef(ncid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check the contents. Check that netcdf-3 rules are in effect. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
      if (nc_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid) != NC_ENOTINDEFINE) ERR;
      if (nc_close(ncid)) ERR;

      /* Check some other stuff about it. Closing and reopening the
       * file forces HDF5 to tell us if we forgot to free some HDF5
       * resource associated with the file. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 1 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
          dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing more complex opens and creates...");
   {
      int ncid, varid, dimids[2];
      int ndims, nvars, natts, unlimdimid;
      int dimids_var[2], var_type;
      size_t dim_len;
      char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
      float float_in, float_out = 99.99;
      int int_in, int_out = -9999;

      /* Create a file, this time with attributes. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &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_def_var(ncid, VAR2_NAME, NC_UINT, 2, dimids, &varid)) ERR;
      if (nc_put_att_float(ncid, NC_GLOBAL, ATT1_NAME, NC_FLOAT, 1, &float_out)) ERR;
      if (nc_put_att_int(ncid, NC_GLOBAL, ATT2_NAME, NC_INT, 1, &int_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen the file and check it. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 2 || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
      if (nc_close(ncid)) ERR;

      /* Reopen it and check each dim, var, and att. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
      if (dim_len != DIM1_LEN || strcmp(dim_name, DIM1_NAME)) ERR;
      if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
      if (dim_len != DIM2_LEN || strcmp(dim_name, DIM2_NAME)) ERR;
      if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 2 || strcmp(var_name, VAR1_NAME) || var_type != NC_INT ||
          dimids_var[0] != dimids[0] || natts != 0) ERR;
      if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
      if (ndims != 2 || strcmp(var_name, VAR2_NAME) || var_type != NC_UINT ||
          dimids_var[1] != dimids[1] || natts != 0) ERR;
      if (nc_get_att_float(ncid, NC_GLOBAL, ATT1_NAME, &float_in)) ERR;
      if (float_in != float_out) ERR;
      if (nc_get_att_int(ncid, NC_GLOBAL, ATT2_NAME, &int_in)) ERR;
      if (int_in != int_out) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

   printf("*** testing redef for netCDF classic...");
   test_redef(NC_FORMAT_CLASSIC);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF 64-bit offset...");
   test_redef(NC_FORMAT_64BIT_OFFSET);
   SUMMARIZE_ERR;

   printf("*** testing redef for netCDF-4 ...");
   test_redef(NC_FORMAT_NETCDF4);
   SUMMARIZE_ERR;
   printf("*** testing redef for netCDF-4, with strict netCDF-3 rules...");
   test_redef(NC_FORMAT_NETCDF4_CLASSIC);
   SUMMARIZE_ERR;

#ifdef ENABLE_CDF5
   printf("*** testing redef for CDF5...");
   test_redef(NC_FORMAT_CDF5);
   SUMMARIZE_ERR;
#endif /* ENABLE_CDF5 */

   printf("*** testing different formats...");
   {
      int ncid;
      int format;

      /* Create a netcdf-3 file. */
      if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_CLASSIC) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-3 64-bit offset file. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_64BIT_OFFSET) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-4 file. */
      if (nc_create(FILE_NAME, NC_NETCDF4|NC_CLOBBER, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_NETCDF4) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing CLASSIC_MODEL flag with classic formats...");
   {
      int ncid;
      int format;

      /* Create a netcdf-3 file. */
      if (nc_create(FILE_NAME, NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_CLASSIC) ERR;
      if (nc_close(ncid)) ERR;

      /* Create a netcdf-3 64-bit offset file. */
      if (nc_create(FILE_NAME, NC_64BIT_OFFSET|NC_CLOBBER|NC_CLASSIC_MODEL, &ncid)) ERR;
      if (nc_inq_format(ncid, &format)) ERR;
      if (format != NC_FORMAT_64BIT_OFFSET) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing multiple open files...");
   {
#define VAR_NAME "Captain_Kirk"
#define NDIMS 1
#define NUM_FILES 30
#define TEXT_LEN 15
#define D1_NAME "tl"
      int ncid[NUM_FILES], varid;
      int dimid;
      size_t count[NDIMS], index[NDIMS] = {0};
      const char ttext[TEXT_LEN + 1] = "20051224.150000";
      char ttext_in[TEXT_LEN + 1];
      char file_name[NC_MAX_NAME + 1];
      size_t chunks[NDIMS] = {TEXT_LEN + 1};
      int f;

      /* Create a bunch of files. */
      for (f = 0; f < NUM_FILES; f++)
      {
         sprintf(file_name, "tst_files2_%d.nc", f);
         if (nc_create(file_name, NC_NETCDF4, &ncid[f])) ERR;
         if (nc_def_dim(ncid[f], D1_NAME, TEXT_LEN + 1, &dimid)) ERR;
         if (nc_def_var(ncid[f], VAR_NAME, NC_CHAR, NDIMS, &dimid, &varid)) ERR;
         if (f % 2 == 0)
            if (nc_def_var_chunking(ncid[f], varid, 0, chunks)) ERR;

         /* Write one time to the coordinate variable. */
         count[0] = TEXT_LEN + 1;
         if (nc_put_vara_text(ncid[f], varid, index, count, ttext)) ERR;
      }

      /* Read something from each file. */
      for (f = 0; f < NUM_FILES; f++)
      {
         if (nc_get_vara_text(ncid[f], varid, index, count, (char *)ttext_in)) ERR;
         if (strcmp(ttext_in, ttext)) ERR;
      }

      /* Close all open files. */
      for (f = 0; f < NUM_FILES; f++)
         if (nc_close(ncid[f])) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
示例#29
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[%lu] = %.15g\tFrom fill file, %s[%lu] = %.15g\n", 
			       varname1, (unsigned long)nn, data1[nn], varname2, (unsigned long)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[%lu] = %d\tFrom fill file, %s[%lu] = %d\n", 
			       varname1, (unsigned long)nn, data1[nn], varname2, (unsigned long)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;
}
int main()
{
    int ncid, varid;
    int ncstat = NC_NOERR;
    char* url;
    char* topsrcdir;
    size_t len;
#ifndef USE_NETCDF4
    int i,j;
#endif

    /* location of our target url: use file:// to avoid remote
	server downtime issues
     */
    
    /* Assume that TESTS_ENVIRONMENT was set */
    topsrcdir = getenv("TOPSRCDIR");
    if(topsrcdir == NULL) {
        fprintf(stderr,"*** FAIL: $abs_top_srcdir not defined: location= %s:%d\n",__FILE__,__LINE__);
        exit(1);
    }    
    len = strlen("file://") + strlen(topsrcdir) + strlen("/ncdap_test/testdata3/test.02") + 1;
#ifdef DEBUG
    len += strlen("[log][show=fetch]");
#endif
    url = (char*)malloc(len);
    url[0] = '\0';

#ifdef DEBUG
    strcat(url,"[log][show=fetch]");
#endif

    strcat(url,"file://");
    strcat(url,topsrcdir);
    strcat(url,"/ncdap_test/testdata3/test.02");

    printf("*** Test: var conversions on URL: %s\n",url);

    /* open file, get varid */
    CHECK(nc_open(url, NC_NOWRITE, &ncid));
    
    /* extract the string case for netcdf-3*/
#ifndef USE_NETCDF4
    CHECK(nc_inq_varid(ncid, "s", &varid));
    CHECK(nc_get_var_text(ncid,varid,(char*)string3));
#ifdef GENERATE
    printf("static %s string3_data[DIMSIZE][STRLEN]={","char");
    for(i=0;i<DIMSIZE;i++) {
	int j;
	/* Do simple escape */
	for(j=0;j<STRLEN;j++) {
	    if(string3[i][j] > 0
	       && string3[i][j] != '\n'
	       && string3[i][j] != '\r'
	       && string3[i][j] != '\t'
	       &&(string3[i][j] < ' ' || string3[i][j] >= '\177'))
		string3[i][j] = '?';
	}
	printf("%s\"%s\"",COMMA,string3[i]);
    }
    printf("};\n");
#else
 	fprintf(stdout,"*** testing: %s\n","string3");
	for(i=0;i<DIMSIZE;i++) {
   	    for(j=0;j<STRLEN;j++) {
	        if(string3[i][j] != string3_data[i][j]) {report(i,"string3",__LINE__); break;}
	    }
	}
#endif
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_text(ncid,varid,ch));
#ifdef GENERATE
    printf("static %s ch_data[DIMSIZE]={","char");
    for(i=0;i<DIMSIZE;i++) printf("%s'\\%03hho'",COMMA,ch[i]);
    printf("};\n");
#else
    COMPARE(NC_CHAR,NC_CHAR,ch,ch_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_schar(ncid,varid,int8));
#ifdef GENERATE
    printf("static %s int8_data[DIMSIZE]={","signed char");
    for(i=0;i<DIMSIZE;i++) printf("%s%hhd",COMMA,int8[i]);
    printf("};\n");
#else
    COMPARE(NC_BYTE,NC_BYTE,int8,int8_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_uchar(ncid,varid,uint8));
#ifdef GENERATE
    printf("static %s uint8_data[DIMSIZE]={","unsigned char");
    for(i=0;i<DIMSIZE;i++) printf("%s%hhu",COMMA,uint8[i]);
    printf("};\n");
#else
    COMPARE(NC_UBYTE,NC_UBYTE,uint8,uint8_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_int(ncid,varid,int32));
#ifdef GENERATE
    printf("static %s int8toint32_data[DIMSIZE]={","int");
    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
    printf("};\n");
#else
    COMPARE(NC_BYTE,NC_INT,int32,int8toint32_data);
#endif

    CHECK(nc_inq_varid(ncid, "b", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32));
#ifdef GENERATE
    printf("static %s int82float32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
    printf("};\n");
#else
    COMPARE(NC_FLOAT,NC_FLOAT,float32,int82float32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i16", &varid));
    CHECK(nc_get_var_short(ncid,varid,int16));
#ifdef GENERATE
    printf("static %s int16_data[DIMSIZE]={","short");
    for(i=0;i<DIMSIZE;i++) printf("%s%hd",COMMA,int16[i]);
    printf("};\n");
#else
    COMPARE(NC_SHORT,NC_SHORT,int16,int16_data);
#endif

    CHECK(nc_inq_varid(ncid, "i16", &varid));
    CHECK(nc_get_var_int(ncid,varid,int32));
#ifdef GENERATE
    printf("static %s int16toint32_data[DIMSIZE]={","int");
    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
    printf("};\n");
#else
    COMPARE(NC_SHORT,NC_INT,int32,int16toint32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i16", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32));
#ifdef GENERATE
    printf("static %s int162float32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
    printf("};\n");
#else
    COMPARE(NC_SHORT,NC_FLOAT,float32,int162float32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i32", &varid));
    CHECK(nc_get_var_int(ncid,varid,int32));
#ifdef GENERATE
    printf("static %s int32_data[DIMSIZE]={","int");
    for(i=0;i<DIMSIZE;i++) printf("%s%d",COMMA,int32[i]);
    printf("};\n");
#else
    COMPARE(NC_INT,NC_INT,int32,int32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i32", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32));
#ifdef GENERATE
    printf("static %s int32tofloat32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
    printf("};\n");
#else
    COMPARE(NC_INT,NC_FLOAT,float32,int32tofloat32_data);
#endif

    CHECK(nc_inq_varid(ncid, "i32", &varid));
    CHECK(nc_get_var_long(ncid,varid,ilong));
#ifdef GENERATE
    printf("static %s int32toilong_data[DIMSIZE]={","long");
    for(i=0;i<DIMSIZE;i++) printf("%s%ld",COMMA,ilong[i]);
    printf("};\n");
#else
    COMPARE(NC_INT,NC_NAT,ilong,int32toilong_data);
#endif

    CHECK(nc_inq_varid(ncid, "f32", &varid));
    CHECK(nc_get_var_float(ncid,varid,float32));
#ifdef GENERATE
    printf("static %s float32_data[DIMSIZE]={","float");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float32[i]);
    printf("};\n");
#else
    COMPARE(NC_FLOAT,NC_FLOAT,float32,float32_data);
#endif

    CHECK(nc_inq_varid(ncid, "f64", &varid));
    CHECK(nc_get_var_double(ncid,varid,float64));
#ifdef GENERATE
    printf("static %s float64_data[DIMSIZE]={","double");
    for(i=0;i<DIMSIZE;i++) printf("%s%1.3f",COMMA,float64[i]);
    printf("};\n");
#else
    COMPARE(NC_DOUBLE,NC_DOUBLE,float64,float64_data);
#endif

    if(failure) {
        printf("ncstat=%d %s",ncstat,nc_strerror(ncstat));
        exit(1);
    }
    return 0;
}