Exemple #1
0
static char *
has_c_format_att(
    int ncid,			/* netcdf id */
    int varid			/* variable id */
    )
{
    nc_type cfmt_type;
    int cfmt_len;
#define C_FMT_NAME	"C_format" /* name of C format attribute */
#define	MAX_CFMT_LEN	100	/* max length of C format attribute */
    static char cfmt[MAX_CFMT_LEN];
    
    /* we expect nc_inq_att to fail if there is no "C_format" attribute */
    int old_nc_opts;
    int nc_stat;

    old_nc_opts = ncopts;
    ncopts = 0;
    nc_stat = ncattinq(ncid, varid, "C_format", &cfmt_type, &cfmt_len);
    ncopts = old_nc_opts;

    if (nc_stat == -1) {
        return 0;
    }

    if (cfmt_type == NC_CHAR && cfmt_len != 0 && cfmt_len < MAX_CFMT_LEN) {
        nc_stat = ncattget(ncid, varid, "C_format", cfmt);
        if(nc_stat != 1)
            nc_advise("Getting 'C_format' attribute", nc_stat, "");
        return &cfmt[0];
    }
    return 0;
}
/* ----------------------------- MNI Header -----------------------------------
@NAME       : update_history
@INPUT      : mincid - id of output minc file
              arg_string - string giving list of arguments
@OUTPUT     : (nothing)
@RETURNS    : (nothing)
@DESCRIPTION: Routine to update the history global variable in the output 
              minc file
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : August 26, 1993 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static void update_history(int mincid, char *arg_string)
{
   nc_type datatype;
   int att_length;
   char *string;

   /* Get the history attribute length */
   ncopts=0;
   if ((ncattinq(mincid, NC_GLOBAL, MIhistory, &datatype,
                 &att_length) == MI_ERROR) ||
       (datatype != NC_CHAR))
      att_length = 0;
   att_length += strlen(arg_string) + 1;

   /* Allocate a string and get the old history */
   string = malloc(att_length);
   string[0] = '\0';
   (void) miattgetstr(mincid, NC_GLOBAL, MIhistory, att_length, 
                      string);
   ncopts = NC_OPTS_VAL;

   /* Add the new command and put the new history. */
   (void) strcat(string, arg_string);
   (void) miattputstr(mincid, NC_GLOBAL, MIhistory, string);
   free(string);

}
Exemple #3
0
/*
 * Return information about a netCDF attribute given its variable
 * ID and name.
 */
static void
c_ncainq (
    int ncid,			/* netCDF ID */
    int varid,			/* variable ID */
    const char* attname,	/* attribute name */
    nc_type* datatype,		/* returned attribute datatype */
    int* attlen,		/* returned attribute length */
    int* rcode			/* returned error code */
)
{
    *rcode = ncattinq(ncid, varid, attname, datatype, attlen)
	     == -1
		? ncerr
		: 0;
}
Exemple #4
0
static DOUBLE
Add_Offset	(
	int	cdfid,
	int	varid
	)

{
	int			status;
	nc_type		datatype;
	int			len;
	char		value[32];
	DOUBLE		d;
	
	d = 0.0;
	
	if ((status = ncattinq(cdfid, varid, "add_offset", &datatype, &len)) == -1)	{
	}
	else if ((status = ncattget(cdfid, varid, "add_offset", value)) == -1)	{
	}
	else	{
		switch (RepairBadDataType(datatype))	{
			case NC_BYTE:
				d = (DOUBLE) *((signed char *) value);
				break;
			case NC_CHAR:
				d = (DOUBLE) *((char *) value);
				break;
			case NC_SHORT:
				d = (DOUBLE) *((short *) value);
				break;
			case NC_LONG:
				d = (DOUBLE) *((nclong *) value);
				break;
			case NC_FLOAT:
				d = (DOUBLE) *((float *) value);
				break;
			case NC_DOUBLE:
				d = (DOUBLE) *((double *) value);
				break;
			default:
				break;
		}
	}
	
	return (d);
}
Exemple #5
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : UpdateHistory
@INPUT      : ChildCDF - the MINC file which will have TimeStamp prepended
                         to its history attribute
              TimeStamp - string to be added to history attribute in ChildCDF
@OUTPUT     : (none)
@RETURNS    : (void)
@DESCRIPTION: Update the history of a MINC file by appending a string
              to it.  The history attribute will be created if it does
              not exist in the file specified by CDF; otherwise, its
              current value will be read in, the string TimeStamp will
              be appended to it, and it will be re-written.
@METHOD     : 
@GLOBALS    : 
@CALLS      : NetCDF, MINC libraries
@CREATED    : 93-10-27, Greg Ward (from MW's code formerly in micreate)
@MODIFIED   : 93-11-16, Greg Ward: removed references to parent file; the
              attribute should now be copied from the parent file before
	      UpdateHistory is ever called.
---------------------------------------------------------------------------- */
void UpdateHistory (int ChildCDF, char *TimeStamp)
{
   nc_type  HistType;
   int      HistLen;

#ifdef DEBUG
   printf ("UpdateHistory:\n");
#endif


   /* Update the history of the child file */
   
   if (ncattinq (ChildCDF,NC_GLOBAL,MIhistory,&HistType,&HistLen) == MI_ERROR)
   {
#ifdef DEBUG
      printf (" creating history attribute\n");
#endif
      ncattput (ChildCDF, NC_GLOBAL, MIhistory, NC_CHAR, 
                strlen(TimeStamp), TimeStamp);
   }
   else
   {
      char    *OldHist;
      char    *NewHist;

#ifdef DEBUG
      printf (" adding to history attribute\n");
#endif
      OldHist = (char *) malloc ((size_t) (HistLen*sizeof(char) + 1));
      ncattget (ChildCDF, NC_GLOBAL, MIhistory, OldHist);
      NewHist = (char *) malloc 
         ((size_t) (HistLen*sizeof(char) + strlen(TimeStamp)*sizeof(char) + 1));
      strcpy (NewHist, OldHist);
      strcat (NewHist, TimeStamp);
      ncattput (ChildCDF, NC_GLOBAL, MIhistory, NC_CHAR, 
                strlen(NewHist), NewHist);
      free (NewHist);
      free (OldHist);
   }
}     /* UpdateHistory () */
Exemple #6
0
MNCAPI int
MI2attinq(int fd, int varid, const char *attnm, nc_type *type_ptr,
          int *length_ptr)
{
    if (MI2_ISH5OBJ(fd)) {
        return (hdf_attinq(fd, varid, attnm, type_ptr, length_ptr));
    }
    else {
        int status;
        int oldncopts = ncopts;
        ncopts = 0;
        status = ncattinq(fd, varid, attnm, type_ptr, length_ptr);

        ncopts = oldncopts;
        if (status != 1 && oldncopts != 0) {
            fprintf(stderr,
                    _("ncattinq: ncid %d: varid: %d: Attribute '%s' not found"),
                    fd, varid, attnm);
	      
        }
        return (status);
    }
}
Exemple #7
0
int ex_get_block( int exoid,
  int blk_type,
  int blk_id,
  char* elem_type,
  int* num_entries_this_blk,
  int* num_nodes_per_entry,
  int* num_edges_per_entry,
  int* num_faces_per_entry,
  int* num_attr_per_entry )
{
   int dimid, connid, len, blk_id_ndx;
   long lnum_entries_this_blk, lnum_nodes_per_entry, lnum_attr_per_entry;
   long lnum_edges_per_entry, lnum_faces_per_entry;
   char *ptr;
   char  errmsg[MAX_ERR_LENGTH];
   nc_type dummy;
   const char* tname;
   const char* dnument;
   const char* dnumnod;
   const char* dnumedg;
   const char* dnumfac;
   const char* dnumatt;
   const char* ablknam;
   const char* vblkcon;
   const char* vblkids;

   exerrval = 0;

   /* First, locate index of element block id in VAR_ID_EL_BLK array */
   switch (blk_type) {
   case EX_EDGE_BLOCK:
     tname = "edge";
     vblkids = VAR_ID_ED_BLK;
     blk_id_ndx = ex_id_lkup(exoid,vblkids,blk_id);
     dnument = DIM_NUM_ED_IN_EBLK(blk_id_ndx);
     dnumnod = DIM_NUM_NOD_PER_ED(blk_id_ndx);
     dnumedg = 0;
     dnumfac = 0;
     dnumatt = DIM_NUM_ATT_IN_EBLK(blk_id_ndx);
     vblkcon = VAR_EBCONN(blk_id_ndx);
     ablknam = ATT_NAME_ELB;
     break;
   case EX_FACE_BLOCK:
     tname = "face";
     vblkids = VAR_ID_FA_BLK;
     blk_id_ndx = ex_id_lkup(exoid,vblkids,blk_id);
     dnument = DIM_NUM_FA_IN_FBLK(blk_id_ndx);
     dnumnod = DIM_NUM_NOD_PER_FA(blk_id_ndx);
     dnumedg = 0; /* it is possible this might be non-NULL some day */
     dnumfac = 0;
     dnumatt = DIM_NUM_ATT_IN_FBLK(blk_id_ndx);
     vblkcon = VAR_FBCONN(blk_id_ndx);
     ablknam = ATT_NAME_ELB;
     break;
   case EX_ELEM_BLOCK:
     tname = "element";
     vblkids = VAR_ID_EL_BLK;
     blk_id_ndx = ex_id_lkup(exoid,vblkids,blk_id);
     dnument = DIM_NUM_EL_IN_BLK(blk_id_ndx);
     dnumnod = DIM_NUM_NOD_PER_EL(blk_id_ndx);
     dnumedg = DIM_NUM_EDG_PER_EL(blk_id_ndx);
     dnumfac = DIM_NUM_FAC_PER_EL(blk_id_ndx);
     dnumatt = DIM_NUM_ATT_IN_BLK(blk_id_ndx);
     vblkcon = VAR_CONN(blk_id_ndx);
     ablknam = ATT_NAME_ELB;
     break;
   default:
     exerrval = EX_BADPARAM;
     sprintf( errmsg, "Bad block type parameter (%d) specified for file id %d.",
       blk_type, exoid );
     return (EX_FATAL);
   }

   if (exerrval != 0) 
     {
     if (exerrval == EX_NULLENTITY)     /* NULL element block?    */
       {
       if ( elem_type )
         strcpy(elem_type, "NULL");     /* NULL element type name */
       *num_entries_this_blk = 0;       /* no elements            */
       *num_nodes_per_entry = 0;        /* no nodes               */
       *num_attr_per_entry = 0;         /* no attributes          */
       return (EX_NOERR);
       }
     else
       {
       sprintf(errmsg,
        "Error: failed to locate element block id %d in %s array in file id %d",
               blk_id,vblkids,exoid);
       ex_err("ex_get_block",errmsg,exerrval);
       return (EX_FATAL);
       }
     }

   /* inquire values of some dimensions */
   if ( num_entries_this_blk )
     {
     if ((dimid = ncdimid (exoid, dnument)) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,
         "Error: failed to locate number of %ss in block %d in file id %d",
         tname,blk_id,exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }

     if (ncdiminq (exoid, dimid, (char *) 0, &lnum_entries_this_blk) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,
         "Error: failed to get number of %ss in block %d in file id %d",
         tname,blk_id, exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }
     *num_entries_this_blk = lnum_entries_this_blk;
     }

   if ( num_nodes_per_entry )
     {
     if ((dimid = ncdimid (exoid, dnumnod)) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,
         "Error: failed to locate number of nodes/%s in block %d in file id %d",
         tname,blk_id,exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }
     if (ncdiminq (exoid, dimid, (char *) 0, &lnum_nodes_per_entry) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,
         "Error: failed to get number of nodes/%s in block %d in file id %d",
         tname,blk_id, exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }
     *num_nodes_per_entry = lnum_nodes_per_entry;
     }

   if ( num_edges_per_entry )
     {
     if ( blk_type != EX_ELEM_BLOCK )
       {
       exerrval = (EX_WARN);
       sprintf(errmsg,
         "Warning: non-NULL pointer passed to num_edges_per_entry for %s block query in file id %d",
         tname,exoid);
       ex_err("ex_get_block",errmsg,exerrval);
       }
     else
       {
       if ((dimid = ncdimid (exoid, dnumedg)) == -1)
         {
         /* undefined => no edge entries per element */
         lnum_edges_per_entry = 0;
         }
       else
         {
         if (ncdiminq (exoid, dimid, (char *) 0, &lnum_edges_per_entry) == -1)
           {
           exerrval = ncerr;
           sprintf(errmsg,
             "Error: failed to get number of edges/%s in block %d in file id %d",
             tname,blk_id, exoid);
           ex_err("ex_get_block",errmsg, exerrval);
           return(EX_FATAL);
           }
         }
       *num_edges_per_entry = lnum_edges_per_entry;
       }
     }

   if ( num_faces_per_entry )
     {
     if ( blk_type != EX_ELEM_BLOCK )
       {
       exerrval = (EX_WARN);
       sprintf(errmsg,
         "Warning: non-NULL pointer passed to num_faces_per_entry for %s block query in file id %d",
         tname,exoid);
       ex_err("ex_get_block",errmsg,exerrval);
       }
     else
       {
       if ((dimid = ncdimid (exoid, dnumfac)) == -1)
         {
         /* undefined => no face entries per element */
         lnum_faces_per_entry = 0;
         }
       else
         {
         if (ncdiminq (exoid, dimid, (char *) 0, &lnum_faces_per_entry) == -1)
           {
           exerrval = ncerr;
           sprintf(errmsg,
             "Error: failed to get number of faces/%s in block %d in file id %d",
             tname,blk_id, exoid);
           ex_err("ex_get_block",errmsg, exerrval);
           return(EX_FATAL);
           }
         }
         *num_faces_per_entry = lnum_faces_per_entry;
       }
     }

   if ( num_attr_per_entry )
     {
     if ((dimid = ncdimid (exoid, dnumatt)) == -1)
       {
       /* dimension is undefined */
       *num_attr_per_entry = 0;
       }
     else
       {
       if (ncdiminq (exoid, dimid, (char *) 0, &lnum_attr_per_entry) == -1)
         {
         exerrval = ncerr;
         sprintf(errmsg,
           "Error: failed to get number of attributes in %s block %d in file id %d",
           tname,blk_id, exoid);
         ex_err("ex_get_block",errmsg, exerrval);
         return(EX_FATAL);
         }
       *num_attr_per_entry = lnum_attr_per_entry;
       }
     }

   if ( elem_type )
     {
     /* look up connectivity array for this element block id */
     if ((connid = ncvarid (exoid, vblkcon)) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,
         "Error: failed to locate connectivity array for element block %d in file id %d",
         blk_id,exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }

     if (ncattinq (exoid, connid, ablknam, &dummy, &len) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,
         "Error: failed to get element block %d type in file id %d",
         blk_id,exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }

     if (len > (MAX_STR_LENGTH+1))
       {
       len = MAX_STR_LENGTH;
       sprintf (errmsg,
         "Warning: element block %d type will be truncated to %d chars", 
         blk_id,len);
       ex_err("ex_get_block",errmsg,EX_MSG);
       }
     /* get the element type name */

     if (ncattget (exoid, connid, ablknam, elem_type) == -1)
       {
       exerrval = ncerr;
       sprintf(errmsg,"Error: failed to get element block %d type in file id %d",
         blk_id, exoid);
       ex_err("ex_get_block",errmsg, exerrval);
       return(EX_FATAL);
       }

     /* get rid of trailing blanks */
     ptr = elem_type;
     /* fprintf(stderr,"[exgblk] %s, len: %d\n",ptr,len); */
     while (ptr < elem_type + len && *ptr != ' ')
       {
       ptr++;
       }
     *(ptr) = '\0';
     }

   return (EX_NOERR);
}
Exemple #8
0
int ex_copy (int in_exoid, int out_exoid)
{
   int ndims;                   /* number of dimensions */
   int nvars;                   /* number of variables */
   int ngatts;                  /* number of global attributes */
   int recdimid;                /* id of unlimited dimension */
   int dimid;                   /* dimension id */
   int dim_out_id;              /* dimension id */
   int varid;                   /* variable id */
   int var_out_id;              /* variable id */
   struct ncvar var;            /* variable */
   struct ncatt att;            /* attribute */
   int i, temp;
   long numrec;
   long dim_sz;
   char dim_nm[MAX_NC_NAME];
   int in_large, out_large;
   
   extern int ncopts;

   exerrval = 0; /* clear error code */

   /*
    * Get exodus_large_model setting on both input and output
    * databases so know how to handle coordinates.
    */
   in_large  = ex_large_model(in_exoid);
   out_large = ex_large_model(out_exoid);
   
   /*
    * get number of dimensions, number of variables, number of global
    * atts, and dimension id of unlimited dimension, if any
    */

   ncinquire(in_exoid, &ndims, &nvars, &ngatts, &recdimid);
   ncdiminq (in_exoid, recdimid, (char *) 0, &numrec);

   /* put output file into define mode */

   ncredef(out_exoid);

   /* copy global attributes */

   for (i = 0; i < ngatts; i++) {

      ncattname(in_exoid, NC_GLOBAL, i, att.name);
        
      ncattinq(in_exoid, NC_GLOBAL, att.name, &att.type, &att.len);

      /* if attribute exists in output file, don't overwrite it; compute 
       * word size, I/O word size etc. are global attributes stored when
       * file is created with ex_create;  we don't want to overwrite those
       */

      if (ncattinq (out_exoid, NC_GLOBAL, att.name, &att.type, &att.len) == -1){

        /* The "last_written_time" attribute is a special attribute
           used by the Sierra IO system to determine whether a
           timestep has been fully written to the database in order to
           try to detect a database crash that happens in the middle
           of a database output step. Don't want to copy that attribute.
        */
        if (strcmp(att.name,"last_written_time") != 0) {
          /* attribute doesn't exist in new file so OK to create it */
          ncattcopy (in_exoid,NC_GLOBAL,att.name,out_exoid,NC_GLOBAL);
        }
      }
   }

   /* copy dimensions */

   /* Get the dimension sizes and names */

   for(dimid = 0; dimid < ndims; dimid++){

      ncdiminq(in_exoid,dimid,dim_nm,&dim_sz);

      /* See if the dimension has already been defined */

      temp = ncopts;
      ncopts = 0;
      dim_out_id = ncdimid(out_exoid,dim_nm);
      ncopts = temp;

      /* If the dimension isn't one we specifically don't want 
       * to copy (ie, number of QA or INFO records) and it 
       * hasn't been defined, copy it */

      if ( ( strcmp(dim_nm,DIM_NUM_QA)        != 0) &&
           ( strcmp(dim_nm,DIM_NUM_INFO)      != 0) &&
           ( strcmp(dim_nm,DIM_NUM_NOD_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_EDG_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_FAC_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_ELE_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_NSET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_ESET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_FSET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_SSET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_ELSET_VAR) != 0) &&
           ( strcmp(dim_nm,DIM_NUM_GLO_VAR)   != 0) ) {

         if(dim_out_id == -1){
            if(dimid != recdimid){
               dim_out_id=ncdimdef(out_exoid,dim_nm,dim_sz);
            }else{
               dim_out_id=ncdimdef(out_exoid,dim_nm,NC_UNLIMITED);
            } /* end else */
         } /* end if */
      } /* end if */
   } /* end loop over dim */

   /* copy variable definitions and variable attributes */

   for (varid = 0; varid < nvars; varid++) {

      ncvarinq(in_exoid, varid, var.name, &var.type, &var.ndims, 
                      var.dims, &var.natts);

      /* we don't want to copy some variables because there is not a
       * simple way to add to them;
       * QA records, info records and all results variables (nodal
       * element, and global results) are examples
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE) != 0)     &&
           ( strcmp(var.name,VAR_INFO) != 0)         &&
           ( strcmp(var.name,VAR_EBLK_TAB) != 0)     &&
           ( strcmp(var.name,VAR_FBLK_TAB) != 0)     &&
           ( strcmp(var.name,VAR_ELEM_TAB) != 0)     &&
           ( strcmp(var.name,VAR_ELSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_SSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_FSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_ESET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_NSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0) &&
           ( strcmp(var.name,VAR_GLO_VAR) != 0)      &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0) &&
           ( strcmp(var.name,VAR_NOD_VAR) != 0)      &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)  &&
           ( strncmp(var.name,"vals_elset_var", 14) != 0) &&
           ( strncmp(var.name,"vals_sset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_fset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_eset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nod_var",   12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",  13) != 0) &&
           ( strncmp(var.name,"vals_face_var",  13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",  13) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          var_out_id = cpy_coord_def (in_exoid, out_exoid, recdimid, var.name,
                                      in_large, out_large);
        } else {
          var_out_id = cpy_var_def (in_exoid, out_exoid, recdimid, var.name);
        }

         /* copy the variable's attributes */
         (void) cpy_att (in_exoid, out_exoid, varid, var_out_id);

      }
   }

   /* take the output file out of define mode */
   ncendef (out_exoid);

   /* output variable data */

   for (varid = 0; varid < nvars; varid++) {
      ncvarinq(in_exoid, varid, var.name, &var.type, &var.ndims,
                    var.dims, &var.natts);

      /* we don't want to copy some variable values;
       * QA records and info records shouldn't be copied because there
       * isn't an easy way to add to them;
       * the time value array ("time_whole") and any results variables
       * (nodal, elemental, or global) shouldn't be copied 
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE) != 0)        &&
           ( strcmp(var.name,VAR_INFO) != 0)            &&
           ( strcmp(var.name,VAR_EBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELEM_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELSET_TAB) != 0)       &&
           ( strcmp(var.name,VAR_SSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ESET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0)    &&
           ( strcmp(var.name,VAR_GLO_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NOD_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)  &&
           ( strncmp(var.name,"vals_elset_var", 14) != 0)&&
           ( strncmp(var.name,"vals_sset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_fset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_eset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nod_var", 12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",13) != 0) &&
           ( strncmp(var.name,"vals_face_var",13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",13) != 0) &&
           ( strcmp(var.name,VAR_WHOLE_TIME) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          (void) cpy_coord_val (in_exoid, out_exoid, var.name,
                                in_large, out_large);
        } else {
          (void) cpy_var_val (in_exoid, out_exoid, var.name);
        }

      }
   }

   /* ensure internal data structures are updated */

   /* if number of blocks > 0 */
   update_internal_structs( out_exoid, EX_INQ_EDGE_BLK, &ed_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_FACE_BLK, &fa_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_ELEM_BLK, &eb_ctr_list );

   /* if number of sets > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_SETS, &ns_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_EDGE_SETS, &es_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_FACE_SETS, &fs_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_SIDE_SETS, &ss_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_ELEM_SETS, &els_ctr_list );

   /* if number of maps > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_MAP, &nm_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_EDGE_MAP, &edm_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_FACE_MAP, &fam_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_ELEM_MAP, &em_ctr_list );

   return(EX_NOERR);
}
Exemple #9
0
int ex_get_init_ext (int   exoid,
                     ex_init_params *info)
{
  int dimid;
  long lnum_dim, lnum_nodes, lnum_elem, lnum_elem_blk, lnum_node_sets; 
  long lnum_side_sets, lnum_edge_sets, lnum_face_sets, lnum_elem_sets;
  long lnum_node_maps, lnum_edge_maps, lnum_face_maps, lnum_elem_maps;
  long lnum_edge, lnum_face, lnum_edge_blk, lnum_face_blk;
  char errmsg[MAX_ERR_LENGTH];
  int title_len;
  nc_type title_type;

  exerrval = 0; /* clear error code */

  if (ncattinq (exoid, NC_GLOBAL, ATT_TITLE, &title_type, &title_len) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to inquire title in file id %d", exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }

  /* Check title length to avoid overrunning clients memory space;
     include trailing null */
  if (title_len > MAX_LINE_LENGTH+1) {
    sprintf(errmsg,
            "Error: Title is too long (%d characters) in file id %d",
            title_len-1, exoid);
    exerrval = -1;
    ex_err("ex_get_init",errmsg,exerrval);
    return (EX_FATAL);
  }
  /* printf("[ex_get_init] title length: %d\n",title_len); */

  if (ncattget (exoid, NC_GLOBAL, ATT_TITLE, info->title) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to get title in file id %d", exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }

    
  /* printf("[ex_get_init] title: %s\n",info->title); */


  if ((dimid = ncdimid (exoid, DIM_NUM_DIM)) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to locate number of dimensions in file id %d",
              exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }

  if (ncdiminq (exoid, dimid, (char *) 0, &lnum_dim) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to get number of dimensions in file id %d",
              exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }
  info->num_dim = lnum_dim;


  /* Handle case with zero-nodes */
#define EX_GET_DIM_VALUE(TNAME,DNAME,DIMVAR,LDIMVAL,SDIMVAL) \
  if ((DIMVAR = ncdimid (exoid, DNAME)) == -1) { \
    /* TNAME are optional and default to zero. */ \
    SDIMVAL = 0; \
  } else { \
      \
    if (ncdiminq (exoid, DIMVAR, (char *) 0, &LDIMVAL) == -1) \
      { \
        exerrval = ncerr; \
        sprintf(errmsg, \
                "Error: failed to get number of " TNAME " in file id %d", \
                exoid); \
        ex_err("ex_get_init",errmsg,exerrval); \
        return (EX_FATAL); \
      } \
    SDIMVAL = LDIMVAL; \
  }
  EX_GET_DIM_VALUE(   "nodes",DIM_NUM_NODES,dimid,lnum_nodes,info->num_nodes);
  EX_GET_DIM_VALUE(   "edges", DIM_NUM_EDGE,dimid, lnum_edge, info->num_edge);
  EX_GET_DIM_VALUE(   "faces", DIM_NUM_FACE,dimid, lnum_face, info->num_face);
  EX_GET_DIM_VALUE("elements", DIM_NUM_ELEM,dimid, lnum_elem, info->num_elem);
   
  if (info->num_elem > 0) {
    if ((dimid = ncdimid (exoid, DIM_NUM_EL_BLK)) == -1)
      {
        exerrval = ncerr;
        sprintf(errmsg,
                "Error: failed to locate number of element blocks in file id %d",
                exoid);
        ex_err("ex_get_init",errmsg,exerrval);
        return (EX_FATAL);
      }

    if (ncdiminq (exoid, dimid, (char *) 0, &lnum_elem_blk) == -1)
      {
        exerrval = ncerr;
        sprintf(errmsg,
                "Error: failed to get number of element blocks in file id %d",
                exoid);
        ex_err("ex_get_init",errmsg,exerrval);
        return (EX_FATAL);
      }
    info->num_elem_blk = lnum_elem_blk;
  } else {
    info->num_elem_blk = 0;
  }


  EX_GET_DIM_VALUE("node sets", DIM_NUM_NS,dimid,lnum_node_sets,info->num_node_sets);
  EX_GET_DIM_VALUE("edge sets", DIM_NUM_ES,dimid,lnum_edge_sets,info->num_edge_sets);
  EX_GET_DIM_VALUE("face sets", DIM_NUM_FS,dimid,lnum_face_sets,info->num_face_sets);
  EX_GET_DIM_VALUE("side sets", DIM_NUM_SS,dimid,lnum_side_sets,info->num_side_sets);
  EX_GET_DIM_VALUE("elem sets",DIM_NUM_ELS,dimid,lnum_elem_sets,info->num_elem_sets);

  EX_GET_DIM_VALUE("node maps", DIM_NUM_NM,dimid,lnum_node_maps,info->num_node_maps);
  EX_GET_DIM_VALUE("edge maps",DIM_NUM_EDM,dimid,lnum_edge_maps,info->num_edge_maps);
  EX_GET_DIM_VALUE("face maps",DIM_NUM_FAM,dimid,lnum_face_maps,info->num_face_maps);
  EX_GET_DIM_VALUE("elem maps", DIM_NUM_EM,dimid,lnum_elem_maps,info->num_elem_maps);

  /* Edge and face blocks are also optional (for backwards compatability) */
  EX_GET_DIM_VALUE("edge blocks",DIM_NUM_ED_BLK,dimid,lnum_edge_blk,info->num_edge_blk);
  EX_GET_DIM_VALUE("face blocks",DIM_NUM_FA_BLK,dimid,lnum_face_blk,info->num_face_blk);

  return (EX_NOERR);
}
Exemple #10
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : PutMaxMin
@INPUT      : ImInfo - pointer to struct describing the image variable
              ImVals - pointer to array of doubles containing the image data
              SliceNum, FrameNum - needed to correctly place the max and min
                values into the MIimagemax and MIimagemin variables
              DoFrames - whether or not there is a time dimension in this file
@OUTPUT     : (none)
@RETURNS    : (void)
@DESCRIPTION: Finds the max and min values of an image, and puts them
              into the MIimagemax and MIimagemin variables associated
              with the specified image variable.  Note: the caller must
              make sure that MIimagemax and MIimagemin exist in the
              file, and ensure that ImInfo->MaxID and ImInfo->MinID contain
              their variable ID's.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : 93-6-3, Greg Ward
@MODIFIED   : 
---------------------------------------------------------------------------- */
void PutMaxMin (ImageInfoRec *ImInfo, double *ImVals, 
                long SliceNum, long FrameNum, 
                Boolean DoSlices, Boolean DoFrames)
{
   int      i;
   double   Max, Min;
   long     Coord [2];          /* might use 0, 1 or 2 elements */
   int      old_ncopts;
   int      ret;
   nc_type  range_type;
   int      range_len;
   int      update_vr;
   double   valid_range[2];
   double   vr_max;

#ifdef DEBUG
   int      NumDims;            /* number of dimensions in imagemax/imagemin */
   int      Dims [4];           /* dimension ID's of imagemax/imagemin */

   printf ("Slice dimension is %d\n", ImInfo->SliceDim);
   printf ("Frame dimension is %d\n", ImInfo->FrameDim);

   ncvarinq (ImInfo->CDF, ImInfo->MaxID, NULL, NULL, &NumDims, Dims, NULL);
   printf ("MIimagemax has %d dimensions: ", NumDims);
   for (i = 0; i < NumDims; i++)
   {
      printf ("%5d", Dims [i]);
   }
   putchar ('\n');

   ncvarinq (ImInfo->CDF, ImInfo->MinID, NULL, NULL, &NumDims, Dims, NULL);
   printf ("MIimagemin has %d dimensions: ", NumDims);
   for (i = 0; i < NumDims; i++)
   {
      printf ("%5d", Dims [i]);
   }
   putchar ('\n');
#endif

   Max = - DBL_MAX;
   Min = DBL_MAX;

   /*
    * Find the actual max and min values in the buffer
    */

   for (i = 0; i < ImInfo->ImageSize; i++)
   {
      if (ImVals [i] > Max)
      {
         Max = ImVals [i];
      }

      if (ImVals [i] < Min)
      {
         Min = ImVals [i];
      }
   }     /* for i */

   /*
    * Now figure out the Coord vector (where to put the max and min
    * within the MIimagemax and MIimagemin variables), and put 'em there
    */

   if (DoFrames)        /* i.e. some frame was specified */
   { 
      Coord [ImInfo->FrameDim] = FrameNum;
   }

   if (DoSlices)
   {
      Coord [ImInfo->SliceDim] = SliceNum;
   }

#ifdef DEBUG
   printf ("Slice %ld, frame %ld: max is %lg, min is %lg\n", 
           (DoSlices) ? (SliceNum) : -1,
           (DoFrames) ? (FrameNum) : -1,
           Max, Min);
   if (DoSlices && DoFrames)
      printf ("Coord vector is: %ld %ld\n", Coord [0], Coord [1]);
   
#endif

   mivarput1 (ImInfo->CDF, ImInfo->MaxID, Coord, NC_DOUBLE, MI_SIGNED, &Max);
   mivarput1 (ImInfo->CDF, ImInfo->MinID, Coord, NC_DOUBLE, MI_SIGNED, &Min);

   /*
    * Update the image valid_range attribute for floating-point volumes
    */
   if ((ImInfo->DataType == NC_FLOAT) || (ImInfo->DataType == NC_DOUBLE)) {

      /* Get type and length of valid_range attribute */
      old_ncopts = ncopts; ncopts = 0;
      ret = ncattinq(ImInfo->CDF, ImInfo->ID, MIvalid_range, 
                     &range_type, &range_len);
      ncopts = old_ncopts;

      /* If type and length are okay, then read in old value and update */
      if ((ret != MI_ERROR) && 
          (range_type == NC_DOUBLE) && (range_len == 2)) {

         (void) ncattget(ImInfo->CDF, ImInfo->ID, MIvalid_range, valid_range);

         /* Test for first write of valid range */
         vr_max = (ImInfo->DataType == NC_DOUBLE ? 
                   1.79769313e+308 : 3.402e+38);
         update_vr = ((valid_range[0] < -vr_max) && (valid_range[1] > vr_max));

         /* Check the range */
         if ((Min < valid_range[0]) || update_vr)
            valid_range[0] = Min;
         if ((Max > valid_range[1]) || update_vr)
            valid_range[1] = Max;

         /* Check for whether float rounding is needed */
         if (ImInfo->DataType == NC_FLOAT) {
            valid_range[0] = (float) valid_range[0];
            valid_range[1] = (float) valid_range[1];
         }

         /* Write it out */
         (void) ncattput(ImInfo->CDF, ImInfo->ID, MIvalid_range, 
                         NC_DOUBLE, 2, valid_range);

      }

   }     /* if DataType is floating-point */

}     /* PutMaxMin */
Exemple #11
0
int ex_get_elem_block (int   exoid,
                       int   elem_blk_id,
                       char *elem_type,
                       int  *num_elem_this_blk, 
                       int  *num_nodes_per_elem,
                       int  *num_attr)

{
   int dimid, connid, len, elem_blk_id_ndx;
   long lnum_elem_this_blk, lnum_nodes_per_elem, lnum_attr;
   char *ptr;
   char  errmsg[MAX_ERR_LENGTH];
   nc_type dummy;

   exerrval = 0;

/* First, locate index of element block id in VAR_ID_EL_BLK array */

   elem_blk_id_ndx = ex_id_lkup(exoid,VAR_ID_EL_BLK,elem_blk_id);
   if (exerrval != 0) 
   {
     if (exerrval == EX_NULLENTITY)     /* NULL element block?    */
     {
       strcpy(elem_type, "NULL");       /* NULL element type name */
       *num_elem_this_blk = 0;          /* no elements            */
       *num_nodes_per_elem = 0;         /* no nodes               */
       *num_attr = 0;                   /* no attributes          */
       return (EX_NOERR);
     }
     else
     {
       sprintf(errmsg,
        "Error: failed to locate element block id %d in %s array in file id %d",
               elem_blk_id,VAR_ID_EL_BLK,exoid);
       ex_err("ex_get_elem_block",errmsg,exerrval);
       return (EX_FATAL);
     }
   }

/* inquire values of some dimensions */

   if ((dimid = ncdimid (exoid, DIM_NUM_EL_IN_BLK(elem_blk_id_ndx))) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
         "Error: failed to locate number of elements in block %d in file id %d",
             elem_blk_id,exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }

   if (ncdiminq (exoid, dimid, (char *) 0, &lnum_elem_this_blk) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
            "Error: failed to get number of elements in block %d in file id %d",
             elem_blk_id, exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }
   *num_elem_this_blk = lnum_elem_this_blk;
   if ((dimid = ncdimid (exoid, DIM_NUM_NOD_PER_EL(elem_blk_id_ndx))) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
    "Error: failed to locate number of nodes/element in block %d in file id %d",
             elem_blk_id,exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }
   if (ncdiminq (exoid, dimid, (char *) 0, &lnum_nodes_per_elem) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
       "Error: failed to get number of nodes/element in block %d in file id %d",
             elem_blk_id, exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }
   *num_nodes_per_elem = lnum_nodes_per_elem;

   if ((dimid = ncdimid (exoid, DIM_NUM_ATT_IN_BLK(elem_blk_id_ndx))) == -1)
      *num_attr = 0;            /* dimension is undefined */
   else
   {
     if (ncdiminq (exoid, dimid, (char *) 0, &lnum_attr) == -1)
     {
       exerrval = ncerr;
       sprintf(errmsg,
          "Error: failed to get number of attributes in block %d in file id %d",
               elem_blk_id, exoid);
       ex_err("ex_get_elem_block",errmsg, exerrval);
       return(EX_FATAL);
     }
     *num_attr = lnum_attr;
   }

   /* look up connectivity array for this element block id */

   if ((connid = ncvarid (exoid, VAR_CONN(elem_blk_id_ndx))) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
"Error: failed to locate connectivity array for element block %d in file id %d",
             elem_blk_id,exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }

   if (ncattinq (exoid, connid, ATT_NAME_ELB, &dummy, &len) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,
    "Error: failed to get element block %d type in file id %d",
             elem_blk_id,exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }

   if (len > (MAX_STR_LENGTH+1))
   {
     len = MAX_STR_LENGTH;
     sprintf (errmsg,
             "Warning: element block %d type will be truncated to %d chars", 
              elem_blk_id,len);
     ex_err("ex_get_elem_block",errmsg,EX_MSG);
   }
/* get the element type name */

   if (ncattget (exoid, connid, ATT_NAME_ELB, elem_type) == -1)
   {
     exerrval = ncerr;
     sprintf(errmsg,"Error: failed to get element block %d type in file id %d",
              elem_blk_id, exoid);
     ex_err("ex_get_elem_block",errmsg, exerrval);
     return(EX_FATAL);
   }

/* get rid of trailing blanks */
   ptr = elem_type;
   /* fprintf(stderr,"[exgelb] %s, len: %d\n",ptr,len); */
   while (ptr < elem_type + len && *ptr != ' ')
   {
     ptr++;
   }
   *(ptr) = '\0';

   return (EX_NOERR);
}
Exemple #12
0
void
mexFunction	(
	INT			nlhs,
	Matrix	*	plhs[],
	INT			nrhs,
	const Matrix	*	prhs[]
	)

{
	char		*	opname;
	OPCODE			opcode;
	
	Matrix		*	mat;
	
	int				status;
	char		*	path;
	int				cmode;
	int				mode;
	int				cdfid;
	int				ndims;
	int				nvars;
	int				natts;
	int				recdim;
	char		*	name;
	long			length;
	int				dimid;
	nc_type			datatype;
	int			*	dim;
	int				varid;
	long		*	coords;
	VOIDP			value;
	long		*	start;
	long		*	count;
	int			*	intcount;
	long		*	stride;
	long		*	imap;
	long			recnum;
	int				nrecvars;
	int			*	recvarids;
	long		*	recsizes;
	VOIDPP			datap;		/*	pointers for record access.	*/
	int				len;
	int				incdf;
	int				invar;
	int				outcdf;
	int				outvar;
	int				attnum;
	char		*	attname;
	char		*	newname;
	int				fillmode;
	
	int				i;
	int				m;
	int				n;
	char		*	p;
	char			buffer[MAX_BUFFER];
	
	DOUBLE		*	pr;
	DOUBLE			addoffset;
	DOUBLE			scalefactor;
	int				autoscale;		/*	do auto-scaling if this flag is non-zero.	*/
	
	/*	Disable the NC_FATAL option from ncopts.	*/
	
	if (ncopts & NC_FATAL)	{
		ncopts -= NC_FATAL;
	}
	
	/*	Display usage if less than one input argument.	*/
	
	if (nrhs < 1)	{
	
		Usage();
		
		return;
	}
	
	/*	Convert the operation name to its opcode.	*/
	
	opname = Mat2Str(prhs[0]);
	for (i = 0; i < strlen(opname); i++)	{
		opname[i] = (char) tolower((int) opname[i]);
	}
	p = opname;
	if (strncmp(p, "nc", 2) == 0)	{	/*	Trim away "nc".	*/
		p += 2;
	}
	
	i = 0;
	opcode = NONE;
	while (ops[i].opcode != NONE)	{
		if (!strcmp(p, ops[i].opname))	{
			opcode = ops[i].opcode;
			if (ops[i].nrhs > nrhs)	{
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few input arguments.\n");
			}
			else if (0 && ops[i].nlhs > nlhs)	{	/*	Disabled.	*/
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few output arguments.\n");
			}
			break;
		}
		else	{
			i++;
		}
	}
	
	if (opcode == NONE)	{
		mexPrintf("MEXCDF: opname = %s\n", opname);
		mexErrMsgTxt("MEXCDF: No such operation.\n");
	}
	
	Free((VOIDPP) & opname);
	
	/*	Extract the cdfid by number.	*/
	
	switch (opcode)	{
	
	case USAGE:
	case CREATE:
	case OPEN:
	case TYPELEN:
	case SETOPTS:
	case ERR:
	case PARAMETER:
	
		break;
	
	default:

		cdfid = Scalar2Int(prhs[1]);
	
		break;
	}
	
	/*	Extract the dimid by number or name.	*/
	
	switch (opcode)	{

	case DIMINQ:
	case DIMRENAME:
	
		if (mxIsNumeric(prhs[2]))	{
			dimid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			dimid = ncdimid(cdfid, name);
			Free((VOIDPP) & name);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the varid by number or name.	*/
	
	switch (opcode)	{

	case VARINQ:
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:
	case VARRENAME:
	case VARCOPY:
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTNAME:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[2]))	{
			varid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			varid = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
			if (varid == -1)	{
				varid = Parameter(prhs[2]);
			}
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the attname by name or number.	*/
	
	switch (opcode)	{
	
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[3]))	{
			attnum = Scalar2Int(prhs[3]);
			attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
			status = ncattname(cdfid, varid, attnum, attname);
		}
		else	{
			attname = Mat2Str(prhs[3]);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the "add_offset" and "scale_factor" attributes.	*/
	
	switch (opcode)	{
	
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:

		addoffset = Add_Offset(cdfid, varid);
		scalefactor = Scale_Factor(cdfid, varid);
		if (scalefactor == 0.0)	{
			scalefactor = 1.0;
		}
		
		break;
	
	default:
	
		break;
	}
	
	/*	Perform the NetCDF operation.	*/
	
	switch (opcode)	{
		
	case USAGE:
	
		Usage();
		
		break;
	
	case CREATE:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			cmode = Parameter(prhs[2]);
		}
		else	{
			cmode = NC_NOCLOBBER;	/*	Default.	*/
		}
		
		cdfid = nccreate(path, cmode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case OPEN:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			mode = Parameter(prhs[2]);
		}
		else	{
			mode = NC_NOWRITE;	/*	Default.	*/
		}
		
		cdfid = ncopen(path, mode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case REDEF:
		
		status = ncredef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ENDEF:
		
		status = ncendef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case CLOSE:
		
		status = ncclose(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case INQUIRE:
	
		status = ncinquire(cdfid, & ndims, & nvars, & natts, & recdim);
		
		if (nlhs > 1)	{
			plhs[0] = Int2Scalar(ndims);
			plhs[1] = Int2Scalar(nvars);
			plhs[2] = Int2Scalar(natts);
			plhs[3] = Int2Scalar(recdim);
			plhs[4] = Int2Scalar(status);
		}
		else	{	/*	Default to 1 x 5 row vector.	*/
			plhs[0] = mxCreateFull(1, 5, REAL);
			pr = mxGetPr(plhs[0]);
			if (status == 0)	{
				pr[0] = (DOUBLE) ndims;
				pr[1] = (DOUBLE) nvars;
				pr[2] = (DOUBLE) natts;
				pr[3] = (DOUBLE) recdim;
			}
			pr[4] = (DOUBLE) status;
		}
		
		break;
		
	case SYNC:
	
		status = ncsync(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ABORT:
	
		status = ncabort(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case DIMDEF:
	
		name = Mat2Str(prhs[2]);
		length = Parameter(prhs[3]);
		
		dimid = ncdimdef(cdfid, name, length);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMID:
	
		name = Mat2Str(prhs[2]);
		
		dimid = ncdimid(cdfid, name);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMINQ:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncdiminq(cdfid, dimid, name, & length);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Long2Scalar(length);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncdimrename(cdfid, dimid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARDEF:
	
		name = Mat2Str(prhs[2]);
		datatype = (nc_type) Parameter(prhs[3]);
		ndims = Scalar2Int(prhs[4]);
		if (ndims == -1)	{
			ndims = Count(prhs[5]);
		}
		dim = Mat2Int(prhs[5]);
		
		varid = ncvardef(cdfid, name, datatype, ndims, dim);
		
		Free((VOIDPP) & name);
		
		plhs[0] = Int2Scalar(varid);
		plhs[1] = Int2Scalar((varid >= 0) ? 0 : varid);
		
		break;
		
	case VARID:
	
		name = Mat2Str(prhs[2]);
		
		varid = ncvarid(cdfid, name);
		
		Free((VOIDPP) & name);
		
		plhs[0] = Int2Scalar(varid);
		plhs[1] = Int2Scalar((varid >= 0) ? 0 : varid);
		
		break;
		
	case VARINQ:
	
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Int2Scalar(datatype);
		plhs[2] = Int2Scalar(ndims);
		plhs[3] = Int2Mat(dim, 1, ndims);
		plhs[4] = Int2Scalar(natts);
		plhs[5] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		break;
		
	case VARPUT1:
		
		coords = Mat2Long(prhs[3]);
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[4]);
		}
		else	{
			mat = prhs[4];
		}
		if (mat == NULL)	{
			mat = prhs[4];
		}
		
		pr = mxGetPr(mat);
		
		autoscale = (nrhs > 5 && Scalar2Int(prhs[5]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		status = Convert(opcode, datatype, 1, buffer, scalefactor, addoffset, pr);
		status = ncvarput1(cdfid, varid, coords, buffer);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & coords);
		
		break;
		
	case VARGET1:
		
		coords = Mat2Long(prhs[3]);
		
		autoscale = (nrhs > 4 && Scalar2Int(prhs[4]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		mat = Int2Scalar(0);
		
		pr = mxGetPr(mat);
		
		status = ncvarget1(cdfid, varid, coords, buffer);
		status = Convert(opcode, datatype, 1, buffer, scalefactor, addoffset, pr);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[0] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & coords);
		
		break;
		
	case VARPUT:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
		
		autoscale = (nrhs > 6 && Scalar2Int(prhs[6]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[5]);
		}
		else	{
			mat = prhs[5];
		}
		if (mat == NULL)	{
			mat = prhs[5];
		}
		
		pr = mxGetPr(mat);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		len = 0;
		if (ndims > 0)	{
			len = 1;
			for (i = 0; i < ndims; i++)	{
				len *= count[i];
			}
		}
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		status = ncvarput(cdfid, varid, start, count, value);
		Free((VOIDPP) & value);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & start);
		Free((VOIDPP) & count);
		
		break;
		
	case VARGET:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
        intcount = Mat2Int(prhs[4]);
		
		autoscale = (nrhs > 5 && Scalar2Int(prhs[5]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		m = 0;
		n = 0;
		if (ndims > 0)	{
			m = count[0];
			n = count[0];
			for (i = 1; i < ndims; i++)	{
				n *= count[i];
				if (count[i] > 1)	{
					m = count[i];
				}
			}
			n /= m;
		}
		len = m * n;
		if (ndims < 2)	{
			m = 1;
			n = len;
		}
		
		for (i = 0; i < ndims; i++)	{
			intcount[i] = count[ndims-i-1];   /*	Reverse order.	*/
		}
		
		if (MEXCDF_4 || ndims < 2)	{
			mat = mxCreateFull(m, n, mxREAL);	/*	mxCreateDoubleMatrix	*/
		}
# if MEXCDF_5
		else	{
			mat = mxCreateNumericArray(ndims, intcount, mxDOUBLE_CLASS, mxREAL);
		}
# endif
		
		pr = mxGetPr(mat);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncvarget(cdfid, varid, start, count, value);
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		Free((VOIDPP) & value);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
			plhs[0] = mat;
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & intcount);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;
		
	case VARPUTG:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		if (nrhs > 7)	{
			if (datatype == NC_CHAR)	{
				mat = SetStr(prhs[7]);
			}
			else	{
				mat = prhs[7];
			}
			if (mat == NULL)	{
				mat = prhs[7];
			}
		}
		else	{
			if (datatype == NC_CHAR)	{
				mat = SetStr(prhs[6]);
			}
			else	{
				mat = prhs[6];
			}
			if (mat == NULL)	{
				mat = prhs[6];
			}
		}
		pr = mxGetPr(mat);
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
		stride = Mat2Long(prhs[5]);
		imap = NULL;
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		len = 0;
		if (ndims > 0)	{
			len = 1;
			for (i = 0; i < ndims; i++)	{
				len *= count[i];
			}
		}
		
		autoscale = (nrhs > 8 && Scalar2Int(prhs[8]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		status = ncvarputg(cdfid, varid, start, count, stride, imap, value);
		Free((VOIDPP) & value);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & stride);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;
		
	case VARGETG:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
        intcount = Mat2Int(prhs[4]);
		stride = Mat2Long(prhs[5]);
		imap = NULL;
		
		autoscale = (nrhs > 7 && Scalar2Int(prhs[7]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		m = 0;
		n = 0;
		if (ndims > 0)	{
			m = count[0];
			n = count[0];
			for (i = 1; i < ndims; i++)	{
				n *= count[i];
				if (count[i] > 1)	{
					m = count[i];
				}
			}
			n /= m;
		}
		len = m * n;
		if (ndims < 2)	{
			m = 1;
			n = len;
		}
		
		for (i = 0; i < ndims; i++)	{
			intcount[i] = count[ndims-i-1];   /*	Reverse order.	*/
		}
		
		if (MEXCDF_4 || ndims < 2)	{
			mat = mxCreateFull(m, n, mxREAL);	/*	mxCreateDoubleMatrix	*/
		}
# if MEXCDF_5
		else	{
			mat = mxCreateNumericArray(ndims, intcount, mxDOUBLE_CLASS, mxREAL);
		}
# endif
		
		pr = mxGetPr(mat);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncvargetg(cdfid, varid, start, count, stride, imap, value);
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		Free((VOIDPP) & value);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[0] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & stride);
		Free((VOIDPP) & intcount);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;

	case VARRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncvarrename(cdfid, varid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARCOPY:
	
		incdf = cdfid;
		
		invar = varid;
		
		outcdf = Scalar2Int(prhs[3]);
	
		outvar = -1;
/*		outvar = ncvarcopy(incdf, invar, outcdf);	*/
		
		plhs[0] = Int2Scalar(outvar);
		plhs[1] = Int2Scalar((outvar >= 0) ? 0 : outvar);
		
		break;
		
	case ATTPUT:
		
		datatype = (nc_type) Parameter(prhs[4]);
		
		datatype = RepairBadDataType(datatype);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[6]);
		}
		else	{
			mat = prhs[6];
		}
		if (mat == NULL)	{
			mat = prhs[6];
		}
		
		len = Scalar2Int(prhs[5]);
		if (len == -1)	{
			len = Count(mat);
		}
		
		pr = mxGetPr(mat);
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, (DOUBLE) 1.0, (DOUBLE) 0.0, pr);
		
		status = ncattput(cdfid, varid, attname, datatype, len, value);
		
		if (value != NULL)	{
			Free((VOIDPP) & value);
		}
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTINQ:
		
		status = ncattinq(cdfid, varid, attname, & datatype, & len);
		
		datatype = RepairBadDataType(datatype);
		
		plhs[0] = Int2Scalar((int) datatype);
		plhs[1] = Int2Scalar(len);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTGET:
		
		status = ncattinq(cdfid, varid, attname, & datatype, & len);
		
		datatype = RepairBadDataType(datatype);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncattget(cdfid, varid, attname, value);
		
		mat = mxCreateDoubleMatrix(1, len, mxREAL);
		
		pr = mxGetPr(mat);
		
		status = Convert(opcode, datatype, len, value, (DOUBLE) 1.0, (DOUBLE) 0.0, pr);
		
		if (value != NULL)	{
			Free((VOIDPP) & value);
		}
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[4] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTCOPY:
	
		incdf = cdfid;
		
		invar = varid;
		
		outcdf = Scalar2Int(prhs[4]);
	
		if (mxIsNumeric(prhs[5]))	{
			outvar = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[5]);
			outvar = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
		}
	
		status = ncattcopy(incdf, invar, attname, outcdf, outvar);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTNAME:
		
		attnum = Scalar2Int(prhs[3]);
		attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncattname(cdfid, varid, attnum, attname);
		
		plhs[0] = Str2Mat(attname);
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTRENAME:
	
		newname = Mat2Str(prhs[4]);
		
		status = ncattrename(cdfid, varid, attname, newname);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		Free((VOIDPP) & newname);
		
		break;
		
	case ATTDEL:
		
		status = ncattdel(cdfid, varid, attname);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case RECPUT:
		
		recnum = Scalar2Long(prhs[2]);
		pr = mxGetPr(prhs[3]);
		
		autoscale = (nrhs > 4 && Scalar2Int(prhs[4]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		datap = (VOIDPP) mxCalloc(MAX_VAR_DIMS, sizeof(VOIDP));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status == -1)	{
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		n = 0;
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			length += recsizes[i];
			n += (recsizes[i] / nctypelen(datatype));
		}
		
		if (Count(prhs[3]) < n)	{
			status = -1;
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		if ((value = (VOIDP) mxCalloc((int) length, sizeof(char))) == NULL)	{
			status = -1;
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		p = value;
		for (i = 0; i < nrecvars; i++)	{
			datap[i] = p;
			p += recsizes[i];
		}
		
		p = (char *) value;
		pr = mxGetPr(prhs[3]);
		
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
		
			length = recsizes[i] / nctypelen(datatype);
			if (autoscale)	{
				addoffset = Add_Offset(cdfid, recvarids[i]);
				scalefactor = Scale_Factor(cdfid, recvarids[i]);
				if (scalefactor == 0.0)	{
					scalefactor = 1.0;
				}
			}
			Convert(opcode, datatype, length, (VOIDP) p,  scalefactor, addoffset, pr);
			pr += length;
			p += recsizes[i];
		}
		
		status = ncrecput(cdfid, recnum, datap);
		
		plhs[0] = Int2Scalar(status);
		
		Free ((VOIDPP) & value);
		Free ((VOIDPP) & datap);
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;
		
	case RECGET:
		
		recnum = Scalar2Long(prhs[2]);
		
		autoscale = (nrhs > 3 && Scalar2Int(prhs[3]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		datap = (VOIDPP) mxCalloc(MAX_VAR_DIMS, sizeof(VOIDP));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status == -1)	{
			Free ((VOIDPP) & recsizes);
			Free ((VOIDPP) & recvarids);
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		if (nrecvars == 0)	{
			Free ((VOIDPP) & recsizes);
			Free ((VOIDPP) & recvarids);
			plhs[0] = mxCreateFull(0, 0, REAL);
			break;
		}
		
		length = 0;
		n = 0;
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			length += recsizes[i];
			n += (recsizes[i] / nctypelen(datatype));
		}
		
		if ((value = (VOIDP) mxCalloc((int) length, sizeof(char))) == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		if (value == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		p = value;
		for (i = 0; i < nrecvars; i++)	{
			datap[i] = p;
			p += recsizes[i];
		}
		
		if ((status = ncrecget(cdfid, recnum, datap)) == -1)	{
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		m = 1;
		
		plhs[0] = mxCreateFull(m, n, REAL);
		
		if (plhs[0] == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		pr = mxGetPr(plhs[0]);
		p = (char *) value;
		
		for (i = 0; i < nrecvars; i++)	{
			status = ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			if (status == -1)	{
				plhs[1] = Int2Scalar(status);
				break;
			}
			length = recsizes[i] / nctypelen(datatype);
			if (autoscale)	{
				addoffset = Add_Offset(cdfid, recvarids[i]);
				scalefactor = Scale_Factor(cdfid, recvarids[i]);
				if (scalefactor == 0.0)	{
					scalefactor = 1.0;
				}
			}
			Convert(opcode, datatype, length, (VOIDP) p,  scalefactor, addoffset, pr);
			pr += length;
			p += recsizes[i];
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free ((VOIDPP) & value);
		Free ((VOIDPP) & datap);
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;

	case RECINQ:
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status != -1)	{
			for (i = 0; i < nrecvars; i++)	{
				ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
				datatype = RepairBadDataType(datatype);
			
				recsizes[i] /= nctypelen(datatype);
			}
			m = 1;
			n = nrecvars;
			plhs[0] = Int2Mat(recvarids, m, n);
			plhs[1] = Long2Mat(recsizes, m, n);
		}
		
		plhs[2] = Int2Scalar(status);
		
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;
		
	case TYPELEN:
	
		datatype = (nc_type) Parameter(prhs[1]);
		
		len = nctypelen(datatype);
		
		plhs[0] = Int2Scalar(len);
		plhs[1] = Int2Scalar((len >= 0) ? 0 : 1);
		
		break;
		
	case SETFILL:
	
		fillmode = Scalar2Int(prhs[1]);
		
		status = ncsetfill(cdfid, fillmode);
		
		plhs[0] = Int2Scalar(status);
		plhs[1] = Int2Scalar(0);
		
		break;

	case SETOPTS:
		
		plhs[0] = Int2Scalar(ncopts);
		plhs[1] = Int2Scalar(0);
		ncopts = Scalar2Int(prhs[1]);
		
		break;
		
	case ERR:
	
		plhs[0] = Int2Scalar(ncerr);
		ncerr = 0;
		plhs[1] = Int2Scalar(0);
		
		break;
		
	case PARAMETER:
	
		if (nrhs > 1)	{
			plhs[0] = Int2Scalar(Parameter(prhs[1]));
			plhs[1] = Int2Scalar(0);
		}
		else	{
			i = 0;
			while (strcmp(parms[i].name, "NONE") != 0)	{
				mexPrintf("%12d %s\n", parms[i].code, parms[i].name);
				i++;
			}
			plhs[0] = Int2Scalar(0);
			plhs[1] = Int2Scalar(-1);
		}
		
		break;
		
	default:
	
		break;
	}
	
	return;
}
Exemple #13
0
MNCAPI int
minc_load_data(char *path, void *dataptr, int datatype,
               long *ct, long *cz, long *cy, long *cx,
               double *dt, double *dz, double *dy, double *dx,
               void **infoptr)
{
    int fd;                     /* MINC file descriptor */
    nc_type nctype;             /* netCDF type */
    char *signstr;              /* MI_SIGNED or MI_UNSIGNED */
    int length;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i, j;                   /* Generic loop counters */
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    int icv;                    /* MINC image conversion variable */
    long start[MI_S_NDIMS];
    long count[MI_S_NDIMS];
    size_t ucount[MI_S_NDIMS];
    int dir[MI_S_NDIMS];        /* Dimension "directions" */
    int map[MI_S_NDIMS];        /* Dimension mapping */
    int old_ncopts;             /* For storing the old state of ncopts */
    double *p_dtmp;
    long *p_ltmp;
    struct file_info *p_file;
    struct att_info *p_att;
    int r;                      /* Generic return code */
    
    *infoptr = NULL;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }

    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
            var_id = ncvarid(fd, minc_dimnames[i]);
            ncattinq(fd, var_id, MIstep, &nctype, &length);

            switch (i) {
            case MI_S_T:
                p_ltmp = ct;
                p_dtmp = dt;
                break;
            case MI_S_X:
                p_ltmp = cx;
                p_dtmp = dx;
                break;
            case MI_S_Y:
                p_ltmp = cy;
                p_dtmp = dy;
                break;
            case MI_S_Z:
                p_ltmp = cz;
                p_dtmp = dz;
                break;
            default:
                return (MINC_STATUS_ERROR);
            }
                
            if (nctype == NC_DOUBLE && length == 1) {
                ncattget(fd, var_id, MIstep, p_dtmp);
            }
            else {
                *p_dtmp = 0;    /* Unknown/not set */
            }
            *p_ltmp = dim_len[i];
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    var_id = ncvarid(fd, MIimage);

    ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

    if (var_ndims != 3 && var_ndims != 4) {
        return (MINC_STATUS_ERROR);
    }

    /* We want the data to wind up in t, x, y, z order. */

    for (i = 0; i < MI_S_NDIMS; i++) {
        map[i] = -1;
    }

    for (i = 0; i < var_ndims; i++) {
        if (var_dims[i] == dim_id[MI_S_T]) {
            map[MI_S_T] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_X]) {
            map[MI_S_X] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Y]) {
            map[MI_S_Y] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Z]) {
            map[MI_S_Z] = i;
        }
    }

    icv = miicv_create();

    minc_simple_to_nc_type(datatype, &nctype, &signstr);
    miicv_setint(icv, MI_ICV_TYPE, nctype);
    miicv_setstr(icv, MI_ICV_SIGN, signstr);
    miicv_attach(icv, fd, var_id);

    for (i = 0; i < var_ndims; i++) {
        start[i] = 0;
    }

    for (i = 0; i < MI_S_NDIMS; i++) {
        if (map[i] >= 0) {
            count[map[i]] = dim_len[i];
        }
    }

    r = miicv_get(icv, start, count, dataptr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    if (map[MI_S_T] >= 0) {
        if (*dt < 0) {
            dir[MI_S_T] = -1;
            *dt = -*dt;
        }
        else {
            dir[MI_S_T] = 1;
        }
    }

    if (map[MI_S_X] >= 0) {
        if (*dx < 0) {
            dir[MI_S_X] = -1;
            *dx = -*dx;
        }
        else {
            dir[MI_S_X] = 1;
        }
    }

    if (map[MI_S_Y] >= 0) {
        if (*dy < 0) {
            dir[MI_S_Y] = -1;
            *dy = -*dy;
        }
        else {
            dir[MI_S_Y] = 1;
        }
    }

    if (map[MI_S_Z] >= 0) {
        if (*dz < 0) {
            dir[MI_S_Z] = -1;
            *dz = -*dz;
        }
        else {
            dir[MI_S_Z] = 1;
        }
    }

    if (var_ndims == 3) {
        for (i = 1; i < MI_S_NDIMS; i++) {
            map[i-1] = map[i];
            dir[i-1] = dir[i];
        }
    }

    j = 0;
    for (i = 0; i < MI_S_NDIMS; i++) {
        if (dim_len[i] > 0) {
            ucount[j++] = dim_len[i];
        }
    }

    restructure_array(var_ndims, dataptr, ucount, nctypelen(nctype),
                      map, dir);

    miicv_detach(icv);
    miicv_free(icv);

    old_ncopts =get_ncopts();
    set_ncopts(0);

    /* Generate the complete infoptr array.
     * This is essentially an in-memory copy of the variables and attributes
     * in the file.
     */

    p_file = (struct file_info *) malloc(sizeof (struct file_info));

    ncinquire(fd, &p_file->file_ndims, &p_file->file_nvars,
              &p_file->file_natts, NULL);

    p_file->file_atts = (struct att_info *) malloc(sizeof (struct att_info) * 
                                                   p_file->file_natts);

    p_file->file_vars = (struct var_info *) malloc(sizeof (struct var_info) *
                                                   p_file->file_nvars);

    for (i = 0; i < p_file->file_natts; i++) {
        p_att = &p_file->file_atts[i];

        ncattname(fd, NC_GLOBAL, i, p_att->att_name);
        ncattinq(fd, NC_GLOBAL, 
                 p_att->att_name, 
                 &p_att->att_type, 
                 &p_att->att_len);

        p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));

        ncattget(fd, NC_GLOBAL, p_att->att_name, p_att->att_val);
    }

    for (i = 0; i < p_file->file_nvars; i++) {
        struct var_info *p_var = &p_file->file_vars[i];

        ncvarinq(fd, i, 
                 p_var->var_name, 
                 &p_var->var_type, 
                 &p_var->var_ndims, 
                 p_var->var_dims,
                 &p_var->var_natts);

        p_var->var_atts = malloc(p_var->var_natts *
                                 sizeof (struct att_info));

        if (ncdimid(fd, p_var->var_name) >= 0) {
            /* It's a dimension variable, have to treat it specially... */
        }

        for (j = 0; j < p_var->var_natts; j++) {
            p_att = &p_var->var_atts[j];

            ncattname(fd, i, j, p_att->att_name);
            ncattinq(fd, i, 
                     p_att->att_name, 
                     &p_att->att_type, 
                     &p_att->att_len);

            p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));
            ncattget(fd, i, p_att->att_name, p_att->att_val);
        }
    }

    *infoptr = p_file;

    set_ncopts(old_ncopts);

    miclose(fd);

    return (MINC_STATUS_OK);
}
Exemple #14
0
int ex_get_init (int   exoid,
                 char *title,
                 int  *num_dim,
                 int  *num_nodes,
                 int  *num_elem, 
                 int  *num_elem_blk,
                 int  *num_node_sets,
                 int  *num_side_sets)
{
  int dimid;
  long lnum_dim, lnum_nodes, lnum_elem, lnum_elem_blk, lnum_node_sets; 
  long lnum_side_sets;
  char errmsg[MAX_ERR_LENGTH];
  int title_len;
  nc_type title_type;

  exerrval = 0; /* clear error code */

  if (ncattinq (exoid, NC_GLOBAL, ATT_TITLE, &title_type, &title_len) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to inquire title in file id %d", exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }

  /* Check title length to avoid overrunning clients memory space;
     include trailing null */
  if (title_len > MAX_LINE_LENGTH+1) {
    sprintf(errmsg,
            "Error: Title is too long (%d characters) in file id %d",
            title_len-1, exoid);
    exerrval = -1;
    ex_err("ex_get_init",errmsg,exerrval);
    return (EX_FATAL);
  }
  /* printf("[ex_get_init] title length: %d\n",title_len); */

  if (ncattget (exoid, NC_GLOBAL, ATT_TITLE, title) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to get title in file id %d", exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }

    
  /* printf("[ex_get_init] title: %s\n",title); */


  if ((dimid = ncdimid (exoid, DIM_NUM_DIM)) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to locate number of dimensions in file id %d",
              exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }

  if (ncdiminq (exoid, dimid, (char *) 0, &lnum_dim) == -1)
    {
      exerrval = ncerr;
      sprintf(errmsg,
              "Error: failed to get number of dimensions in file id %d",
              exoid);
      ex_err("ex_get_init",errmsg,exerrval);
      return (EX_FATAL);
    }
  *num_dim = lnum_dim;


  /* Handle case with zero-nodes */
  if ((dimid = ncdimid (exoid, DIM_NUM_NODES)) == -1) {
    *num_nodes = 0;
  } else {
     
    if (ncdiminq (exoid, dimid, (char *) 0, &lnum_nodes) == -1)
      {
        exerrval = ncerr;
        sprintf(errmsg,
                "Error: failed to get number of nodes in file id %d",
                exoid);
        ex_err("ex_get_init",errmsg,exerrval);
        return (EX_FATAL);
      }
    *num_nodes = lnum_nodes;
  }
   
  if ((dimid = ncdimid (exoid, DIM_NUM_ELEM)) == -1) {
    *num_elem = 0;
  } else {
    if (ncdiminq (exoid, dimid, (char *) 0, &lnum_elem) == -1)
      {
        exerrval = ncerr;
        sprintf(errmsg,
                "Error: failed to get number of elements in file id %d",
                exoid);
        ex_err("ex_get_init",errmsg,exerrval);
        return (EX_FATAL);
      }
    *num_elem = lnum_elem;
  }


  if (*num_elem > 0) {
    if ((dimid = ncdimid (exoid, DIM_NUM_EL_BLK)) == -1)
      {
        exerrval = ncerr;
        sprintf(errmsg,
                "Error: failed to locate number of element blocks in file id %d",
                exoid);
        ex_err("ex_get_init",errmsg,exerrval);
        return (EX_FATAL);
      }

    if (ncdiminq (exoid, dimid, (char *) 0, &lnum_elem_blk) == -1)
      {
        exerrval = ncerr;
        sprintf(errmsg,
                "Error: failed to get number of element blocks in file id %d",
                exoid);
        ex_err("ex_get_init",errmsg,exerrval);
        return (EX_FATAL);
      }
    *num_elem_blk = lnum_elem_blk;
  } else {
    *num_elem_blk = 0;
  }


  /* node sets are optional */
  if ((dimid = ncdimid (exoid, DIM_NUM_NS)) == -1)
    *num_node_sets = 0;
  else
    {
      if (ncdiminq (exoid, dimid, (char *) 0, &lnum_node_sets) == -1)
        {
          exerrval = ncerr;
          sprintf(errmsg,
                  "Error: failed to get number of node sets in file id %d",
                  exoid);
          ex_err("ex_get_init",errmsg,exerrval);
          return (EX_FATAL);
        }
      *num_node_sets = lnum_node_sets;
    }

  /* side sets are optional */
  if ((dimid = ncdimid (exoid, DIM_NUM_SS))  == -1)
    *num_side_sets = 0;
  else
    {
      if (ncdiminq (exoid, dimid, (char *) 0, &lnum_side_sets) == -1)
        {
          exerrval = ncerr;
          sprintf(errmsg,
                  "Error: failed to get number of side sets in file id %d",
                  exoid);
          ex_err("ex_get_init",errmsg,exerrval);
          return (EX_FATAL);
        }
      *num_side_sets = lnum_side_sets;
    }

  return (EX_NOERR);
}
Exemple #15
0
static int
test3(struct testinfo *ip, struct dimdef *dims, int ndims)
{
  /* Try to read the data back. */
  size_t total;
  long coords[3];
  long lengths[3];
  void *buf_ptr;
  int *int_ptr;
  int i, j, k;
  int stat;
  
  int varid;
  int att_length;
  nc_type att_datatype;
  char *att;

  total = 1;
  for (i = 0; i < ndims; i++) {
    total *= dims[i].length;
  }

  buf_ptr = malloc(total * sizeof (int));

  if (buf_ptr == NULL) {
    fprintf(stderr, "Oops, malloc failed\n");
    return (-1);
  }

  coords[TST_X] = 0;
  coords[TST_Y] = 0;
  coords[TST_Z] = 0;
  lengths[TST_X] = dims[TST_X].length;
  lengths[TST_Y] = dims[TST_Y].length;
  lengths[TST_Z] = dims[TST_Z].length;

  stat = mivarget(ip->fd, ip->imgid, coords, lengths, NC_INT, MI_SIGNED, 
                  buf_ptr);
  if (stat < 0) {
    FUNC_ERROR("mivarget");
  }

  int_ptr = (int *) buf_ptr;
  for (i = 0; i < dims[TST_X].length; i++) {
    for (j = 0; j < dims[TST_Y].length; j++) {
      for (k = 0; k < dims[TST_Z].length; k++) {
        int tmp = (i * 10000) + (j * 100) + k;
        if (*int_ptr != tmp) {
          fprintf(stderr, "1. Data error at (%d,%d,%d)\n", i,j,k);
          errors++;
        }
        int_ptr++;
      }
    }
  }
  free(buf_ptr);

  
  varid = ncvarid(ip->fd, "test");
  if(varid<0)
    FUNC_ERROR("ncvarid");

  if ((ncattinq(ip->fd, varid, "test", &att_datatype, &att_length) == MI_ERROR) ||
        (att_datatype != NC_CHAR))
    FUNC_ERROR("ncattinq");

  if(att_length!=ip->attribute_size)
    FUNC_ERROR("Wrong attribute length!");

  att=malloc(att_length);

  if(miattgetstr(ip->fd, varid, "test", att_length, att)==NULL)
    FUNC_ERROR("miattgetstr");

  if(memcmp(att,ip->large_attribute,att_length)!=0)
    FUNC_ERROR("Attribute contents mismath!");

  free(att);
  
  return (0);
}
Exemple #16
0
/*
 * TODO, lots of declared, but unused variables here
 */
static void do_netcdfquery_proc(Widget, XtPointer, XtPointer)
{
    int setno, src;
    char xvar[256], yvar[256];
    char buf[256], fname[512];
    XmString xms;
    XmString *s, cs;
    int *pos_list;
    int i, j, pos_cnt, cnt;
    char *cstr;

    int cdfid; /* netCDF id */
    int ndims, nvars, ngatts, recdim;
    int var_id;
    long start[2];
    long count[2];
    char varname[256];
    nc_type datatype = 0;
    int dim[100], natts;
    long dimlen[100];
    long len;

    int x_id, y_id;
    nc_type xdatatype = 0;
    nc_type ydatatype = 0;
    int xndims, xdim[10], xnatts;
    int yndims, ydim[10], ynatts;
    long nx, ny;

    int atlen;
    char attname[256];
    char atcharval[256];

    extern int ncopts;

    ncopts = 0; /* no crash on error */

    set_wait_cursor();

    strcpy(fname, xv_getstr(netcdf_file_item));

    if ((cdfid = ncopen(fname, NC_NOWRITE)) == -1)
    {
        errwin("Can't open file.");
        goto out2;
    }
    if (XmListGetSelectedPos(netcdf_listx_item, &pos_list, &pos_cnt))
    {
        XtVaGetValues(netcdf_listx_item,
                      XmNselectedItemCount, &cnt,
                      XmNselectedItems, &s,
                      NULL);
        cs = XmStringCopy(*s);
        if (XmStringGetLtoR(cs, charset, &cstr))
        {
            strcpy(xvar, cstr);
            XtFree(cstr);
        }
        XmStringFree(cs);
    }
    else
    {
        errwin("Need to select X, either variable name or INDEX");
        goto out1;
    }
    if (XmListGetSelectedPos(netcdf_listy_item, &pos_list, &pos_cnt))
    {
        XtVaGetValues(netcdf_listy_item,
                      XmNselectedItemCount, &cnt,
                      XmNselectedItems, &s,
                      NULL);
        cs = XmStringCopy(*s);
        if (XmStringGetLtoR(cs, charset, &cstr))
        {
            strcpy(yvar, cstr);
            XtFree(cstr);
        }
        XmStringFree(cs);
    }
    else
    {
        errwin("Need to select Y");
        goto out1;
    }
    if (strcmp(xvar, "INDEX") == 0)
    {
        stufftext("X is the index of the Y variable\n", STUFF_START);
    }
    else
    {
        if ((x_id = ncvarid(cdfid, xvar)) == -1)
        {
            char ebuf[256];
            sprintf(ebuf, "do_query(): No such variable %s for X", xvar);
            errwin(ebuf);
            goto out1;
        }
        ncvarinq(cdfid, x_id, NULL, &xdatatype, &xndims, xdim, &xnatts);
        ncdiminq(cdfid, xdim[0], NULL, &nx);
        sprintf(buf, "X is %s, data type %s \t length [%d]\n", xvar, getcdf_type(xdatatype), nx);
        stufftext(buf, STUFF_TEXT);
        sprintf(buf, "\t%d Attributes:\n", xnatts);
        stufftext(buf, STUFF_TEXT);
        for (i = 0; i < xnatts; i++)
        {
            atcharval[0] = 0;
            ncattname(cdfid, x_id, i, attname);
            ncattinq(cdfid, x_id, attname, &datatype, &atlen);
            switch (datatype)
            {
            case NC_CHAR:
                ncattget(cdfid, x_id, attname, (void *)atcharval);
                break;
            }
            sprintf(buf, "\t\t%s: %s\n", attname, atcharval);
            stufftext(buf, STUFF_TEXT);
        }
    }
    if ((y_id = ncvarid(cdfid, yvar)) == -1)
    {
        char ebuf[256];
        sprintf(ebuf, "do_query(): No such variable %s for Y", yvar);
        errwin(ebuf);
        goto out1;
    }
    ncvarinq(cdfid, y_id, NULL, &ydatatype, &yndims, ydim, &ynatts);
    ncdiminq(cdfid, ydim[0], NULL, &ny);
    sprintf(buf, "Y is %s, data type %s \t length [%d]\n", yvar, getcdf_type(ydatatype), ny);
    stufftext(buf, STUFF_TEXT);
    sprintf(buf, "\t%d Attributes:\n", ynatts);
    stufftext(buf, STUFF_TEXT);
    for (i = 0; i < ynatts; i++)
    {
        atcharval[0] = 0;
        ncattname(cdfid, y_id, i, attname);
        ncattinq(cdfid, y_id, attname, &datatype, &atlen);
        switch (datatype)
        {
        case NC_CHAR:
            ncattget(cdfid, y_id, attname, (void *)atcharval);
            break;
        }
        sprintf(buf, "\t\t%s: %s\n", attname, atcharval);
        stufftext(buf, STUFF_TEXT);
    }

out1:
    ;
    ncclose(cdfid);

out2:
    ;
    stufftext("\n", STUFF_STOP);
    unset_wait_cursor();
}
int main(int argc, char *argv[])
{
   char *pname;
   char *filename, *tempfile, *newfile;
   char string[1024];
   char *variable_name, *attribute_name;
   int created_tempfile;
   int done_redef;
   int iatt;
   int mincid, varid;
   int variable_exists, attribute_exists;
   nc_type attribute_type, new_type;
   int attribute_length, new_length;
   void *new_value;
   int total_length, alloc_length, ival;
   char *zeros;
   int old_ncopts;

   /* Parse the command line */
   pname=argv[0];
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) {
      (void) fprintf(stderr, "\nUsage: %s [<options>] <file.mnc>\n", 
                     pname);
      (void) fprintf(stderr,   "       %s [-help]\n\n", pname);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];

   /* Create temp file name. First try looking for minc extension, then
      a compression extension. Chop off the unwanted extension. */
   (void) strncpy(string, filename, sizeof(string)-1);
   tempfile = strstr(string, MINC_EXTENSION);
   if (tempfile != NULL) {
      tempfile += strlen(MINC_EXTENSION);
      if (*tempfile == '\0')
         tempfile = NULL;
   }
   else {
      tempfile = strstr(string, GZIP_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, BZIP_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, BZIP2_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, COMPRESS_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, PACK_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, ZIP_EXTENSION);
   }
   if (tempfile != NULL) {
      *tempfile = '\0';
      tempfile = string;
   }

   /* If tempfile == NULL, then either we have a minc file or we don't know 
      how to edit the file in place. Check that it is a minc file. */
   if (tempfile == NULL) {
      newfile = miexpand_file(filename, tempfile, TRUE, &created_tempfile);
      if (created_tempfile) {
         if (newfile != NULL) {
            (void) remove(newfile);
            free(newfile);
         }
         (void) fprintf(stderr, "Cannot edit file \"%s\" in place.\n",
                        filename);
         exit(EXIT_FAILURE);
      }
   }

   /* Expand the file. */
   newfile = miexpand_file(filename, tempfile, FALSE, &created_tempfile);
   if (newfile == NULL) {
      (void) fprintf(stderr, "Error decompressing file \"%s\"\n",
                     filename);
      exit(EXIT_FAILURE);
   }

   /* If a new file was created, get rid of the old one */
   if (created_tempfile) {
      (void) remove(filename);
   }

   /* Open the file */
   mincid = miopen(newfile, NC_WRITE);

   /* Loop through attribute list, modifying values */
   done_redef = FALSE;
   ncopts = NC_VERBOSE;
   zeros = NULL;
   alloc_length = 0;
   for (iatt=0; iatt < attribute_list_size; iatt++) {

      /* Get variable and attribute name */
      variable_name = attribute_list[iatt].variable;
      attribute_name = attribute_list[iatt].attribute;

      /* Check for attribute existence */
      if (strlen(variable_name) == 0) {
         varid = NC_GLOBAL;
         variable_exists = TRUE;
      }
      else {
         old_ncopts = ncopts; ncopts = 0;
         varid = ncvarid(mincid, variable_name);
         ncopts = old_ncopts;
         variable_exists = (varid != MI_ERROR);
      }
      attribute_type = NC_CHAR;
      attribute_length = 0;
      if (variable_exists) {
         old_ncopts = ncopts; ncopts = 0;
         attribute_exists = 
            (ncattinq(mincid, varid, attribute_name,
                      &attribute_type, &attribute_length) != MI_ERROR);
         ncopts = old_ncopts;
      }
      else
         attribute_exists = FALSE;

      /* Are we inserting or deleting? */
      switch (attribute_list[iatt].action) {
      case Insert_attribute:
      case Append_attribute:
         if (attribute_list[iatt].value != NULL) {
            new_type = NC_CHAR;
            new_length = strlen(attribute_list[iatt].value)+1;
            new_value = (void *) attribute_list[iatt].value;
         }
         else {
            new_type = NC_DOUBLE;
            new_length = attribute_list[iatt].num_doubles;
            new_value = (void *) attribute_list[iatt].double_values;
         }

         /* For append we have to copy the entire attribute, if it 
          * already exists.
          */
         if (attribute_list[iatt].action == Append_attribute &&
             attribute_exists) {
             char *tmp_value;

             /* Verify that the existing type matches the newly
              * requested type.  Don't allow a -dappend on a 
              * string attribute, for example.
              */
             if (new_type != attribute_type) {
                 fprintf(stderr, 
                         "Can't append %s data to %s attribute %s:%s.\n",
                         (new_type == NC_DOUBLE) ? "double" : "string",
                         (attribute_type == NC_DOUBLE) ? "double" : "string",
                         variable_name, attribute_name);
                 exit(EXIT_FAILURE);
             }

             new_type = attribute_type;
             tmp_value = malloc((attribute_length + new_length) * nctypelen(new_type));
             ncattget(mincid, varid, attribute_name, tmp_value);

             /* For string attributes, remove any trailing null
              * character before appending.
              */
             if (new_type == NC_CHAR && tmp_value[attribute_length-1] == 0) {
                 attribute_length--;
             }

             memcpy(tmp_value + attribute_length * nctypelen(new_type),
                    new_value,
                    new_length * nctypelen(new_type));
             new_length += attribute_length;
             new_value = (void *) tmp_value;
         }

         total_length = attribute_length*nctypelen(attribute_type);
         if (!attribute_exists ||
             (total_length < new_length*nctypelen(new_type))) {
            if (! done_redef) {
               done_redef = TRUE;
               (void) ncredef(mincid);
            }
         }
         else if (!done_redef && attribute_exists && (total_length > 0)) {
            if (total_length > alloc_length) {
               if (zeros != NULL) free(zeros);
               zeros = malloc(total_length);
               alloc_length = total_length;
               for (ival=0; ival < alloc_length; ival++)
                  zeros[ival] = '\0';
            }
            (void) ncattput(mincid, varid, attribute_name, NC_CHAR,
                            total_length, zeros);
            (void) ncsync(mincid);
            
         }
         if (!variable_exists) {
            old_ncopts = ncopts; ncopts = 0;
            varid = micreate_group_variable(mincid, variable_name);
            ncopts = old_ncopts;
            if (varid == MI_ERROR) {
               varid = ncvardef(mincid, variable_name, NC_INT,
                                0, NULL);
            }
            variable_exists = (varid != MI_ERROR);
         }
         if (variable_exists) {
            (void) ncattput(mincid, varid, attribute_name,
                            new_type, new_length, new_value);
         }

         break;

      case Delete_attribute:

         if (attribute_exists) {
            if (! done_redef) {
               done_redef = TRUE;
               (void) ncredef(mincid);
            }
            (void) ncattdel(mincid, varid, attribute_name);
         }
              
         break;

      default:
          (void) fprintf(stderr, "Program error: unknown action %d\n",
                         (int) attribute_list[iatt].action);
          exit(EXIT_FAILURE);
      }

   }
   ncopts = NC_VERBOSE | NC_FATAL;

   /* Close the file */
   (void) miclose(mincid);

   /* Free stuff */
   free(newfile);
   if (zeros != NULL) free(zeros);

   exit(EXIT_SUCCESS);
}