/*
  ----------------------------------------------------------------------------
  |    Copyright (c) 1999  Emergent IT Inc.  and Raytheon Systems Company    |
  |                                                                          |
  |  Permission to use, modify, and distribute this software and its         |
  |  documentation for any purpose without fee is hereby granted, provided   |
  |  that the above copyright notice appear in all copies and that both that |
  |  copyright notice and this permission notice appear in supporting        |
  |                          documentation.                                  |
  ----------------------------------------------------------------------------
*/


#include <HE5_HdfEosDef.h>
#include <ease.h>
#include <math.h>

#define	HE5_GRIDOFFSET 671088642    /* (2**26)*10 + 2  */
#define HE5_NGRID            400
#define HE5_NGRIDREGN        512
#define M_PI1           3.14159265358979323846
#define SQUARE(x)       ((x) * (x))   /* x**2 */

char    HE5_GDXSDname[HE5_HDFE_NAMBUFSIZE];
char    HE5_GDXSDdims[HE5_HDFE_DIMBUFSIZE];

/* Grid Structure External Arrays */
struct HE5_gridStructure 
{
  hid_t     fid;                      /* HDF-EOS file ID                   */
  hid_t     obj_id;                   /* "GRIDS" group ID                  */
  hid_t     gd_id;                    /* one grid group ID                 */
  hid_t     data_id;                  /* "Data Fields" group ID            */
  hid_t     plist;                    /* current dataset creation property */

  HE5_DTSinfo  *ddataset;             /* Ptr to dataset info structure     */
  
  int       compparm[5];              /* compression level                 */
  int 	    active;                   /* Flag: if file is active or not    */
  int  	    tilecode;                 /* tile/no-tile flag                 */
  int  	    tilerank;                 /* rank of a dataset to tile         */
  
  long      nDFLD;                    /* number of data fields             */
  
  hsize_t   tiledims[HE5_DTSETRANKMAX];/* dimension sizes of tiled dataset */
  
  char      gdname[HE5_OBJNAMELENMAX]; /* grid name                        */
  char      compmethod[HE5_HDFE_NAMBUFSIZE];/* compression method          */
};

struct HE5_gridStructure HE5_GDXGrid[HE5_NGRID];


struct HE5_gridRegion
{
  hid_t     fid;
  hid_t	    gridID;
  
  double    upleftpt[2];
  double    lowrightpt[2];
  
  long 	    xStart;
  long 	    xCount;
  long 	    yStart;
  long 	    yCount;
  long      somStart;
  long      somCount;
  long	    StartVertical[HE5_DTSETRANKMAX];
  long 	    StopVertical[HE5_DTSETRANKMAX];
  
  char 	    *DimNamePtr[HE5_DTSETRANKMAX];
};

struct HE5_gridRegion *HE5_GDXRegion[HE5_NGRIDREGN];

/* Grid Function Prototypes (internal routines)  */
/* --------------------------------------------- */

static size_t HE5_GDfielddatasize(hid_t gridID, const char *fieldname );
static herr_t HE5_GDgetfieldID(hid_t gridID, const char *fieldname, hid_t *fieldID);
static herr_t HE5_GDchkgdid(hid_t gridID, const char *routname, hid_t *fid, hid_t *gid, long *idx );
static herr_t HE5_GDwrrdfield(hid_t gridID, const char *fieldname, char *code,const hssize_t start[], const hsize_t stride[], const hsize_t  edge[], void *datbuf);
static herr_t HE5_GDtangentpnts(int, double[], double[], double[], double[], double[], long *);
herr_t HE5_GDgetdefaults(int projcode, int zonecode, double projparm[], int spherecode, double upleftpt[], double lowrightpt[]);
static int HE5_GDfldnameinfo(hid_t gridID, const char *fieldname, char *fldactualname);
herr_t HE5_GDll2mm_cea(int projcode,int zonecode, int spherecode, double projparm[], long xdimsize, long ydimsize, double upleftpt[], double lowrightpt[], long npnts, double lon[], double lat[], double x[], double y[], double *scaleX, double *scaleY);
herr_t HE5_GDmm2ll_cea(int projcode,int zonecode, int spherecode, double projparm[], long xdimsize, long ydimsize, double  upleftpt[], double lowrightpt[], long npnts, double x[], double  y[], double longitude[], double latitude[]);
int HE5_szip_can_encode(void );
void HE5_GDgetEastAndNorthFiles(char *eastFile, char *northFile);

static herr_t HE5_GDflddiminfo(hid_t gridID, char *fieldname, int *rank,  hsize_t dims[], hsize_t maxdims[]);
static herr_t HE5_GDupdatedim(hid_t gridhID,  char *dimname, hsize_t dim);

/* FORTRAN wrappers */
/* ================ */

/* File/Grid access routine */

int HE5_GDopenF(char *filename, int Flags);
int HE5_GDcreateF(int fileID, char *gridname, long xdimsize, long ydimsize, double upleftpt[], double lowrightpt[]);
int HE5_GDattachF(int fileID, char *gridname);
int HE5_GDdetachF(int gridID);
int HE5_GDcloseF(int fileID);


/* Definition routines */

int HE5_GDdefdimF(int gridID,  char *dimname, long dim);
int HE5_GDdefprojF(int gridID, int projcode, int zonecode,  int spherecode, double projparm[]);
int HE5_GDdeforiginF(int gridID, int origincode);
int HE5_GDdeffld(int gridID, char *fieldname, char *fortdimlist, char *fortmaxdimlist, int ntype, int merge);
int HE5_GDsetfill(int gridID, char *fieldname, int ntype, void *fillval);
int HE5_GDdefcompF(int gridID, int compcode, int compparm[]);
int HE5_GDdeftileF(int gridID, int tilecode, int tilerank, long *tiledims);
int HE5_GDdefcomtileF(int gridID, int compcode, int compparm[], int tilerank, long *tiledims );
int HE5_GDdefpixregF(int gridID, int pixregcode);
int HE5_GDsetaliasF(int gridID, char *fieldname, char *fortaliaslist);
int HE5_GDdropaliasF(int gridID, int fldgroup, char *aliasname);


/* I/O routines */

int HE5_GDwrfld(int gridID, char *fieldname, long fortstart[], long fortstride[], long fortedge[], void *data);
int HE5_GDwrcharfld(int gridID, char *fieldname, int elemlen, int numelem, long fortstart[], long fortstride[], long fortedge[], void *data);
int HE5_GDrdfld(int gridID, char *fieldname, long fortstart[], long fortstride[], long fortedge[], void *buffer);
int HE5_GDrdcharfld(int gridID, char *fieldname, int elemlen, int numelem, long fortstart[], long fortstride[], long fortedge[], void *buffer);
int HE5_GDgetfill(int gridID, char *fieldname, void *fillval);
int HE5_GDwrattr(int gridID, char *attrname, int ntype, long fortcount[], void *datbuf);
int HE5_GDwrgattr(int gridID, char *attrname, int ntype, long fortcount[], void *datbuf);
int HE5_GDwrlattr(int gridID, char *fieldname, char *attrname, int ntype,long fortcount[], void *datbuf);
int HE5_GDrdattr(int gridID, char *attrname, void *datbuf);
int HE5_GDrdgattr(int gridID, char *attrname, void *datbuf);
int HE5_GDrdlattr(int gridID, char *fieldname, char *attrname, void *datbuf);



/* Inquiry routines */

long HE5_GDinqdimsF(int gridID, char *dimnames, long dims[]);
long HE5_GDdiminfoF(int gridID, char *dimname);
int HE5_GDinqflds(int gridID, char *fieldlist, int rank[], int ntype[]);
int HE5_GDfldinfo(int gridID, char *fieldname, int *rank, long dims[], int *ntype, char *fortdimlist, char *fortmaxdimlist); 
int HE5_GDinqdatatypeF(int gridID, char *fieldname, char *attrname, int fieldgroup, int *type, int *TypeClass, int *TypeOrder, long *TypeSize); 
long HE5_GDinqgridF(char *filename, char *gridlist, long *strbufsize);
int HE5_GDgridinfoF(int gridID, long *xdimsize, long *ydimsize, double upleftpt[], double lowrightpt[]);
int HE5_GDatinfo(int gridID, char *attrname, int *ntype, long *fortcount);
int HE5_GDgatinfo(int gridID, char *attrname, int *ntype, long *fortcount);
int HE5_GDlatinfo(int gridID, char *fieldname, char *attrname, int *ntype, long *fortcount);
int HE5_GDatinfo2(int gridID, char *attrname, int *ntype, long *fortcount, long *fortsize);
int HE5_GDgatinfo2(int gridID, char *attrname, int *ntype, long *fortcount, long *fortsize);
int HE5_GDlatinfo2(int gridID, char *fieldname, char *attrname, int *ntype, long *fortcount, long *fortsize);
int HE5_GDprojinfoF(int gridID, int *projcode,  int *zonecode, int *spherecode, double projparm[]);
int HE5_GDorigininfoF(int gridID, int *origincode);
int HE5_GDreginfo(int gridID, int regionID, char *fieldname, int *ntype, int *rank, long dims[], long  *size, double upleftpt[], double lowrightpt[]);
int HE5_GDpixreginfoF(int gridID, int *pixregcode);
int HE5_GDcompinfoF(int gridID, char *fieldname, int *compcode, int compparm[]);
long HE5_GDnentriesF(int gridID, int entrycode, long *strbufsize);
long HE5_GDinqattrsF(int gridID, char *attrnames, long *strbufsize);
long HE5_GDinqgrpattrsF(int gridID, char *attrnames, long *strbufsize);
long HE5_GDinqlocattrsF(int gridID, char *fieldname, char *attrnames, long *strbufsize);
int HE5_GDtileinfoF(int gridID, char *fieldname, int *tilecode, int *tilerank, long tiledims[]);
int HE5_GDaliasinfoF(int gridID, int fldgroup, char *aliasname, int *length, char *buffer);
long HE5_GDinqfldaliasF(int gridID, char *fldalias, long *strbufsize);
long HE5_GDgetaliaslistF(int gridID, int fldgroup, char *aliaslist, long *strbufsize);



/* Subsetting/Retrieving routines */

int HE5_GDdefboxregionF(int gridID, double cornerlon[], double cornerlat[]);
int HE5_GDextractregionF(int gridID, int regionID, char *fieldname, void *buffer);
int HE5_GDdeftimeperiodF(int gridID, int periodID, double starttime, double stoptime);
int HE5_GDdefvrtregionF(int gridID, int regionID, char *vertObj, double range[]);
int HE5_GDdupregionF(int oldregionID);
int HE5_GDgetpixelsF(int gridID, long nLonLat, double lonVal[], double latVal[], long pixRow[], long pixCol[]);
long HE5_GDgetpixvaluesF(int gridID, long nPixels, long pixRow[], long pixCol[], char *fieldname, void *buffer);
long HE5_GDinterpolateF(int gridID, long nValues, double lonVal[], double latVal[], char *fieldname, double interpVal[]);


/* EXTERNAL DATA FILE INTERFACE */

int HE5_GDsetextdataF(int gridID, char *fortfilelist, long offset[], long size[]);
int HE5_GDgetextdataF(int gridID, char *fieldname, long namelength, char *fortfilelist, long offset[], long size[]);


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDopen                                                       |
|                                                                             |
|  DESCRIPTION: Opens or creates HDF file in order to create, read, or write  |
|                a grid.                                                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  fid            hid_t   None        HDF-EOS file ID                         |
|                                                                             |
|  INPUTS:                                                                    |
|  filename       char*   None        Filename                                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A. Muslimov   Changed the return type from int32_t to hid_t.      |
|  7/12/00  A. Muslimov   Unmasked the hdf5 data types.                       |
|  END_PROLOG                                                                 |
  -----------------------------------------------------------------------------*/
hid_t
HE5_GDopen(const char *filename, uintn flags)
{
  hid_t     fid     = FAIL;/* hdf5 type file ID    */ 

  char      *errbuf = NULL;/* Error message buffer */


  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf  = (char *)calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDopen", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory to error buffer.");
      HE5_EHprint("Error: Cannot allocate memory to error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }  

  /* Call EHopen to perform file access */
  /* ---------------------------------- */
  fid = HE5_EHopen(filename,flags, H5P_DEFAULT );
  if(fid == FAIL)
    {
      sprintf(errbuf, "Cannot open the file \"%s\". Check the file name. \n", filename);
      H5Epush(__FILE__, "HE5_GDopen", __LINE__, H5E_FILE, H5E_CANTOPENFILE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }  

  free(errbuf);
  return(fid);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDcreate                                                     |
|                                                                             |
|  DESCRIPTION: Creates a grid within the file.                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  gridID         hid_t   None        Grid structure ID                       |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            hid_t   None        File ID                                 |
|  gridname       char    None        Grid structure name                     |
|  xdimsize       long    None        Number of columns in grid               |
|  ydimsize       long    None        Number of rows in grid                  |
|  upleftpt       double  None        Location (m/deg) of upper left corner   |
|  lowrightpt     double  None        Location (m/deg) of lower right corner  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|             H5Gopen                                                         |
|             H5Gcreate                                                       |
|             H5Gclose                                                        |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A. Muslimov   Replaced gid by fid in the call to EHinsertmeta().  |
|                         Added a statement 'nGrid = ngridopen;' to fix a bug |
|                         associated with grid numbering in StructMetadata.   |
|                         Also,  added the calls gd_id = H5Gcreate( GRIDS_ID, |
|                         gridname, 0). Dynamically allocated memory for      |
|                         buffers.   Replaced the call to EHattrcat() by      |
|                         EHdatasetcat(). Added error hadling after the calls |
|                         to EHinsertmeta() and EHdatasetcat().               |
|  3/29/00  A. Muslimov   Added "Data Fields" group for consistency with the  |
|                         Swath interface.                                    |
|  7/12/00  A. Muslimov   Unmasked the hdf5 data types.                       |
|  Sep  01  A. Muslimov   Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
hid_t 
HE5_GDcreate(hid_t fid, const char *gridname, long xdimsize, long ydimsize, double upleftpt[], double lowrightpt[])
{
  hid_t           gridID    = FAIL;/* grid ID (return value)              */
  hid_t           HDFfid    = FAIL;/* HDF file id                         */
  hid_t           gd_id     = FAIL;/* gridname group ID                   */
  hid_t           GRIDS_ID  = FAIL;/* GRIDS group ID                      */
  hid_t           gid       = FAIL;/* HDF-EOS group ID                    */
  hid_t           data_id   = FAIL;/* "Data Fields" group ID              */
  hid_t           i;		   /* Loop index                          */

  herr_t          status    = FAIL;/* routine status variable             */

  int             ngridopen =  0;  /* # of grid structures opened         */

  long            nGrid     =  0;  /* Grid counter                        */

  char            *errbuf  = (char *)NULL; /* Buffer for error message          */
  char            *utlbuf  = (char *)NULL; /* Utility buffer                    */
  char            *header  = (char *)NULL; /* Structural metadata header string */
  char            *footer  = (char *)NULL; /* Structural metadata footer string */
  char            *refstr1 = (char *)NULL; /* Upper left ref string (metadata)  */
  char            *refstr2 = (char *)NULL; /* Lower right ref string (metadata) */

  uintn           acs      = 777;          /* Read/Write file access code       */

  HE5_LOCK;
  CHECKNAME(gridname);

  errbuf  = (char *)calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char) );
  if (errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /* Allocate memory for buffers */
  /* --------------------------- */
  utlbuf  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if ( utlbuf == NULL )
    {
      sprintf(errbuf, "Cannot allocate memory for buffer.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
   
      return(FAIL);
    }
  header  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if ( header == NULL )
    {
      sprintf(errbuf, "Cannot allocate memory for buffer.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
   
      return(FAIL);
    }
   
  footer  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if ( footer == NULL )
    {
      sprintf(errbuf, "Cannot allocate memory for buffer.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
      free(header);
   
      return(FAIL);
    }

  refstr1 = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if ( refstr1 == NULL )
    {
      sprintf(errbuf, "Cannot allocate memory for buffer.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
      free(header);
      free(footer);
	
      return(FAIL);
    }

  refstr2 = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if ( refstr1 == NULL )
    {
      sprintf(errbuf, "Cannot allocate memory for buffer.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
      free(header);
      free(footer);
      free(refstr1);
	
      return(FAIL);
    }

  /*
**********************************************************
*  Check for proper file ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and access code               *  
**********************************************************
*/
  status = HE5_EHchkfid(fid,"HE5_GDcreate", &HDFfid, &gid, &acs);
  /* Check file access */
  /* -------------------------- */
  if ( acs == 0 )
    {
      status = FAIL;
      sprintf(errbuf, "Cannot call HE5_GDcreate on a file opened read-only.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for file ID failed.\n");
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
      free(header);
      free(footer);
      free(refstr1);
      free(refstr2);
	
      return(FAIL);
    }
 

  /* Check gridname for length */
  /* ------------------------- */
  if ( strlen(gridname) > HE5_OBJNAMELENMAX)
    {
      status = FAIL;
      sprintf(errbuf, "Gridname \"%s\" must be less than %d characters.\n", gridname, HE5_OBJNAMELENMAX);
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_FILE, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }


  /* Determine number of grids currently opened */
  /* ------------------------------------------- */
  for (i = 0; i < HE5_NGRID; i++)
    ngridopen += HE5_GDXGrid[i].active;
	
  /* Setup file interface */
  /* -------------------- */
  if (ngridopen < HE5_NGRID)
    {
      /* Probe , check if GRIDS group exists */
      /* ----------------------------------- */
      H5E_BEGIN_TRY {
	GRIDS_ID = H5Gopen(gid, "GRIDS");
      }
      H5E_END_TRY;
		
      if(GRIDS_ID == FAIL )
	{
	  nGrid = 0;         
			
	  /* Create the "GRIDS" group */
	  /* ------------------------ */
	  GRIDS_ID = H5Gcreate(gid,"GRIDS",0);
	  if ( GRIDS_ID == FAIL )
	    {
	      sprintf(errbuf, "Cannot create \"GRIDS\" group.\n");
	      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (errbuf  != NULL)  free(errbuf);
	      if (utlbuf  != NULL)  free(utlbuf);
	      if (header  != NULL)  free(header);
	      if (footer  != NULL)  free(footer);
	      if (refstr1 != NULL)  free(refstr1);
	      if (refstr2 != NULL)  free(refstr2);

	      return( FAIL );
	    }
			

	}
      /* Group "GRIDS" exists */
      else
	{
	  /* Probe , check if gridname group exists */
	  /* -------------------------------------- */
	  H5E_BEGIN_TRY{
	    gd_id = H5Gopen(GRIDS_ID, gridname);
	  }
	  H5E_END_TRY;
			
	  if( gd_id == FAIL )
	    {
	      /* Get the number of grids in "GRIDS" group */
	      /* ---------------------------------------- */
	      nGrid = HE5_EHdatasetcat(fid, "/HDFEOS/GRIDS", NULL,  NULL);
	      if (nGrid == FAIL )
		{
		  sprintf(errbuf,"Cannot retrieve the number of grids.");
		  H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  H5Gclose(GRIDS_ID);

		  if (errbuf  != NULL)  free(errbuf);
		  if (utlbuf  != NULL)  free(utlbuf);
		  if (header  != NULL)  free(header);
		  if (footer  != NULL)  free(footer);
		  if (refstr1 != NULL)  free(refstr1);
		  if (refstr2 != NULL)  free(refstr2);
					  
		  return(FAIL);
		}

	    }
	  else
	    {
	      sprintf(errbuf, "Grid \"%s\" already exists.", gridname);
	      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_BTREE, H5E_EXISTS, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      H5Gclose(GRIDS_ID);

	      if (errbuf  != NULL)  free(errbuf);
	      if (utlbuf  != NULL)  free(utlbuf);
	      if (header  != NULL)  free(header);
	      if (footer  != NULL)  free(footer);
	      if (refstr1 != NULL)  free(refstr1);
	      if (refstr2 != NULL)  free(refstr2);

	      return(FAIL);
	    }

	}

      /* gridname does not exist */
      /* ----------------------- */
	      
      /* Create gridname group */
      /* --------------------- */
      gd_id = H5Gcreate( GRIDS_ID, gridname, 0);
      if ( gd_id == FAIL )
	{
	  sprintf(errbuf, "Cannot create \"%s\" group.\n", gridname);
	  H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (errbuf  != NULL)  free(errbuf);
	  if (utlbuf  != NULL)  free(utlbuf);
	  if (header  != NULL)  free(header);
	  if (footer  != NULL)  free(footer);
	  if (refstr1 != NULL)  free(refstr1);
	  if (refstr2 != NULL)  free(refstr2);

	  return( FAIL );
	}
		
		
      /* Create "gridname/Data Fields" group */
      /* ----------------------------------- */
      data_id = H5Gcreate( gd_id, "Data Fields", 0);
      if ( data_id == FAIL )
	{
	  sprintf(errbuf, "Cannot create \"Data Fields\" group.\n");
	  H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (errbuf  != NULL)  free(errbuf);
	  if (utlbuf  != NULL)  free(utlbuf);
	  if (header  != NULL)  free(header);
	  if (footer  != NULL)  free(footer);
	  if (refstr1 != NULL)  free(refstr1);
	  if (refstr2 != NULL)  free(refstr2);

	  return( FAIL );
	}
		
		
		
      /* Establish Grid in Structural MetaData Block */
      /* -------------------------------------------- */
      sprintf(header, "%s%li%s%s%s%s%li%s%s%li%s",
	      "\tGROUP=GRID_", nGrid + 1,
	      "\n\t\tGridName=\"", gridname, "\"\n",
	      "\t\tXDim=", xdimsize, "\n",
	      "\t\tYDim=", ydimsize, "\n");
		
      sprintf(footer,
	      "%s%s%s%s%s%s%s%li%s",
	      "\t\tGROUP=Dimension\n",
	      "\t\tEND_GROUP=Dimension\n",
	      "\t\tGROUP=DataField\n",
	      "\t\tEND_GROUP=DataField\n",
	      "\t\tGROUP=MergedFields\n",
	      "\t\tEND_GROUP=MergedFields\n",
	      "\tEND_GROUP=GRID_", nGrid + 1, "\n");


      /* Build Ref point Col-Row strings */
      /* ------------------------------- */
      if ( upleftpt == NULL || ( upleftpt[0] == 0 && upleftpt[1] == 0 && lowrightpt[0] == 0 && lowrightpt[1] == 0))
	{
	  strcpy(refstr1, "DEFAULT");
	  strcpy(refstr2, "DEFAULT");
	}
      else
	{
	  sprintf(refstr1, "%s%lf%s%lf%s","(", upleftpt[0], ",", upleftpt[1], ")");		 
	  sprintf(refstr2, "%s%lf%s%lf%s", "(", lowrightpt[0], ",", lowrightpt[1], ")");
	}
		
      sprintf(utlbuf, "%s%s%s%s%s%s%s%s", header, "\t\tUpperLeftPointMtrs=", refstr1, "\n","\t\tLowerRightMtrs=", refstr2, "\n",footer);
		
      /* Insert record to SM dataset */
      /* --------------------------- */
      status = HE5_EHinsertmeta(fid, (char*)gridname, "g", 1002L, utlbuf, NULL);
      if (status == FAIL )
	{
	  sprintf(errbuf,"Cannot insert metadata.");
	  H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);  
	  H5Gclose(GRIDS_ID);

	  if (errbuf  != NULL)  free(errbuf);
	  if (utlbuf  != NULL)  free(utlbuf);
	  if (header  != NULL)  free(header);
	  if (footer  != NULL)  free(footer);
	  if (refstr1 != NULL)  free(refstr1);
	  if (refstr2 != NULL)  free(refstr2);
		  
	  return(FAIL);
	}
		

      /* Release "GRIDS" group ID */
      /* ------------------------ */		
      status = H5Gclose(GRIDS_ID);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot close \"GRIDS\" group.\n");
	  H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_OHDR, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);

	  if (errbuf  != NULL)  free(errbuf);
	  if (utlbuf  != NULL)  free(utlbuf);
	  if (header  != NULL)  free(header);
	  if (footer  != NULL)  free(footer);
	  if (refstr1 != NULL)  free(refstr1);
	  if (refstr2 != NULL)  free(refstr2);
		  
	  return( FAIL );
	}
		
		
      /* Set up entries in external Table */
      /* -------------------------------- */
      for (i = 0; i < HE5_NGRID; i++)
	{
	  if (HE5_GDXGrid[ i ].active == 0)
	    {
	      gridID                        = i + HE5_GRIDOFFSET;
	      HE5_GDXGrid[ i ].active           = 1;
	      HE5_GDXGrid[ i ].fid              = fid;
	      HE5_GDXGrid[ i ].gd_id            = gd_id;
	      HE5_GDXGrid[ i ].data_id          = data_id;
	      HE5_GDXGrid[ i ].obj_id           = GRIDS_ID;
	      HE5_GDXGrid[ i ].plist            = FAIL;
	      HE5_GDXGrid[ i ].tilecode         = HE5_HDFE_NOTILE;
	      strcpy(HE5_GDXGrid[ i ].gdname, gridname);
	      strcpy(HE5_GDXGrid[ i ].compmethod,"HE5_HDFE_COMP_NONE");
	      break;
	    }
			
	}
		
    }
  else
    {
      /* Too many files opened */
      /* --------------------- */
      gridID = FAIL;
      sprintf(errbuf, "No more than %d grids may be opened simutaneously.\n", HE5_NGRID);
      H5Epush(__FILE__, "HE5_GDcreate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
	
  /* Deallocate memory */
  /* ----------------- */
  if (errbuf  != NULL)  free(errbuf);
  if (utlbuf  != NULL)  free(utlbuf);
  if (header  != NULL)  free(header);
  if (footer  != NULL)  free(footer);
  if (refstr1 != NULL)  free(refstr1);
  if (refstr2 != NULL)  free(refstr2);
    
  utlbuf  = NULL;
  header  = NULL;
  footer  = NULL;
  refstr1 = NULL;
  refstr2 = NULL;
  errbuf  = NULL;

 COMPLETION:
  HE5_UNLOCK;
  return(gridID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDattach                                                     |
|                                                                             |
|  DESCRIPTION: Attaches to an existing grid within the file.                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            hid_t   None        HDF-EOS file id                         |
|  gridname       char*   None        grid sructure name                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Gopen                                                         |
|             H5Giterate                                                      |
|             H5Dopen                                                         |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/24/99  A.Muslimov    Added proper error handling after function calls.   |
|                         Removed redundant if(status==0){} brackets.         |
|                         In the block if( inout.name != NULL){} changed the  |
|                         statement before the last one from                  |
|                            "if(inout.name==NULL) free(inout.name);" onto    |
|                            "if(inout.name!=NULL) free(inout.name);"         |
|                         Changed the datatype of idx from int32_t to int.    |
| 10/18/99  A.Muslimov    Replaced memcpy() by memmove() to avoid a problem   |
|                         when arguments 1 and 2 overlap in memory.           |
| 10/18/99  A.Taaheri     Replaced strcpy() by memmove() to avoid a problem   |
|                         when arguments 1 and 2 overlap in memory.           |
| 01/21/00  A.Muslimov    Reset the value of "tilecode" to HDFE_NOTILE in     |
|                         external array.                                     |
| 02/24/00  A.Muslimov    Added more error checkings and cleanings.           |
| 03/29/00  A.Muslimov    Added attaching to the "Data Fields" group.         |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| Sep   01  A. Muslimov   Added mutex "lock"/"unlock" calls.                  |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
hid_t
HE5_GDattach(hid_t fid, const char *gridname)
{
  hid_t           gridID    = FAIL;	/* Return value of the Grid ID    */
  hid_t           HDFfid    = FAIL;	/* HDF-EOS file ID                */
  hid_t           datid     = FAIL;	/* dataset ID                     */
  hid_t           infogid   = FAIL;	/* "HDFEOS" group ID              */
  hid_t           gd_id     = FAIL;	/* Grid group ID                  */
  hid_t           data_id   = FAIL;	/* "Data Fields" Group ID         */
  hid_t           i;			/* Loop index                     */
  hid_t           emptyslot = FAIL;	/* "empty" grid index             */

  herr_t          status    = FAIL;	/* routine return status variable */

  int             ngridopen = 0;        /* no. of grid structures opened  */
  int             idx       = FAIL;	/* Object index                   */

  uintn           acs       = 777;	/* Read/Write file access code    */
 
  HE5_OBJINFO     inout;	        /* IN/OUT data of the operation   */

  char            *grpname = (char *)NULL; /* Grid group name string  */
  char            *errbuf  = (char *)NULL; /* Error message buffer    */
  char            *namebuf = (char *)NULL; /* Name list buffer        */
  char            *fldname = (char *)NULL; /* Dataset name buffer     */
  char            *comma   = (char *)NULL; /* Pointer to the comma    */


  HE5_LOCK;
  CHECKPOINTER(gridname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory to error buffer.");
      HE5_EHprint("Error: Cannot allocate memory to error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /*
**********************************************************
*  Check for proper file ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and access code               *  
**********************************************************
*/
  status = HE5_EHchkfid(fid, "HE5_GDattach", &HDFfid, &infogid, &acs);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(FAIL);
    }

  /* Determine number of grids currently opened */
  /* ------------------------------------------ */ 
  for (i = 0; i < HE5_NGRID; i++)
    ngridopen += HE5_GDXGrid[ i ].active;

  if (ngridopen < HE5_NGRID)
    {
      /* Allocate memory to the "HDFEOS/GRIDS/gridname" buffer */
      grpname = (char *)calloc( (strlen(gridname)+40), sizeof(char));
      if(grpname == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory to the grpname.\n");
	  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
		  
	  return(FAIL);
	}

      strcpy( grpname, "/HDFEOS/GRIDS/");
      strcat( grpname, gridname);

      /* Try to open the Grid group */
      /* ========================== */
      H5E_BEGIN_TRY{
	gd_id = H5Gopen(HDFfid,grpname);
      }
      H5E_END_TRY;

      if( gd_id == FAIL )
	{  
	  sprintf(errbuf, "Grid:\"%s\" does not exist within HDF file.",gridname) ;
	  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if(grpname != NULL) free(grpname);
	  free(errbuf);

	  return(FAIL);
	}


      /* Try to open the "Data Fields" group */
      /* =================================== */
      H5E_BEGIN_TRY{
	data_id = H5Gopen(gd_id,"Data Fields");
      }
      H5E_END_TRY;

      if( data_id == FAIL )
	{  
	  sprintf(errbuf, "Group \"Data Fields\" does not exist in \"%s\" grid.",gridname) ;
	  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if(grpname != NULL) free(grpname);
	  free(errbuf);

	  return(FAIL);
	}



      /* Setup External Arrays */
      /* ===================== */
      for (i = 0; i < HE5_NGRID; i++)
	{
	  /* Find empty entry in array of grids */
	  /* ---------------------------------- */
	  if (HE5_GDXGrid[ i ].active == 0)
	    {
	      /* Set IDs, Flags, and  Codes */
	      /* -------------------------- */
	      HE5_GDXGrid[ i ].active           = 1;
	      HE5_GDXGrid[ i ].fid              = fid;
	      HE5_GDXGrid[ i ].gd_id            = gd_id;
	      HE5_GDXGrid[ i ].data_id          = data_id;              
	      HE5_GDXGrid[ i ].plist            = FAIL;
	      HE5_GDXGrid[ i ].tilecode         = HE5_HDFE_NOTILE;
	      strcpy(HE5_GDXGrid[ i ].compmethod,"HE5_HDFE_COMP_NONE");
	      gridID                            = i + HE5_GRIDOFFSET;
	      strcpy(HE5_GDXGrid[ i ].gdname, gridname);
	      break;
	    }
	}

      emptyslot = i;

		
      /* Get the number of OBJECTS within the "Data Fields"  group */
      /* ========================================================= */ 
      inout.count   = 0;
      inout.name    = NULL;
      inout.strsize = 0;

      strcat( grpname, "/Data Fields");
      idx = H5Giterate(data_id, grpname , NULL, HE5_EHobj_info, &inout);
      if (idx == FAIL )
	{
	  sprintf(errbuf, "Cannot get information about \"Data Fields\" group.\n");
	  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  if (grpname != NULL) free(grpname);
		   
	  return(FAIL);
	}
      if(grpname != NULL) free(grpname);

      /* Set the data members of external structure */
      /* ========================================== */   
      HE5_GDXGrid[ emptyslot ].nDFLD = inout.count;


      /*--------------------------------------------------*/
      /* Loop through all datasets and open them          */
      /*          Allocate space for namebuf,             */
      /*   copy inout.name into it, append comma, etc.    */
      /*--------------------------------------------------*/
      if( inout.name != NULL && inout.count > 0 )
	{

	  /* Allocate memory to "ddataset" struct */
	  HE5_GDXGrid[emptyslot].ddataset = (HE5_DTSinfo *)realloc((void *)HE5_GDXGrid[emptyslot].ddataset,(HE5_GDXGrid[emptyslot].nDFLD) * sizeof(HE5_DTSinfo));
	  if(HE5_GDXGrid[ emptyslot ].ddataset == NULL)
	    {
	      sprintf(errbuf, "Cannot allocate memory to the ddataset structure.\n");
	      H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		       
	      return(FAIL);
	    }

	  /* Allocate memory to the name list buffer */
	  namebuf = (char *) calloc(strlen(inout.name) + 2, sizeof(char));
	  if(namebuf == NULL)
	    {
	      sprintf(errbuf, "Cannot allocate memory to the name list buffer.\n");
	      H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);

	      return(FAIL);
	    }

	  strcpy(namebuf, inout.name);
	  strcat(namebuf, ",");

	  /* Find comma */
	  comma = strchr(namebuf, ',');

	  i = 0;

	  /* Loop through entries in name list */
	  /* ================================= */
	  while (comma != NULL)
	    {
	      /* Copy field list entry to fldname */
	      fldname = (char *) calloc(comma - namebuf + 1, sizeof(char));
	      if(fldname == NULL)
		{
		  sprintf(errbuf, "Cannot allocate memory to fldname.\n");
		  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(namebuf);
		       
		  return(FAIL);
		}
	      memmove(fldname, namebuf, comma - namebuf);
	      fldname[comma - namebuf] = 0;

	      /* Open the dataset */
	      /* ================ */
	      datid = H5Dopen(data_id, fldname);		   
	      if ( datid == FAIL)
		{
		  sprintf(errbuf, "Cannot open the dataset \"%s\" .\n", fldname);
		  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(namebuf);
		  free(fldname);
		       
		  return(FAIL);
		}

	      /*allocate memory to the dataset name*/
	      HE5_GDXGrid[ emptyslot ].ddataset[ i ].name = (char *) calloc((strlen(fldname)+1), sizeof(char) );
	      if(HE5_GDXGrid[ emptyslot ].ddataset[ i ].name == NULL)
		{
		  sprintf(errbuf, "Cannot allocate memory to the dataset name.\n");
		  H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(namebuf);
		  free(fldname);

		  return(FAIL);
		}

	      /* Set the data members of external structure */
	      /* ========================================== */   
	      HE5_GDXGrid[ emptyslot ].ddataset[ i ].ID = datid;
	      strcpy(HE5_GDXGrid[ emptyslot ].ddataset[ i ].name, fldname);

				
	      /* Go to the next dataset/field entry */
	      /* ================================== */  
	      memmove(namebuf, comma + 1, strlen(comma)-1);
	      namebuf[strlen(comma)-1] = 0;
	      comma = strchr(namebuf, ',');
	      if (fldname != NULL) free(fldname);
	      i++;
				
	    }

	  if (namebuf != NULL) 
	    {
	      free(namebuf);
	      namebuf = NULL;
	    }
	  if(inout.name != NULL )
	    {
	      free( inout.name);
	      inout.name = NULL;
	    }
		   
	} /* end 'if(name!==NULL)' */

    }
  else
    {
      /* Too many Grids opened */
      gridID = FAIL;
      sprintf(errbuf, "No more than %d grids may be open simultaneously", HE5_NGRID);
      H5Epush(__FILE__, "HE5_GDattach", __LINE__, H5E_FILE, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  if (errbuf != NULL) free(errbuf);
  
 COMPLETION:    
  HE5_UNLOCK;
  return(gridID);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDchkgdid                                                    |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        hdf5  type grid  ID                     |
|  routname       char    None        Name of routine calling GDchkgdid       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fid            hid_t   None        HDF-EOS file ID                         |
|  gid            hid_t   None        "HDFEOS" group ID                       |
|  idx            long    None        Grid index                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/30/99  A.Muslimov    Added error handlings after the function calls.     |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static herr_t   
HE5_GDchkgdid(hid_t gridID, const char *routname, hid_t *fid, hid_t *gid, long *idx )
{
  herr_t          status     = SUCCEED;/* routine return status variable */
  
  uintn           access     = 777;    /* Read/Write file access code    */
  
  hid_t           HDFfid     = FAIL;   /* HDF-EOS file ID                */
  
  long            idOffset   = HE5_GRIDOFFSET;/* HDF-EOS Grid ID offset  */
  
  char            message1[] = "Invalid grid id: %d in routine \"%s\".  ID must be >= %d and < %d.\n";
  char            message2[] = "Grid id %d in routine \"%s\" not active.\n";
					       char            errbuf[HE5_HDFE_ERRBUFSIZE];
  
  /*
*******************************
*  Check for proper grid ID   *   
*******************************
*/ 
  if (gridID < idOffset || gridID >= HE5_NGRID + idOffset)
    {
      status = FAIL;
      sprintf(errbuf, message1, gridID, routname, idOffset, HE5_NGRID + idOffset);
      H5Epush(__FILE__, "HE5_GDchkgdid", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
	
    }
  else
    {
      /* Check for active grid ID */
      /* ------------------------- */
      if (HE5_GDXGrid[gridID % idOffset].active == 0)
        {
	  status = FAIL;
	  sprintf(errbuf,  message2, gridID, routname);
	  H5Epush(__FILE__, "HE5_GDchkgdid", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf) ;
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
        }
      else
        {
          /* Get Grid index */
          /* -------------- */
	  *idx = HE5_EHhid2long(gridID) % idOffset;
	  if ( *idx == FAIL)
	    {
	      status = FAIL;
	      sprintf(errbuf, "Cannot get the Grid index \n");
	      H5Epush(__FILE__, "HE5_GDchkgdid", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf) ;
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }

	  /* Get HDF-EOS file ID and "HDFEOS" group ID */
	  /* ----------------------------------------- */
	  *fid = HE5_GDXGrid[ *idx ].fid;
	  status = HE5_EHchkfid(*fid,"", &HDFfid, gid, &access);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Checking for file ID failed.\n");
	      H5Epush(__FILE__,"HE5_GDchkgdid", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
	    
        }
    }
  
  return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefdim                                                     |
|                                                                             |
|  DESCRIPTION: Defines a new dimension within the grid.                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  dimname        char*   None        Dimension name to define                |
|  dim            hsize_t   None      Dimemsion value                         |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/20/99  A.Muslimov    In the call to EHinsertmeta() replaced the argument |
|                         gid by fid.                                         |
|  9/27/99  A.Muslimov    Added proper error handlings. Removed redundant     |
|                         if(status == 0){} brackets.                         |
|  1/06/00  A.Muslimov    Changed the datatype of "dim" from int32_t to       |
|                         hsize_t to make a call to EHinsertmeta() successfull|
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDdefdim(hid_t gridID, char *dimname, hsize_t dim)
{
  herr_t       status  = FAIL;        /* routine return status variable */
  
  hid_t        gid     = FAIL;        /* "HDFEOS" group ID              */
  hid_t        fid     = FAIL;        /* HDF-EOS file ID                */
  
  long         idx     = FAIL;        /* Grid index                     */
  
  char         *errbuf = (char *)NULL;/* Buffer for error message       */
  
  HE5_LOCK;
  CHECKNAME(dimname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefdim", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/  
  status = HE5_GDchkgdid(gridID, "HE5_GDdefdim", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefdim", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  /* Insert Dimension value to Structural MetaData */
  /* --------------------------------------------- */
  status = HE5_EHinsertmeta(fid, HE5_GDXGrid[idx].gdname, "g", 0L, dimname, &dim);
  if (status == FAIL )
    {
      status = FAIL;
      sprintf(errbuf,"Cannot insert metadata.");
      H5Epush(__FILE__, "HE5_GDdefdim", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(errbuf);
  errbuf = NULL;

 COMPLETION:  
  HE5_UNLOCK;
  return(status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefproj                                                    |
|                                                                             |
|  DESCRIPTION: Defines projection of grid.                                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units       Description                           |
|  ============   ======    =========   ===================================== |
|  status         herr_t    None        return status (0) SUCCEED, (-1) FAIL  |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t     None        HDF-EOS type grid  ID                 |
|  projcode       int                   GCTP projection code                  |
|  zonecode       int                   UTM zone code                         |
|  spherecode     int                   GCTP spheriod code                    |
|  projparm       double                Projection parameters                 |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    In the call to EHinsertmeta() replaced the argument |
|                         gid by fid. Added error handling after the call to  |
|                         EHinsertmeta().                                     |
|  4/19/00  A.Muslimov    Changed 'slen' type from long to size_t.            |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDdefproj(hid_t gridID, int projcode, int zonecode,  int spherecode, double projparm[])
{
  herr_t          status   = FAIL;      /* routine return status variable  */  

  int             i;                    /* Loop index                      */
  
  hid_t           fid      = FAIL;      /* HDF-EOS file ID                 */
  hid_t           gid      = FAIL;      /* Grid group ID                   */
  
  long            idx      = FAIL;      /* Grid index                      */

  size_t          slen     = 0;             /* String length               */
  
  char            *utlbuf  = (char *)NULL;    /* Utility Buffer            */
  char            projparmbuf[HE5_HDFE_UTLBUFSIZE];/* Projection parameter */
  char            *GCTPproj[128] = {"HE5_GCTP_GEO","HE5_GCTP_UTM","HE5_GCTP_SPCS",
				    "HE5_GCTP_ALBERS","HE5_GCTP_LAMCC","HE5_GCTP_MERCAT",
				    "HE5_GCTP_PS","HE5_GCTP_POLYC","HE5_GCTP_EQUIDC",
				    "HE5_GCTP_TM","HE5_GCTP_STEREO", "HE5_GCTP_LAMAZ",
				    "HE5_GCTP_AZMEQD", "HE5_GCTP_GNOMON","HE5_GCTP_ORTHO", 
				    "HE5_GCTP_GVNSP","HE5_GCTP_SNSOID","HE5_GCTP_EQRECT",
				    "HE5_GCTP_MILLER","HE5_GCTP_VGRINT","HE5_GCTP_HOM",
				    "HE5_GCTP_ROBIN","HE5_GCTP_SOM","HE5_GCTP_ALASKA",
				    "HE5_GCTP_GOOD", "HE5_GCTP_MOLL","HE5_GCTP_IMOLL", 
				    "HE5_GCTP_HAMMER","HE5_GCTP_WAGIV","HE5_GCTP_WAGVII",
				    "HE5_GCTP_OBLEQA"/*,"HE5_GCTP_CEA","HE5_GCTP_BCEA",
				    "HE5_GCTP_ISINUS"*/};/* GCTP projection codes    */
  char            *errbuf = (char *)NULL;     /* Buffer for error message */
  
  HE5_LOCK;

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefproj", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /* Allocate memory for utility buffer */
  /* ---------------------------------- */
  utlbuf  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlbuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDdefproj", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  
  /* Add "non-standard" GCTP codes */
  /* ----------------------------- */
  GCTPproj[ 97 ] = (char *)calloc( (strlen("HE5_GCTP_CEA")+ 1),  sizeof(char) );
  if(GCTPproj[ 97 ] == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDdefproj", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);

      return(FAIL);
    }
  strcpy(GCTPproj[97], "HE5_GCTP_CEA");
 
  GCTPproj[ 98 ] = (char *)calloc( (strlen("HE5_GCTP_BCEA")+ 1),  sizeof(char) );
  if(GCTPproj[ 98 ] == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDdefproj", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
      free(GCTPproj[97]);

      return(FAIL);
    }
  strcpy(GCTPproj[98], "HE5_GCTP_BCEA");

 

  GCTPproj[ 99 ] = (char *)calloc( (strlen("HE5_GCTP_ISINUS") + 1), sizeof(char) );
  if(GCTPproj[ 99 ] == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDdefproj", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlbuf);
      free(GCTPproj[97]);
      free(GCTPproj[98]);
	
      return(FAIL);
    }
  strcpy(GCTPproj[99], "HE5_GCTP_ISINUS");
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/    
  status = HE5_GDchkgdid(gridID, "HE5_GDdefproj", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /*
       * If projection not GEO, UTM, or State Code build projection
       * parameter string
       */
      if (projcode != HE5_GCTP_GEO &&  projcode != HE5_GCTP_UTM && projcode != HE5_GCTP_SPCS)
        {

	  /* Begin projection parameter list with "(" */
	  strcpy(projparmbuf, "(");

	  /* Add each projection parameter to string */
	  for (i = 0; i < 13; i++)
            {
	      /* If projparm[i] = 0 ... */
	      if (projparm[i] == 0.0)
                {
		  strcpy(utlbuf, "0,");
                }
	      else
                {
		  /* if projparm[i] is integer ... */
		  if ( ((long)projparm[ i ]) == projparm[ i ])
		    {
		      sprintf(utlbuf, "%li%s", (long)projparm[ i ], ",");
		    }
		  /* else if projparm[i] is between 0 and 1 ... */
		  else if ((i == 1) && (projparm[1] > 0) && (projparm[1] < 1))
		    {
		      sprintf(utlbuf, "%g%s", projparm[i], ",");
		    }
		  else
		    {
		      sprintf(utlbuf, "%lf%s", projparm[i], ",");
		    }
                }
	      strcat(projparmbuf, utlbuf);
            }
	  slen = strlen(projparmbuf);

	  /* Add trailing ")" */
	  projparmbuf[slen - 1] = ')';
        }


      /* Build metadata string */
      /* --------------------- */
      if (projcode == HE5_GCTP_GEO)
        {
	  int spherecode_tmp = 12;
	  sprintf(utlbuf,
		  "%s%s%s%s%d%s", 
		  "\t\tProjection=", GCTPproj[projcode], "\n",
		  "\t\tSphereCode=", spherecode_tmp, "\n");
        }
      else if (projcode == HE5_GCTP_UTM || projcode == HE5_GCTP_SPCS)
        {
	  sprintf(utlbuf,
		  "%s%s%s%s%d%s%s%d%s",
		  "\t\tProjection=", GCTPproj[projcode], "\n",
		  "\t\tZoneCode=", zonecode, "\n",
		  "\t\tSphereCode=", spherecode, "\n");
        }
      else
        {
	  sprintf(utlbuf,
		  "%s%s%s%s%s%s%s%d%s",
		  "\t\tProjection=", GCTPproj[projcode], "\n",
		  "\t\tProjParams=", projparmbuf, "\n",
		  "\t\tSphereCode=", spherecode, "\n");
        }


      /* Insert in structural metadata */
      /* ----------------------------- */
      status = HE5_EHinsertmeta(fid, HE5_GDXGrid[ idx ].gdname, "g", 101L, utlbuf, NULL);
      if (status == FAIL )
	{
	  sprintf(errbuf,"Cannot insert metadata.\n");
	  H5Epush(__FILE__, "HE5_GDdefproj", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(utlbuf);
	  if (GCTPproj[97] != NULL) free(GCTPproj[97]);
	  if (GCTPproj[98] != NULL) free(GCTPproj[98]);
	  if (GCTPproj[99] != NULL) free(GCTPproj[99]);

	  return(FAIL);
	}

    }
  
  free(errbuf);
  free(utlbuf);
  free(GCTPproj[97]);
  free(GCTPproj[98]);
  free(GCTPproj[99]);
  GCTPproj[97] = NULL;
  GCTPproj[98] = NULL;
  GCTPproj[99] = NULL;
  utlbuf = NULL;
  errbuf = NULL;

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDblkSOMoffset                                               |
|                                                                             |
|  DESCRIPTION: Writes Block SOM offset values                                |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  offset         long                Offset values                           |
|  count[]        hsize_t             Number of offset values                 |
|  code           char                w/r code (w/r)                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 00   A.Muslimov    Added more checkings.                               |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDblkSOMoffset(hid_t gridID, long offset[], hsize_t count[], char *code)
{
  herr_t          status   = FAIL;        /* routine return status variable */

  int             projcode = FAIL;        /* GCTP projection code           */
  int             i;                      /* Loop index                     */
  
  hid_t           fid      = FAIL;        /* HDF-EOS file ID                */
  hid_t           gid      = FAIL;        /* "HDFEOS" group ID              */
  
  long            idx      = FAIL;        /* Grid index                     */
    
  double          projparm[13];           /* Projection parameters          */
  
  char            utlbuf[HE5_HDFE_UTLBUFSIZE];/* Utility Buffer             */
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message Buffer       */
  
  HE5_LOCK;
  CHECKPOINTER(offset);
  CHECKPOINTER(count);
  CHECKPOINTER(code);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDblkSOMoffset", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Initialize projection parameters */
      /* -------------------------------- */
      for (i = 0; i < 13; i++)
	projparm[i] = 0.;
	  
      /* Get projection parameters */
      /* ------------------------- */
      status = HE5_GDprojinfo(gridID, &projcode, NULL, NULL, projparm);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot get projection information.\n");
	  H5Epush(__FILE__, "HE5_GDblkSOMoffset", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	
	  return(status);
	}

      /* If SOM projection with projparm[11] non-zero ... */
      /* ------------------------------------------------ */
      if (projcode == HE5_GCTP_SOM && projparm[11] != 0) 
        {
	  sprintf(utlbuf, "%s", "_BLKSOM");

	  /* Write offset values as attribute */
	  if (strcmp(code, "w") == 0)
            {
	      status = HE5_GDwriteattr(gridID, "_BLKSOM", H5T_NATIVE_LONG, count, offset);
	      if ( status == FAIL)
		{
		  sprintf(errbuf, "Cannot write in offset values.\n");
		  H5Epush(__FILE__, "HE5_GDblkSOMoffset", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
	
		  return(status);
		}
            }
	  /* Read offset values from attribute */
	  /* --------------------------------- */
	  else if (strcmp(code, "r") == 0)
            {
	      status = HE5_GDreadattr(gridID, utlbuf, offset);
	      if ( status == FAIL)
		{
		  sprintf(errbuf, "Cannot read out the offset values.\n");
		  H5Epush(__FILE__, "HE5_GDblkSOMoffset", __LINE__, H5E_ATTR, H5E_READERROR, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
	
		  return(status);
		}
            }
        }
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefcomp                                                    |
|                                                                             |
|  DESCRIPTION: Defines compression type and parameters                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  compcode       int                 compression code                        |
|  compparm       int                 compression parameters                  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:   Before calling this function, storage must be CHUNKED             |
|                      Values of compression code                             |
|                         HDFE_COMP_NONE                  0                   |
|                         HDFE_COMP_RLE                   1                   |
|                         HDFE_COMP_NBIT                  2                   |
|                         HDFE_COMP_SKPHUFF               3                   |
|                         HDFE_COMP_DEFLATE               4                   |
|                         HDFE_COMP_SZIP_CHIP             5                   |
|                         HDFE_COMP_SZIP_K13              6                   |
|                         HDFE_COMP_SZIP_EC               7                   |
|                         HDFE_COMP_SZIP_NN               8                   |
|                         HDFE_COMP_SZIP_K13orEC          9                   |
|                         HDFE_COMP_SZIP_K13orNN          10                  |
|                         HDFE_COMP_SHUF_DEFLATE          11                  |
|                         HDFE_COMP_SHUF_SZIP_CHIP        12                  |
|                         HDFE_COMP_SHUF_SZIP_K13         13                  |
|                         HDFE_COMP_SHUF_SZIP_EC          14                  |
|                         HDFE_COMP_SHUF_SZIP_NN          15                  |
|                         HDFE_COMP_SHUF_SZIP_K13orEC     16                  |
|                         HDFE_COMP_SHUF_SZIP_K13orNN     17                  |
|  RLE=Run Length Encoding                                                    |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Pget_layout                                                   |
|             H5Pset_layout                                                   |
|             H5Pset_deflate                                                  |
|             H5Pset_szip                                                     |
|             H5Pset_shuffle                                                  |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  1/18/99  A.Muslimov    Added compcode parameter, and "switch (comcode)"    |
|                         block.                                              |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 06/04/01  A.Muslimov    Added checking for compression code/level.          |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  Aug  03  S.Zhao        Added Szip compression methods.                     |
|  Oct  03  S.Zhao        Added the shuffling method.                         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDdefcomp(hid_t gridID, int compcode, int compparm[])
{
  herr_t          status   = FAIL;/* routine return status variable */

  int             level    = 0;   /* compression level              */
  
  hid_t           fid      = FAIL;/* HDF-EOS file id                */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID              */
  hid_t           (*func)(void*);
    
  void            *edata = (void *)NULL;
  
  long            idx      = FAIL;/* Grid index                     */
  
  H5D_layout_t    layout   = H5D_LAYOUT_ERROR;/* Type of storage    */
  int             can_encode=0;     /* szip encoder presence flag     */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Error message buffer  */

  H5Eget_auto((H5E_auto1_t *)&func,&edata);

  HE5_LOCK;  
  CHECKPOINTER(compparm);

  /* Check if compression code is valid */
  /* ---------------------------------- */
  if( compcode != HE5_HDFE_COMP_DEFLATE && compcode != HE5_HDFE_COMP_NONE && 
      compcode != HE5_HDFE_COMP_SZIP_CHIP && compcode != HE5_HDFE_COMP_SZIP_K13 &&
      compcode != HE5_HDFE_COMP_SZIP_EC && compcode != HE5_HDFE_COMP_SZIP_NN &&
      compcode != HE5_HDFE_COMP_SZIP_K13orEC && compcode != HE5_HDFE_COMP_SZIP_K13orNN &&
      compcode != HE5_HDFE_COMP_SHUF_DEFLATE && compcode != HE5_HDFE_COMP_SHUF_SZIP_CHIP &&
      compcode != HE5_HDFE_COMP_SHUF_SZIP_K13 && compcode != HE5_HDFE_COMP_SHUF_SZIP_EC &&
      compcode != HE5_HDFE_COMP_SHUF_SZIP_NN && compcode != HE5_HDFE_COMP_SHUF_SZIP_K13orEC &&
      compcode != HE5_HDFE_COMP_SHUF_SZIP_K13orNN )
    {
      status = FAIL;
      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Invalid/unsupported compression code. \n");
      HE5_EHprint("Error: Invalid/unsupported compression code, occured", __FILE__, __LINE__);
      return(status);
    }

  if( compcode == HE5_HDFE_COMP_DEFLATE || compcode == HE5_HDFE_COMP_NONE || compcode == HE5_HDFE_COMP_SHUF_DEFLATE)
    {
      /* Check GZIP compression level */
      /* ---------------------------- */
      if( compparm[0] < 0 || compparm[0] > 9)
	{
	  status = FAIL;
	  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Invalid GZIP compression level. \n");
	  HE5_EHprint("Error: Invalid GZIP compression level, occured", __FILE__, __LINE__);
	  return(status);
	}
    }
  else
    {
      /* Check SZIP compression block size */
      /* --------------------------------- */
      if( compparm[0] != 2 && compparm[0] != 4 && compparm[0] != 6 && compparm[0] != 8 &&
	  compparm[0] != 10 && compparm[0] != 12 && compparm[0] != 14 && compparm[0] != 16 &&
	  compparm[0] != 18 && compparm[0] != 20 && compparm[0] != 22 && compparm[0] != 24 &&
	  compparm[0] != 26 && compparm[0] != 28 && compparm[0] != 30 && compparm[0] != 32)
	{
	  status = FAIL;
	  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Invalid SZIP compression block size. \n");
	  HE5_EHprint("Error: Invalid SZIP compression block size, occured", __FILE__, __LINE__);
	  return(status);
	}
    }
  
#ifdef H5_HAVE_FILTER_SZIP
  can_encode = HE5_szip_can_encode();
#endif


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdefcomp", &fid, &gid, &idx);
  if (status == FAIL) 
    {
      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADRANGE, "Checking for grid ID failed.\n");
      HE5_EHprint("Error: Checking for grid ID failed, occured", __FILE__, __LINE__);
      return( status );
    }
  
  /* if current property instance has not been created, report error */
  /* --------------------------------------------------------------- */
  if( HE5_GDXGrid[ idx ].plist == FAIL )
    {
      if (compcode != HE5_HDFE_COMP_NONE)
	{
	  status = FAIL;
	  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_PLIST, H5E_NOTFOUND, "Unable to compress, dataset storage layout has not been set to CHUNKED.");
	  HE5_EHprint("Error: Unable to compress, dataset storage layout has not been set to CHUNKED, occured", __FILE__, __LINE__);
	  return(status);
	}
    }
  else
    {
      layout = H5Pget_layout(HE5_GDXGrid[ idx ].plist);
      if( layout != H5D_CHUNKED )
	{
	  status = H5Pset_layout(HE5_GDXGrid[idx].plist, H5D_CHUNKED);
	  if ( status == FAIL )
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set the layout.\n");
	      HE5_EHprint("Error: Cannot set the layout, occured", __FILE__, __LINE__);
	      return(status );
	    }
	}
	   
      switch(compcode)
	{
	  /* Set NBIT compression parameters in ext. array */
	  /* --------------------------------------------- */
	case HE5_HDFE_COMP_NBIT:
 
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
	  HE5_GDXGrid[ idx ].compparm[ 1 ] = compparm[ 1 ];
	  HE5_GDXGrid[ idx ].compparm[ 2 ] = compparm[ 2 ];
	  HE5_GDXGrid[ idx ].compparm[ 3 ] = compparm[ 3 ];
 
	  break;

	  /* Set compression method to HE5_HDFE_COMP_DEFLATE */
	  /* ----------------------------------------------- */
	case HE5_HDFE_COMP_DEFLATE:

	  level = compparm[0];
	  status = H5Pset_deflate(HE5_GDXGrid[ idx ].plist, level);
	  if ( status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set GZIP compression method.\n");
	      HE5_EHprint("Error: Cannot set GZIP compression method, occured", __FILE__, __LINE__);
	      return(status );
	    }
 
	  /* ------------------------------------------------- */
	  /* Set GZIP compression method and compression       */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_DEFLATE");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];

	  break;

	case HE5_HDFE_COMP_SZIP_CHIP:

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_CHIP_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_CHIP compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_CHIP compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ------------------------------------------------- */
	  /* Set SZIP_CHIP compression method and compression  */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_CHIP");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
 
	case HE5_HDFE_COMP_SZIP_K13:

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_K13 compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_K13 compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ------------------------------------------------- */
	  /* Set SZIP_K13 compression method and compression   */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_K13");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SZIP_EC:

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_EC_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_EC compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_EC compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ------------------------------------------------- */
	  /* Set SZIP_EC compression method and compression    */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_EC");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SZIP_NN:

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_NN_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_NN compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_NN compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ------------------------------------------------- */
	  /* Set SZIP_NN compression method and compression    */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_NN");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SZIP_K13orEC:

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_EC_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_K13orSZIP_EC compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_K13orSZIP_EC compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ------------------------------------------------------- */
	  /* Set SZIP_K13orEC compression method and compression     */
	  /*    parameters in external array                         */
	  /* ------------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_K13orHE5_HDFE_COMP_SZIP_EC");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SZIP_K13orNN:

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_NN_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_K13orSZIP_NN compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_K13orSZIP_NN compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ----------------------------------------------------- */
	  /* Set SZIP_K13orNN compression method and compression   */
	  /*    parameters in external array                       */
	  /* ----------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_K13orHE5_HDFE_COMP_SZIP_NN");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
	  break;

	case HE5_HDFE_COMP_SHUF_DEFLATE:
 
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

	  level = compparm[0];
	  status = H5Pset_deflate(HE5_GDXGrid[ idx ].plist, level);
	  if ( status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set GZIP compression method.\n");
	      HE5_EHprint("Error: Cannot set GZIP compression method, occured", __FILE__, __LINE__);
	      return(status );
	    }
 
	  /* ------------------------------------------------- */
	  /* Set shuffling+GZIP method and compression         */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_DEFLATE");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
	  break;
		  
	case HE5_HDFE_COMP_SHUF_SZIP_CHIP:
		  
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_CHIP_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_CHIP compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_CHIP compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
#endif

	  /* ------------------------------------------------- */
	  /* Set shuffling+SZIP_CHIP method and compression    */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_CHIP");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SHUF_SZIP_K13:
		  
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_K13 compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_K13 compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    } 
#endif

	  /* ------------------------------------------------- */
	  /* Set shuffling+SZIP_K13 method and compression     */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SHUF_SZIP_EC:
		  
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_EC_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_EC compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_EC compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    } 
#endif

	  /* ------------------------------------------------- */
	  /* Set shuffling+SZIP_EC method and compression      */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_EC");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SHUF_SZIP_NN:
		  
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_NN_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_NN compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_NN compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    } 
#endif

	  /* ------------------------------------------------- */
	  /* Set shuffling+SZIP_NN method and compression      */
	  /*    parameters in external array                   */
	  /* ------------------------------------------------- */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_NN");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SHUF_SZIP_K13orEC:
		  
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_EC_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_K13orEC compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_K13orEC compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    } 
#endif
 
	  /* ------------------------------------------------------ */
	  /* Set shuffling+SZIP_K13orEC method and compression      */
	  /*    parameters in external array                        */
	  /* ------------------------------------------------------ */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13orEC");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_SHUF_SZIP_K13orNN:
 
	  status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
	  if (status == FAIL)
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Cannot set the shuffling method. \n");
	      HE5_EHprint("Error: Cannot set the shuffling method, occured", __FILE__, __LINE__);
	      return(status);
	    }

#ifdef H5_HAVE_FILTER_SZIP
	  if(can_encode == 1)
	    {
	      status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_NN_OPTION_MASK,compparm[0]);
	      if ( status == FAIL)
		{
		  H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set SZIP_K13orNN compression method.\n");
		  HE5_EHprint("Error: Cannot set SZIP_K13orNN compression method, occured", __FILE__, __LINE__);
		  return(status );
		}
	    } 
	  else
	    {
	      sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    } 
#endif
		  
	  /* ------------------------------------------------------ */
	  /* Set shuffling+SZIP_K13orNN method and compression      */
	  /*    parameters in external array                        */
	  /* ------------------------------------------------------ */
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13orNN");
	  HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
		  
	  break;
		  
	case HE5_HDFE_COMP_NONE:
		  
	  strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_NONE");
	  HE5_GDXGrid[idx].compparm[0] = compparm[0];
   
	  break;

	default:
	  {
	    status = FAIL;
	    H5Epush(__FILE__, "HE5_GDdefcomp", __LINE__, H5E_ARGS, H5E_BADVALUE, "Compression method is not specified.\n");
	    HE5_EHprint("Error: Compression method is not specified, occured", __FILE__, __LINE__);
	  }
	  break;
		  
	}
	  
    }
  
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeftile                                                    |
|                                                                             |
|  DESCRIPTION: Defines tiling parameters                                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  tilecode       int                 tile code                               |
|  tilerank       int                 number of tiling dimensions             |
|  tiledims       hsize_t             tiling dimensions                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|  None                                                                       |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Pcreate                                                       |
|             H5Pset_layout                                                   |
|             H5Pset_chunk                                                    |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jan 00   A.Muslimov    Changed the datatype of tiledims[] from int32_t to  |
|                         const hsize_t. Added retrieving/creation of the     |
|                         property list. Added setting up of the dataset      |
|                         chunking.                                           |
|  Feb 00   A.Muslimov    Added error checkings.                              |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDdeftile(hid_t gridID, int tilecode, int tilerank, const hsize_t *tiledims)
{

  herr_t          status   = FAIL;          /* routine return status variable */  

  int             i;                        /* Loop index                     */
  
  hid_t           fid      = FAIL;          /* HDF-EOS file id                */
  hid_t           gid      = FAIL;          /* "HDFEOS" group ID              */
  
  long            idx      = FAIL;          /* Grid index                     */
  
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message Buffer         */
  int             temp_tilerank;
  hsize_t         temp_dims[8];

  HE5_LOCK;    
  /*CHECKPOINTER(tiledims);*/

  if (tilerank == 0)
    {
      temp_tilerank = 1;
    }
  else
    {   
      temp_tilerank = tilerank;
    }
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdeftile", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Initialize external array */
      /* ------------------------- */
      for (i = 0; i < HE5_DTSETRANKMAX; i++)
	{
	  HE5_GDXGrid[ idx ].tiledims[ i ] = 0;
	}
	  
      HE5_GDXGrid[ idx ].tilecode = tilecode;

      switch (tilecode)
	{
	case HE5_HDFE_NOTILE:

	  HE5_GDXGrid[idx].tilerank = 0;

	  break;

	case HE5_HDFE_TILE:

	  HE5_GDXGrid[ idx ].tilerank = temp_tilerank;

	  for (i = 0; i < temp_tilerank; i++)
	    {
	      HE5_GDXGrid[ idx ].tiledims[ i ] = tiledims[ i ];

	      if (HE5_GDXGrid[ idx ].tiledims[i] == 0)
		{
		  HE5_GDXGrid[ idx ].tiledims[ i ] = 1;
		}
	    }

	  break;
		  
	default:
	  {
	    sprintf(errbuf, "Unknown tile code.\n");
	    H5Epush(__FILE__, "HE5_GDdeftile", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	  }
	  break;

	}

      /* get the current dataset creation property ID from external array  */
      /* if current property instance has not been created, then create it */
      /* ----------------------------------------------------------------- */
      if( HE5_GDXGrid[idx].plist == FAIL)
	{
	  HE5_GDXGrid[idx].plist = H5Pcreate(H5P_DATASET_CREATE);
	  if ( HE5_GDXGrid[idx].plist == FAIL )
	    {
	      status = FAIL;
	      sprintf(errbuf, "Cannot create the property list.\n");
	      H5Epush(__FILE__, "HE5_GDdeftile", __LINE__, H5E_PLIST, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
			  
	      return(status);
	    }
	}

      /* Set layout */
      /* ---------- */
      status = H5Pset_layout( HE5_GDXGrid[idx].plist, H5D_CHUNKED);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot set the type of storage of the raw data to \"CHUNKED\".\n");
	  H5Epush(__FILE__, "HE5_GDdeftile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	
	  return(status);
	}
       
      /* Set chunking */
      /* ------------ */
      if (tiledims == NULL)
	{
	  for (i = 0; i < temp_tilerank; i++)
	    {
	      temp_dims[ i ] = 1;
	      HE5_GDXGrid[ idx ].tiledims[ i ] = temp_dims[ i ];
	    }
	}
      else
	{
	  for (i = 0; i < temp_tilerank; i++)
	    {
	      temp_dims[ i ] = tiledims[i];
	      HE5_GDXGrid[ idx ].tiledims[ i ] = temp_dims[ i ];
	    }
	}

      status = H5Pset_chunk( HE5_GDXGrid[idx].plist, temp_tilerank, temp_dims); 
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot set the sizes of the chunks.\n");
	  H5Epush(__FILE__, "HE5_GDdeftile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}  
    }
  
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefcomtile                                                 |
|                                                                             |
|  DESCRIPTION: Defines compression type and parameters and sets tiling/      |
|                                                       chunking              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  compcode       int                 compression code                        |
|  compparm[]     int                 compression parameters                  |
|  tilerank       int                 number of tiling dimensions             |
|  tiledims       hsize_t             tiling dimensions                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Pcreate                                                       |
|             H5Pget_layout                                                   |
|             H5Pset_layout                                                   |
|             H5Pset_deflate                                                  |
|             H5Pset_szip                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer    Description                                        |
|  ========  ============  =================================================  |
|  07/24/00  A.Muslimov    Original development.                              |
|  06/04/01  A.Muslimov    Added checking for compression code/level.         |
|  09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                 |
|  Aug  03   S.Zhao        Added Szip compression methods.                    |
|  Oct  03   S.Zhao        Added the shuffling method.                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDdefcomtile(hid_t gridID, int compcode, int compparm[], int tilerank, const hsize_t *tiledims )
{
  herr_t          status   = FAIL;/* routine return status variable */

  int             i;              /* Loop index                     */   

  hid_t           fid      = FAIL;/* HDF-EOS file id                */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID              */
  hid_t           (*func)(void*);

  hsize_t         dims[HE5_DTSETRANKMAX];/* default dimension sizes */
   
  void            *edata = (void *)NULL;
  
  long            idx      = FAIL;/* Grid index                     */
  
  H5D_layout_t    layout   = H5D_LAYOUT_ERROR;/* Type of storage of the raw data */

  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message Buffer  */
  int             can_encode;        /* szip encoder presence flag  */

  H5Eget_auto((H5E_auto1_t *)&func,&edata);
  
  HE5_LOCK;
  CHECKPOINTER(compparm);
  /*CHECKPOINTER(tiledims);*/

  /* Check if compression code is valid */
  /* ---------------------------------- */
  if( compcode != HE5_HDFE_COMP_DEFLATE && compcode != HE5_HDFE_COMP_NONE &&
      compcode != HE5_HDFE_COMP_SZIP_CHIP && compcode != HE5_HDFE_COMP_SZIP_K13 &&
      compcode != HE5_HDFE_COMP_SZIP_EC && compcode != HE5_HDFE_COMP_SZIP_NN &&
      compcode != HE5_HDFE_COMP_SZIP_K13orEC && compcode != HE5_HDFE_COMP_SZIP_K13orNN &&
      compcode != HE5_HDFE_COMP_SHUF_DEFLATE && compcode != HE5_HDFE_COMP_SHUF_SZIP_CHIP &&
      compcode != HE5_HDFE_COMP_SHUF_SZIP_K13 && compcode != HE5_HDFE_COMP_SHUF_SZIP_EC &&
      compcode != HE5_HDFE_COMP_SHUF_SZIP_NN && compcode != HE5_HDFE_COMP_SHUF_SZIP_K13orEC &&
      compcode != HE5_HDFE_COMP_SHUF_SZIP_K13orNN )
    {
      status = FAIL;
      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_ARGS, H5E_BADVALUE, "Invalid/unsupported compression code. \n");
      HE5_EHprint("Error: Invalid/unsupported compression code, occured", __FILE__, __LINE__);
      return(status);
    }

  if( compcode == HE5_HDFE_COMP_DEFLATE || compcode == HE5_HDFE_COMP_NONE || compcode == HE5_HDFE_COMP_SHUF_DEFLATE)
    {
      /* Check GZIP compression level */
      /* ---------------------------- */
      if( compparm[0] < 0 || compparm[0] > 9)
	{
	  status = FAIL;
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_ARGS, H5E_BADVALUE, "Invalid GZIP compression level. \n");
	  HE5_EHprint("Error: Invalid GZIP compression level, occured", __FILE__, __LINE__);
	  return(status);
	}
    }
  else
    {
      /* Check SZIP compression block size */
      /* --------------------------------- */
      if( compparm[0] != 2 && compparm[0] != 4 && compparm[0] != 6 && compparm[0] != 8 &&
	  compparm[0] != 10 && compparm[0] != 12 && compparm[0] != 14 && compparm[0] != 16 &&
	  compparm[0] != 18 && compparm[0] != 20 && compparm[0] != 22 && compparm[0] != 24 &&
	  compparm[0] != 26 && compparm[0] != 28 && compparm[0] != 30 && compparm[0] != 32)
	{
	  status = FAIL;
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_ARGS, H5E_BADVALUE, "Invalid SZIP compression block size. \n");
	  HE5_EHprint("Error: Invalid SZIP compression block size, occured", __FILE__, __LINE__);
	  return(status);
	}
    }

#ifdef H5_HAVE_FILTER_SZIP
  can_encode = HE5_szip_can_encode();
#endif

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdefcomtile", &fid, &gid, &idx);
  if (status == FAIL) 
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return( status );
    }
  
  
  /* Initialize arrays */
  /* ----------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    {
      HE5_GDXGrid[ idx ].tiledims[ i ] = 0;
      dims[ i ] = 0;
    }
  
  /* Get the current property list ID */
  /* -------------------------------- */
  if( HE5_GDXGrid[ idx ].plist == FAIL )
    {
      /* create property list */
      /* -------------------- */
      HE5_GDXGrid[idx].plist = H5Pcreate(H5P_DATASET_CREATE);
      if (HE5_GDXGrid[idx].plist == FAIL )
	{
	  status = FAIL;
	  sprintf(errbuf, "Cannot create the property list.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_PLIST, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
 
      /* set layout to "H5D_CHUNKED" */
      /* --------------------------- */
      status = H5Pset_layout( HE5_GDXGrid[idx].plist, H5D_CHUNKED);
      if (status == FAIL )
	{
	  sprintf(errbuf, "Cannot set the \"CHUNKED\" type of storage.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_STORAGE, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
    }
  else
    {
      /* Get layout of the raw data */
      /* -------------------------- */
      layout = H5Pget_layout(HE5_GDXGrid[ idx ].plist);
      if (layout == H5D_LAYOUT_ERROR)
	{
	  status = FAIL;
	  sprintf(errbuf, "Cannot get the layout of the raw data.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_STORAGE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
      if( layout != H5D_CHUNKED )
	{
	  /* set layout to "H5D_CHUNKED" */
	  /* --------------------------- */
	  status = H5Pset_layout(HE5_GDXGrid[idx].plist, H5D_CHUNKED);
	  if ( status == FAIL )
	    {
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, "Cannot set the layout.\n");
	      HE5_EHprint("Error: Cannot set the layout, occured", __FILE__, __LINE__);
	      return(status );
	    }
	}
	   
    }

  /* Set tiling/chunking */
  /* ------------------- */
  if ( tilerank > 0 && tiledims != (hsize_t *)NULL)
    {
      status = H5Pset_chunk( HE5_GDXGrid[idx].plist, tilerank, tiledims); 
      if (status == FAIL )
	{
	  sprintf(errbuf, "Cannot set the sizes of chunks.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
      /* Set tile/chunk sizes */
      /* -------------------- */
      for (i = 0; i < tilerank; i++)
	HE5_GDXGrid[ idx ].tiledims[ i ] = tiledims[ i ];
    }  
  else if ( tilerank > 0 && tiledims == (hsize_t *)NULL)
    {
      /* Set default tile/chunk sizes */
      /* ---------------------------- */
      for (i = 0; i < tilerank; i++)
	{
	  /* dims[ i ] = HE5_CHUNKSIZE;*/
	  dims[ i ] = 1;
	  HE5_GDXGrid[ idx ].tiledims[ i ] = dims[ i ];
	}

      if (compcode == HE5_HDFE_COMP_NONE)
	{
	  HE5_GDXGrid[idx].tilecode = HE5_HDFE_NOTILE;
	}

      status = H5Pset_chunk( HE5_GDXGrid[idx].plist, tilerank, dims); 
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the sizes of chunks.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
    }
  else
    {
      sprintf(errbuf, "Invalid dataset rank: %d .", tilerank);
      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  HE5_GDXGrid[ idx ].tilerank = tilerank;

  switch(compcode)
    {
      /* Set NBIT compression parameters in ext. array */
    case HE5_HDFE_COMP_NBIT:
 
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
      HE5_GDXGrid[ idx ].compparm[ 1 ] = compparm[ 1 ];
      HE5_GDXGrid[ idx ].compparm[ 2 ] = compparm[ 2 ];
      HE5_GDXGrid[ idx ].compparm[ 3 ] = compparm[ 3 ];
 
      break;

      /* Set compression method to HE5_HDFE_COMP_DEFLATE */
      /* ----------------------------------------------- */
    case HE5_HDFE_COMP_DEFLATE:
	  
      status = H5Pset_deflate(HE5_GDXGrid[ idx ].plist,compparm[0]);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set GZIP compresssion method and level.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

      /* ------------------------------------------------- */
      /* Set GZIP compression method and compression       */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_DEFLATE");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
	  
      break;

    case HE5_HDFE_COMP_SZIP_CHIP:

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_CHIP_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_CHIP compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	  
      /* ------------------------------------------------- */
      /* Set SZIP_CHIP compression method and compression  */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_CHIP");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
	  
      break;
	  
    case HE5_HDFE_COMP_SZIP_K13:

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_EC_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_K13 cmpression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif

      /* ------------------------------------------------- */ 
      /* Set SZIP_K13 compression method and compression   */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_K13");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;

    case HE5_HDFE_COMP_SZIP_EC:

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_EC_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_EC compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	  
      /* ------------------------------------------------- */
      /* Set SZIP_EC compression method and compression    */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_EC");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];

      break;
 
    case HE5_HDFE_COMP_SZIP_NN:

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_NN_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_NN compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	  
      /* ------------------------------------------------- */
      /* Set SZIP_NN compression method and compression    */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_NN");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];

      break;

    case HE5_HDFE_COMP_SZIP_K13orEC:

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_EC_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_K13orEC compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ---------------------------------------------------------- */
      /* Set SZIP_K13orEC compression method and compression        */
      /*    parameters in external array                            */
      /* ---------------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_K13orEC");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;
 
    case HE5_HDFE_COMP_SZIP_K13orNN:

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_NN_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_K13orNN compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ---------------------------------------------------------- */
      /* Set SZIP_K13orNN compression method and compression        */
      /*    parameters in external array                            */
      /* ---------------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SZIP_K13orNN");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;

    case HE5_HDFE_COMP_SHUF_DEFLATE:
         
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
          
      status = H5Pset_deflate(HE5_GDXGrid[ idx ].plist,compparm[0]);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set GZIP compresssion method and level.");
	  H5Epush(__FILE__,"HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
 
      /* ------------------------------------------------- */
      /* Set shuffling+GZIP method and compression         */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_DEFLATE");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
         
      break;
 
    case HE5_HDFE_COMP_SHUF_SZIP_CHIP:
         
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_CHIP_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_CHIP compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ------------------------------------------------- */
      /* Set shuffling+SZIP_CHIP method and compression    */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_CHIP");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;
 
    case HE5_HDFE_COMP_SHUF_SZIP_K13:
 
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_EC_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_K13 cmpression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ------------------------------------------------- */
      /* Set shuffling+SZIP_K13 method and compression     */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;
 
    case HE5_HDFE_COMP_SHUF_SZIP_EC:
 
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_EC_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_EC compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ------------------------------------------------- */
      /* Set shuffling+SZIP_EC method and compression      */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_EC");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;
 
    case HE5_HDFE_COMP_SHUF_SZIP_NN:
 
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_NN_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_NN compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ------------------------------------------------- */
      /* Set shuffling+SZIP_NN method and compression      */
      /*    parameters in external array                   */
      /* ------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_NN");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;
 
    case HE5_HDFE_COMP_SHUF_SZIP_K13orEC:
 
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_EC_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_K13orEC compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ---------------------------------------------------------- */
      /* Set shuffling+SZIP_K13orEC method and compression          */
      /*    parameters in external array                            */
      /* ---------------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13orEC");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;
 
    case HE5_HDFE_COMP_SHUF_SZIP_K13orNN:
 
      status = H5Pset_shuffle(HE5_GDXGrid[idx].plist);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot set the shuffling method.");
	  H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

#ifdef H5_HAVE_FILTER_SZIP
      if(can_encode == 1)
	{
	  status = H5Pset_szip(HE5_GDXGrid[ idx ].plist,H5_SZIP_ALLOW_K13_OPTION_MASK|H5_SZIP_NN_OPTION_MASK,compparm[0]);
	  if ( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set SZIP_K13orNN compression method and block size.\n");
	      H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	} 
      else
	{
	  sprintf(errbuf, "Szip does not have encoder; szip compression won't apply to datafields.\n");
	  H5Epush(__FILE__, "HE5_GDdefcomptile", __LINE__, H5E_RESOURCE, H5E_CANTENCODE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	} 
#endif
	   
      /* ---------------------------------------------------------- */
      /* Set shuffling+SZIP_K13orNN method and compression          */
      /*    parameters in external array                            */
      /* ---------------------------------------------------------- */
      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13orNN");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];
 
      break;

    case HE5_HDFE_COMP_NONE:

      strcpy(HE5_GDXGrid[ idx ].compmethod, "HE5_HDFE_COMP_NONE");
      HE5_GDXGrid[ idx ].compparm[ 0 ] = compparm[ 0 ];

      break;

    default:
      {
	status = FAIL;
	sprintf(errbuf, "Compression method is not specified.\n"); 
	H5Epush(__FILE__, "HE5_GDdefcomtile", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	HE5_EHprint(errbuf, __FILE__, __LINE__);
      }
      break;
	  
    }
	   
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeforigin                                                  |
|                                                                             |
|  DESCRIPTION: Defines the origin of the grid data.                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  origincode     int                 origin code                             |
|                                     HDFE_GD_UL (0)                          |
|                                     HDFE_GD_UR (1)                          |
|                                     HDFE_GD_LL (2)                          |
|                                     HDFE_GD_LR (3)                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/20/99  A.Muslimov    In the call to EHinsertmeta() replaced the argument |
|                         gid by fid.                                         |
|  9/27/99  A.Muslimov    Added proper error handlings. Removed redundant     |
|                         if(status == 0){} brackets.                         |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDdeforigin(hid_t gridID, int origincode)
{
  herr_t          status = FAIL;              /* routine return status variable */
  
  hid_t           fid    = FAIL;              /* HDF-EOS file ID                */
  hid_t           gid    = FAIL;              /* "HDFEOS" group ID              */
  
  long            idx    = FAIL;              /* Grid index                     */
  
  char            *utlbuf = (char *)NULL;    /* Utility buffer                  */
  char            *errbuf = (char *)NULL;    /* Buffer for error message        */
  char            *originNames[] = {"HE5_HDFE_GD_UL", "HE5_HDFE_GD_UR", "HE5_HDFE_GD_LL", "HE5_HDFE_GD_LR"};


  HE5_LOCK;
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdeforigin", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdeforigin", &fid, &gid, &idx);
  if ( status == FAIL)
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdeforigin", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  utlbuf  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if( utlbuf  == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDdeforigin", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	  
      return(FAIL);
    }
  
  /* If proper origin code then write to structural metadata */
  /* ------------------------------------------------------- */
  if (origincode >= 0 && origincode <= 3)
    {
      sprintf(utlbuf, "%s%s%s", "\t\tGridOrigin=", originNames[origincode], "\n");

      status = HE5_EHinsertmeta(fid, HE5_GDXGrid[idx].gdname, "g", 101L,  utlbuf, NULL);
      if (status == FAIL)
	{
	  sprintf(errbuf,"Cannot insert metadata.");
	  H5Epush(__FILE__, "HE5_GDdeforigin", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}

    }
  else
    {
      status = FAIL;
      sprintf(errbuf, "Improper Grid Origin code: %d\n", origincode);
      H5Epush(__FILE__,  "HE5_GDdeforigin", __LINE__, H5E_FILE, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(utlbuf);
  free(errbuf);
  utlbuf = NULL;
  errbuf = NULL;
  
  
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefpixreg                                                  |
|                                                                             |
|  DESCRIPTION: Defines pixel registration within grid cell.                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  pixregcode     int     None        Pixel registration code                 |
|                                     HDFE_CENTER (0)                         |
|                                     HDFE_CORNER (1)                         |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/20/99  A.Muslimov    In the call to EHinsertmeta() replaced gid by fid.  |
|  9/27/99  A.Muslimov    Added proper error hadlings. Removed redundant      |
|                         if(status == 0){} brackets.                         |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDdefpixreg(hid_t gridID, int pixregcode)
{
  herr_t          status = FAIL;            /* routine return status variable */
  
  hid_t           fid    = FAIL;            /* HDF-EOS file ID                */
  hid_t           gid    = FAIL;            /* "HDFEOS" group ID              */
  
  long            idx    = FAIL;            /* Grid index                     */
  
  char            *utlbuf = (char *)NULL;   /* Utility buffer                 */
  char            *pixregNames[] = {"HE5_HDFE_CENTER", "HE5_HDFE_CORNER"};/* Pixel Registration Codes */
  char            *errbuf = (char *)NULL;   /* Buffer for error message       */ 


  HE5_LOCK;

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefpixreg", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdefpixreg", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefpixreg", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  /* Allocate memory for utility buffer */
  utlbuf  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlbuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDdefpixreg", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  
  
  /* If proper pix reg code then write to structural metadata */
  /* -------------------------------------------------------- */
  if (pixregcode >= 0 && pixregcode <= 1)
    {
      sprintf(utlbuf, "%s%s%s", "\t\tPixelRegistration=", pixregNames[pixregcode], "\n");

      status = HE5_EHinsertmeta(fid, HE5_GDXGrid[idx].gdname, "g", 101L,utlbuf, NULL);
      if(status == FAIL)
	{
	  status = FAIL;
	  sprintf(errbuf, "Cannot insert metadata.\n");
	  H5Epush(__FILE__, "HE5_GDdefpixreg", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}

    }
  else
    {
      status = FAIL;
      sprintf(errbuf, "Improper Pixel Registration code: %d\n", pixregcode);
      H5Epush(__FILE__, "HE5_GDdefpixreg", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(utlbuf);
  free(errbuf);
  
  utlbuf = NULL;
  errbuf = NULL;
  
 COMPLETION:
  HE5_UNLOCK;  
  return (status);

}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdiminfo                                                    |
|                                                                             |
|  DESCRIPTION: Retrieve size of specified dimension.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  size           hsize_t None        Size of dimension                       |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  dimname        char*   None        Dimension name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid.                                         |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 04/11/01  A.Muslimov    Initialized size to 0, but "Unlim" returns -1!,     |
|                          not 0!                                             |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
hsize_t
HE5_GDdiminfo(hid_t gridID, char *dimname)
{
  hsize_t       size   = 0;              /* Dimension size (return value)  */

  herr_t        status = FAIL;           /* routine return status variable */
  
  hid_t         fid    = FAIL;           /* HDF-EOS file ID                */
  hid_t         gid    = FAIL;           /* "HDFEOS" group ID              */
  
  long          idx    = FAIL;           /* Grid index                     */
    
  char          *metabuf = (char *)NULL;   /* Pointer to structural metadata (SM)     */
  char          *metaptrs[2] = {NULL,NULL};/* Pointers to begin and end of SM section */
  char          *utlstr  = (char *)NULL;   /* Utility string                          */
  char          *errbuf  = (char *)NULL;   /* Buffer for error mesage                 */
  
  CHECKPOINTER(dimname);
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdiminfo", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(0);
    }


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdiminfo", &fid, &gid, &idx);
  if ( status == FAIL)
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdiminfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(0);
    }
  
  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDdiminfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(0);
    }
  
  
  /* Get pointers to "Dimension" section within SM */
  /* --------------------------------------------- */
  metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g", "Dimension", metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for metabuffer.\n");
      H5Epush(__FILE__, "HE5_GDdiminfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlstr);
	 
      return(0);
    }
  
  /* Search for dimension name (surrounded by quotes) */
  /* ------------------------------------------------ */
  sprintf(utlstr, "%s%s%s", "\"", dimname, "\"\n");
  metaptrs[0] = strstr(metaptrs[0], utlstr);
  
  /*
   * If dimension found within grid structure then get dimension value
   */
  if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    {
      /* Set endptr at end of dimension definition entry */
      metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");

      status = HE5_EHgetmetavalue(metaptrs, "Size", utlstr);
      if (status == SUCCEED)
	size = atol(utlstr);
      else
	{
	  size = 0;
	  sprintf(errbuf,  "\"Size\" string not found in metadata.");
	  H5Epush(__FILE__, "HE5_GDdiminfo", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }
  else
    {
      size = 0;    
      sprintf(errbuf, "Dimension \"%s\" not found.", dimname);
      H5Epush(__FILE__, "HE5_GDdiminfo", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(metabuf);
  free(utlstr);
  free(errbuf);
  
  metabuf = NULL;
  utlstr = NULL;
  errbuf = NULL;
 
 COMPLETION:
  return(size);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgridinfo                                                   |
|                                                                             |
|  DESCRIPTION: Returns xdim, ydim and location of upper left and lower       |
|                right corners, in meters.                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  xdimsize       long                Number of columns in grid               |
|  ydimsize       long                Number of rows in grid                  |
|  upleftpt       double              Location (m/deg) of upper left corner   |
|  lowrightpt     double              Location (m/deg) of lower right corner  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid. Changed the data type of statmeta from  |
|                         intn to int   .                                     |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDgridinfo(hid_t gridID, long *xdimsize, long *ydimsize, double upleftpt[], double lowrightpt[])
{
  herr_t          status   = FAIL;           /* routine return status variable          */
  herr_t          statmeta = FAIL;           /* EHgetmetavalue return status            */
  
  hid_t           fid      = FAIL;           /* HDF-EOS file ID                         */
  hid_t           gid      = FAIL;           /* "HDFEOS" group ID                       */
  
  long            idx      = FAIL;           /* Grid index                              */
  
  char            *metabuf = (char *)NULL;   /* Pointer to structural metadata (SM)     */
  char            *metaptrs[2] = {NULL,NULL};/* Pointers to begin and end of SM section */
  char            *utlstr = (char *)NULL;    /* Utility string                          */
  char            errbuf[HE5_HDFE_ERRBUFSIZE];
  
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgridinfo", &fid, &gid, &idx);
  if ( status == FAIL)
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
	
      return( FAIL );
    }
  
  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
	
      return(FAIL);
    }
  
  /* Get pointers to grid structure section within SM */
  /* ------------------------------------------------ */
  metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g", NULL, metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for metabuffer  string.\n");
      H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
	    
      return(FAIL);
    }
  
  /* Get xdimsize if requested */
  /* ------------------------- */
  if (xdimsize != NULL)
    {
      statmeta = HE5_EHgetmetavalue(metaptrs, "XDim", utlstr);
      if (statmeta == SUCCEED)
	{
	  *xdimsize = atol(utlstr);
	}
      else
	{
	  status = FAIL;
	  sprintf(errbuf, "\"XDim\" string not found in metadata.\n");
	  H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }
  
  /* Get ydimsize if requested */
  /* ------------------------- */
  if (ydimsize != NULL)
    {
      statmeta = HE5_EHgetmetavalue(metaptrs, "YDim", utlstr);
      if (statmeta == SUCCEED)
	{
	  *ydimsize = atol(utlstr);
	}
      else
	{
	  status = FAIL;
	  sprintf(errbuf, "\"YDim\" string not found in metadata.\n");
	  H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }
  
  
  /* Get upleftpt if requested */
  /* ------------------------- */
  if (upleftpt != NULL)
    {
      statmeta = HE5_EHgetmetavalue(metaptrs, "UpperLeftPointMtrs", utlstr);
      if (statmeta == SUCCEED)
	{
	  /* If value is "DEFAULT" then return zeros */
	  /* --------------------------------------- */
	  if (strcmp(utlstr, "DEFAULT") == 0)
	    {
	      upleftpt[0] = 0;
	      upleftpt[1] = 0;
	    }
	  else
	    {
	      sscanf(utlstr, "(%lf,%lf)", &upleftpt[0], &upleftpt[1]);
	    }
	}
      else
	{
	  status = FAIL;
	  sprintf( errbuf, "\"UpperLeftPointMtrs\" string not found in metadata.\n");
	  H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}

    }
  
  /* Get lowrightpt if requested */
  /* --------------------------- */
  if (lowrightpt != NULL)
    {
      statmeta = HE5_EHgetmetavalue(metaptrs, "LowerRightMtrs", utlstr);
      if (statmeta == SUCCEED)
	{
	  /* If value is "DEFAULT" then return zeros */
	  if (strcmp(utlstr, "DEFAULT") == 0)
	    {
	      lowrightpt[0] = 0;
	      lowrightpt[1] = 0;
	    }
	  else
	    {
	      sscanf(utlstr, "(%lf,%lf)", &lowrightpt[0], &lowrightpt[1]);
	    }
	}
      else
	{
	  status = FAIL;
	  sprintf( errbuf,"\"LowerRightMtrs\"  string not found in metadata.\n");
	  H5Epush(__FILE__, "HE5_GDgridinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }
  
  free(metabuf);
  free(utlstr);
   
  metabuf = NULL; 
  utlstr  = NULL;
  
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDprojinfo                                                   |
|                                                                             |
|  DESCRIPTION: Returns GCTP projection code, zone code, spheroid code        |
|                and projection parameters.                                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  spherecode     int                 GCTP spheriod code                      |
|  projparm       double              Projection parameters                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid. Changed the datatype of statmeta from   |
|                         intn to int   , and initialized the return statuses |
|                         to -1.                                              |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDprojinfo(hid_t gridID, int *projcode,  int *zonecode, int *spherecode, double projparm[])
{

  herr_t          status   = FAIL;    /* routine return status variable */
  herr_t          statmeta = FAIL;    /* EHgetmetavalue return status   */  

  int             i;                  /* Loop index                     */
  
  hid_t           fid      = FAIL;    /* HDF-EOS file ID                */
  hid_t           gid      = FAIL;    /* "HDFEOS" group ID              */
  
  long            idx      = FAIL;    /* Grid index                     */
  
  char            *metabuf = (char *)NULL;   /*Pointer to structural metadata (SM)      */
  char            *metaptrs[2] = {NULL,NULL};/* Pointers to begin and end of SM section */
  char            *utlstr  = (char *)NULL;   /* Utility string                          */
  char            fmt[96];                   /* Format String                           */
  char            *GCTPproj[128] = {"HE5_GCTP_GEO", "HE5_GCTP_UTM", "HE5_GCTP_SPCS", 
				    "HE5_GCTP_ALBERS", "HE5_GCTP_LAMCC", "HE5_GCTP_MERCAT", "HE5_GCTP_PS", 
				    "HE5_GCTP_POLYC", "HE5_GCTP_EQUIDC", "HE5_GCTP_TM", "HE5_GCTP_STEREO", 
				    "HE5_GCTP_LAMAZ", "HE5_GCTP_AZMEQD", "HE5_GCTP_GNOMON", "HE5_GCTP_ORTHO",
				    "HE5_GCTP_GVNSP","HE5_GCTP_SNSOID", "HE5_GCTP_EQRECT", "HE5_GCTP_MILLER",
				    "HE5_GCTP_VGRINT","HE5_GCTP_HOM", "HE5_GCTP_ROBIN","HE5_GCTP_SOM",
				    "HE5_GCTP_ALASKA", "HE5_GCTP_GOOD", "HE5_GCTP_MOLL","HE5_GCTP_IMOLL",
				    "HE5_GCTP_HAMMER","HE5_GCTP_WAGIV", "HE5_GCTP_WAGVII","HE5_GCTP_OBLEQA"
				    /*,"HE5_GCTP_CEA", "HE5_GCTP_BCEA", "HE5_GCTP_ISINUS"*/};/* GCTP projection codes */

  char            errbuf[HE5_HDFE_ERRBUFSIZE];

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDprojinfo", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return( FAIL);
    }
  
  
  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
  
  /* Add "non-standard" GCTP codes */
  /* ----------------------------- */  
  GCTPproj[ 97 ] = (char *)calloc( HE5_HDFE_NAMBUFSIZE,  sizeof(char) );
  if(GCTPproj[ 97 ] == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
  
      return(FAIL);
    }
  strcpy(GCTPproj[97], "HE5_GCTP_CEA");
 
  GCTPproj[ 98 ] = (char *)calloc( HE5_HDFE_NAMBUFSIZE,  sizeof(char) );
  if(GCTPproj[ 98 ] == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);

      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
      free(GCTPproj[ 97 ]); 
      return(FAIL);
    }
  strcpy(GCTPproj[98], "HE5_GCTP_BCEA");


  GCTPproj[99] = (char *) calloc( HE5_HDFE_NAMBUFSIZE, sizeof(char) );
  if(GCTPproj[99] == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for GCTP codes string.\n");
      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
      free(GCTPproj[ 97 ]);
      free(GCTPproj[ 98 ]);
      return(FAIL);
    }
  strcpy(GCTPproj[99],"HE5_GCTP_ISINUS");
  
  /* Get pointers to grid structure section within SM */
  /* ------------------------------------------------ */
  metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g", NULL, metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for metabuffer string.\n");
      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
      free(GCTPproj[ 97 ]);
      free(GCTPproj[ 98 ]);
      free(GCTPproj[99]);
	    
      return(FAIL);
    }
  
  /* Get projcode if requested */
  /* ------------------------- */
  if (projcode != NULL)
    {
      *projcode = FAIL;
		
      statmeta = HE5_EHgetmetavalue(metaptrs, "Projection", utlstr);
      if (statmeta == SUCCEED)
	{
	  /* Loop through projection codes until found */
	  /* ----------------------------------------- */
	  for (i = 0; i < 128; i++)
	    {
	      if (GCTPproj[i] != NULL)
		{
		  if (strcmp(utlstr, GCTPproj[i]) == 0)
		    {
		      *projcode = i;
		      break;
		    }
		}
	    }
	}
      else
	{
	  sprintf(errbuf, "Projection Code not defined for \"%s\".\n", HE5_GDXGrid[idx].gdname);
	  H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (projparm != NULL)
	    {
	      for (i = 0; i < 13; i++)
		{
		  projparm[i] = FAIL;
		}
	    }
	  free(utlstr);
	  free(GCTPproj[97]);
	  free(GCTPproj[98]);
	  free(GCTPproj[99]);
	  free(metabuf);
			
	  return(FAIL);
			
	}
    }
  
  
  /* Get zonecode if requested */
  /* ------------------------- */
  if (zonecode != NULL)
    {
      *zonecode = FAIL;
		
      /* Zone code only relevant for UTM and State Code projections */
      /* ---------------------------------------------------------- */
      if (*projcode == HE5_GCTP_UTM || *projcode == HE5_GCTP_SPCS)
	{
	  statmeta = HE5_EHgetmetavalue(metaptrs, "ZoneCode", utlstr);
	  if (statmeta == SUCCEED)
	    {
	      *zonecode = atoi(utlstr);
	    }
	  else
	    {
	      sprintf(errbuf, "Zone Code not defined for \"%s\".\n", HE5_GDXGrid[idx].gdname);
	      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(utlstr);
	      free(GCTPproj[97]);
	      free(GCTPproj[98]);
	      free(GCTPproj[99]);
	      free(metabuf);
					
	      return(FAIL);
	    }
	}
    }
  
  /* Get projection parameters if requested */
  /* -------------------------------------- */
  if (projparm != NULL)
    {

      /*
       * Note: No projection parameters for GEO, UTM, and State Code
       * projections
       */
      if (*projcode == HE5_GCTP_GEO || *projcode == HE5_GCTP_UTM || *projcode == HE5_GCTP_SPCS)
	{
	  for (i = 0; i < 13; i++)
	    {
	      projparm[i] = 0.0;
	    }

	}
      else
	{
	  statmeta = HE5_EHgetmetavalue(metaptrs, "ProjParams", utlstr);
	  if (statmeta == SUCCEED)
	    {

	      /* Build format string to read projection parameters */
	      /* ------------------------------------------------- */
	      strcpy(fmt, "%lf,");
	      for (i = 1; i <= 11; i++)
		strcat(fmt, "%lf,");
	      strcat(fmt, "%lf");
					
					
	      /* Read parameters from numeric list */
	      /* --------------------------------- */
	      sscanf(&utlstr[1], fmt,
		     &projparm[0], &projparm[1],
		     &projparm[2], &projparm[3],
		     &projparm[4], &projparm[5],
		     &projparm[6], &projparm[7],
		     &projparm[8], &projparm[9],
		     &projparm[10], &projparm[11],
		     &projparm[12]);
	    }
	  else
	    {
	      sprintf(errbuf, "Projection parameters not defined for \"%s\".\n", HE5_GDXGrid[idx].gdname);
	      H5Epush(__FILE__, "HE5_GDprojinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(utlstr);
	      free(GCTPproj[97]);
	      free(GCTPproj[98]);
	      free(GCTPproj[99]);
	      free(metabuf);
					
	      return(FAIL);
	    }
	}
    }
  
  
  /* Get spherecode if requested */
  /* --------------------------- */
  if (spherecode != NULL)
    {
      *spherecode = 0;
		
      /* Note: Spherecode not defined for GEO projection */
      /* ----------------------------------------------- */
      if (*projcode != HE5_GCTP_GEO)
	{
	  statmeta = HE5_EHgetmetavalue(metaptrs, "SphereCode", utlstr);
	  if (statmeta == SUCCEED)
	    {
	      *spherecode = atoi(utlstr);
	    }
	}
    }
  
  free(metabuf);
  free(GCTPproj[97]);
  free(GCTPproj[98]);
  free(GCTPproj[99]);
  free(utlstr);
  
  metabuf      = NULL;
  GCTPproj[97] = NULL;
  GCTPproj[98] = NULL;
  GCTPproj[99] = NULL;
  utlstr       = NULL;
  
  return (status);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDorigininfo                                                 |
|                                                                             |
|  DESCRIPTION: Returns origin code                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  origincode     int                   grid origin code                      |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid.  Changed the type of statmeta from intn |
|                         to int   , and  initialized the return statuses to  |
|                         -1.                                                 |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Mar 04   S.Zhao        Changed the default origin code from 0 to FAIL.     |
|  Aug 11   Abe Taaheri   Modified to return default value if it is not found |
|                         in structure metadata                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDorigininfo(hid_t gridID, int *origincode)
{

  herr_t          status   = FAIL;          /* routine return status variable */
  herr_t          statmeta = FAIL;          /* EHgetmetavalue return status   */  

  int             i;                        /* Loop index                     */
  
  hid_t           fid      = FAIL;          /* HDF-EOS file ID                */
  hid_t           gid      = FAIL;          /* "HDFEOS" group ID              */
  
  long            idx      = FAIL;          /* Grid index                     */
  
  char            *metabuf = (char *)NULL;      /* Pointer to structural metadata (SM)     */
  char            *metaptrs[2] = {NULL,NULL};   /* Pointers to begin and end of SM section */
  char            *utlstr  = (char *)NULL;      /* Utility string                          */
  char            *originNames[] = {"HE5_HDFE_GD_UL", "HE5_HDFE_GD_UR","HE5_HDFE_GD_LL", "HE5_HDFE_GD_LR"};                                      /* Array of origin codes                   */
  char            *errbuf = (char *)NULL;/* Buffer for error message                */ 
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDorigininfo", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDorigininfo", &fid, &gid, &idx);
  if ( status == FAIL)
    {
      *origincode = FAIL;
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDorigininfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      *origincode = FAIL;
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDorigininfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(FAIL);
    }
  
  /* Set default origin code */
  /* ----------------------- */
  *origincode = FAIL;
  
  /* Get pointers to grid structure section within SM */
  /* ------------------------------------------------ */
  metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g",NULL, metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for metabuffer string.\n");
      H5Epush(__FILE__, "HE5_GDorigininfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlstr);
	    
      return(FAIL);
    }
  
  /* Get "GridOrigin" metadata string */
  /* -------------------------------- */
  statmeta = HE5_EHgetmetavalue(metaptrs, "GridOrigin", utlstr);
  if (statmeta == FAIL)
    {
      /* return default value */
      status = 0;
      *origincode = 0;
      
      /*
      sprintf(errbuf,"Cannot get metadata string.\n");
      H5Epush(__FILE__, "HE5_GDorigininfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      status=FAIL;
      */

      free(errbuf);
      free(utlstr);
      free(metabuf);
      metabuf = NULL;
      utlstr = NULL;
      errbuf = NULL;
   
      return(status);
    }
  
  /*
   * If "GridOrigin" string found in metadata then convert to
   *        numeric origin code (fixed added: Jan 97)
   */
  for (i = 0; i < 4; i++)
    {
      if (strcmp(utlstr, originNames[i]) == 0)
	{
	  *origincode = i;
	  break;
	}
    }
  
  
  free(metabuf);
  free(utlstr);
  free(errbuf);
  
  metabuf = NULL;
  utlstr = NULL;
  errbuf = NULL;
  
  return (status);

}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDpixreginfo                                                 |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  pixregcode     int       None      Pixel registration code                 |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid. Changed the type of statmeta from intn  |
|                         to int   , and  initialized the return statuses to  |
|                         -1.                                                 |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Mar 04   S.Zhao        Changed the default pixreg code from 0 to FAIL.     |
|  Aug 11   Abe Taaheri   Modified to return default value if it is not found |
|                         in structure metadata                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDpixreginfo(hid_t gridID, int *pixregcode)
{

  herr_t          status   = FAIL;      /* routine return status variable */
  herr_t          statmeta = FAIL;      /* EHgetmetavalue return status   */  

  int             i;                    /* Loop index                     */
  
  hid_t           fid    = FAIL;        /* HDF-EOS file ID                */
  hid_t           gid    = FAIL;        /* "HDFEOS" group ID              */
  
  long            idx    = FAIL;        /* Grid index                     */
  
  char            *metabuf = (char *)NULL;      /* Ptr to structural metadata (SM) */
  char            *metaptrs[2] = {NULL,NULL};   /* Ptrs to begin/end of SM section */
  char            *utlstr = (char *)NULL;       /* Utility string                  */
  char            *pixregNames[] = {"HE5_HDFE_CENTER", "HE5_HDFE_CORNER"};/* Pixel Registration Codes */
  char            *errbuf = (char *)NULL;                                 /* Buffer for error message */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDpixreginfo", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDpixreginfo", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      *pixregcode = FAIL;
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDpixreginfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return( FAIL );
    }
  
  /* Set default pixreg code */
  /* ----------------------- */
  *pixregcode = FAIL;
  
  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDpixreginfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	 
      return(FAIL);
    }
  
  
  /* Get pointers to Grid structure section within SM */
  /* ------------------------------------------------ */
  metabuf = (char *)HE5_EHmetagroup(fid , HE5_GDXGrid[idx].gdname, "g",  NULL, metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for metabuffer string.\n");
      H5Epush(__FILE__, "HE5_GDpixreginfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlstr);
	    
      return(FAIL);
    }
  
  /* Get "PixelRegistration" metadata string */
  /* --------------------------------------- */
  statmeta = HE5_EHgetmetavalue(metaptrs, "PixelRegistration", utlstr);

  if (statmeta == FAIL)
    {
      /* return default value */
      status = 0;
      *pixregcode = 0;
 
      /*
      sprintf(errbuf,"Cannot get metadata string.\n");
      H5Epush(__FILE__, "HE5_GDpixreginfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      status = FAIL;
      */

      free(errbuf);
      free(utlstr);
      free(metabuf);   
      metabuf = NULL;
      utlstr = NULL;
      errbuf = NULL;

      return(status);
    }
  
  /*
   * If "PixelRegistration" string found in metadata then convert
   * to numeric origin code (fixed added: Jan 97)
   */
  for (i = 0; i < 2; i++)
    {
      if (strcmp(utlstr, pixregNames[i]) == 0)
	{
	  *pixregcode = i;
	  break;
	}
    }
  
  free(metabuf);
  free(utlstr);
  free(errbuf);
  
  metabuf = NULL;
  utlstr = NULL;
  errbuf = NULL;
  
  return (status);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDcompinfo                                                   |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*   None                                                |
|  compcode       int*    None                                                |
|  compparm       int     none                                                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid. Changed the type of gridID from int32_t |
|                         to hid_t. Changed the type of statmeta from intn    |
|                         to int   , and  initialized the return statuses to  |
|                         -1.                                                 |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  June 03  S.Zhao        Changed the type of compcode from *char to *int.    |
|  Aug  03  S.Zhao        Added Szip compression methods.                     |
|  Apr  04  S.Zhao        Added the HE5_GDfldnameinfo() call.                 |
|  Dec  13  Abe Taaheri   Added compression detection from field, if it is    |
|                          not found from the structure metadata              |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDcompinfo(hid_t gridID, const char *fieldname, int *compcode, int compparm[])
{

  herr_t          status   = FAIL;            /* routine return status variable */
  herr_t          statmeta = FAIL;            /* EHgetmetavalue return status   */  

  int             i;                          /* Loop Index                     */

  hid_t           (*func)(void*);
  hid_t           fid    = FAIL;              /* HDF-EOS file ID                */
  hid_t           gid    = FAIL;              /* "HDFEOS" group ID              */
  
  long            idx    = FAIL;              /* Grid index                     */
  long            idOffset   = HE5_GRIDOFFSET;/* HDF-EOS Grid ID offset         */
  int             nameflag = FAIL;            /* Name flag (0-alias,1-actual)   */
  char            fldname[HE5_HDFE_NAMBUFSIZE];      /* Field name buffer       */
  char            fldactualname[HE5_HDFE_NAMBUFSIZE];/* Actual name of a field  */
  char            *metabuf = (char *)NULL;   /* Ptr to structural metadata (SM) */
  char            *metaptrs[2] = {NULL,NULL};/* Ptrs to begin/end of SM section */
  char            *utlstr = (char *)NULL;    /* Utility string                  */
  char            *errbuf = (char *)NULL;    /* buffer for error message        */
  hid_t           sdid,dcpl;
  size_t          nelmts;
  unsigned int    flags,filter_info;
  int             got_compparm = 0;
  int             found = 0;
  int             numfilt;
  hid_t           plist_id;
  int             done_loop = 0;
  H5Z_filter_t    filter_type;
  void            *edata = (void *)NULL;
  char            *HDFcomp[18] = {"HE5_HDFE_COMP_NONE", "HE5_HDFE_COMP_RLE", "HE5_HDFE_COMP_NBIT", "HE5_HDFE_COMP_SKPHUFF", "HE5_HDFE_COMP_DEFLATE", "HE5_HDFE_COMP_SZIP_CHIP", "HE5_HDFE_COMP_SZIP_K13", "HE5_HDFE_COMP_SZIP_EC", "HE5_HDFE_COMP_SZIP_NN", "HE5_HDFE_COMP_SZIP_K13orEC", "HE5_HDFE_COMP_SZIP_K13orNN", "HE5_HDFE_COMP_SHUF_DEFLATE", "HE5_HDFE_COMP_SHUF_SZIP_CHIP", "HE5_HDFE_COMP_SHUF_SZIP_K13", "HE5_HDFE_COMP_SHUF_SZIP_EC", "HE5_HDFE_COMP_SHUF_SZIP_NN", "HE5_HDFE_COMP_SHUF_SZIP_K13orEC", "HE5_HDFE_COMP_SHUF_SZIP_K13orNN"};  /* Compression method Codes    */
  
  H5Eget_auto((H5E_auto1_t *)&func, &edata);

  CHECKPOINTER(fieldname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDcompinfo", &fid, &gid, &idx);
  if ( status == FAIL)
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return( FAIL );
    }
  
  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  /* Call HE5_GDfldnameinfo() to get actual field name */
  /* ------------------------------------------------- */
  nameflag = HE5_GDfldnameinfo(gridID, fieldname, fldactualname);
  if ( nameflag == FAIL )
    {
      sprintf(errbuf, "Cannot get the actual name of the field.\n");
      H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlstr);
 
      return(FAIL);
    }

  /* If fldname is alias, then change it to the actual name */
  /* ------------------------------------------------------ */
  if (nameflag == FALSE)
    {
      strcpy(fldname,"");
      strcpy(fldname,fldactualname);
    }
 
  if (nameflag == TRUE)
    {
      strcpy(fldname,"");
      strcpy(fldname,fieldname);
    }

  /* Get pointers to "DataField" section within SM */
  /* --------------------------------------------- */
  metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g","DataField", metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for metabuffer string.\n");
      H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(utlstr);
	    
      return(FAIL);
    }
  
  /* Search for field */
  /* ---------------- */
  sprintf(utlstr, "%s%s%s", "\"", fldname, "\"\n");
  metaptrs[0] = strstr(metaptrs[0], utlstr);
  
  
  /* If field found and user wants compression code ... */
  /* -------------------------------------------------- */
  if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    {
      if (compcode != NULL)
	{
	  /* Set endptr at end of field's definition entry */
	  /* --------------------------------------------- */
	  metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
			
	  /* Get compression type */
	  /* -------------------- */
	  statmeta = HE5_EHgetmetavalue(metaptrs, "CompressionType", utlstr);
	  /*
	    if (statmeta == FAIL)
	    {
	    sprintf(errbuf,"Cannot get metadata string.\n");
	    H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    free(utlstr);
	    free(metabuf);
		   
	    return( FAIL );
	    }
	  */
    
	  /*
	   * Default is no compression if "CompressionType" string not
	   * in metadata
	   */
	  *compcode = HE5_HDFE_COMP_NONE;
	  /* strcpy( compcode, utlstr);*/

	  /* If compression code is found ... */
	  /* -------------------------------- */
	  if (statmeta == SUCCEED)
	    {
	      /* Loop through compression types until match */
	      /* ------------------------------------------ */
	      for (i = 0; i < 18; i++)
		{
		  if (strcmp(utlstr, HDFcomp[i]) == 0)
		    {
		      *compcode = i;
		      break;
		    }
		}
	    }
	}
		
      
      /* If user wants compression parameters ... */
      
      /* Compression is not listed in the structure metadata. 
	 Lets see if the field is compressed by other means such 
	 as herepack where the compression is done but does not 
	 show up in the structure metadata.
      */
      got_compparm = 0;
      if(*compcode == HE5_HDFE_COMP_NONE)
	{
	  if (HE5_GDXGrid[gridID % idOffset].active != 0)
	    {
	      /* Get Grid index */
	      /* -------------- */
	      idx = HE5_EHhid2long(gridID) % idOffset;
	      if ( idx == FAIL)
		{
		  status = FAIL;
		  sprintf(errbuf, "Cannot get the Grid index \n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf) ;
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		}
	    }
	  /* Loop through all datasets in grid */
	  /* ------------------------------ */
	  for (i = 0; i < HE5_GDXGrid[idx].nDFLD; i++)
	    {
	      /* Get dataset name */
	      if( strcmp(fieldname, HE5_GDXGrid[ idx ].ddataset[ i ].name) == 0 )
		{
		  found = 1; 
		  sdid = HE5_GDXGrid[ idx ].ddataset[ i ].ID;
		  break;
		} 
	    }
	  
	  if(found == 1) /* did not find fieldname */
	    {
	      /*
	       * Retrieve dataset creation property list.
	       */
	      dcpl = H5Dget_create_plist (sdid); 
	      numfilt = H5Pget_nfilters (plist_id);

	      done_loop = 0;	      
	      for (i=0; i<numfilt; i++) {
		nelmts = 0;
		filter_type = H5Pget_filter2 (plist_id, (unsigned)i, &flags, &nelmts, 
					      NULL, 0, NULL,
					      &filter_info);
		switch(filter_type)
		  {
		    /*-------------------------------------------------------------------------
		     * H5Z_FILTER_DEFLATE      1 , deflation like gzip
		     *-------------------------------------------------------------------------
		     */
		  case H5Z_FILTER_DEFLATE:
		    if(numfilt == 1)
		      {
			*compcode = 4; /* HE5_HDFE_COMP_DEFLATE */
			compparm[0] = 6; /* default value */
			done_loop = 1;
		      }
		    else
		      {
			*compcode = 11; /* HE5_HDFE_COMP_SHUF_DEFLATE */
			compparm[0] = 6; /* default value */
			done_loop = 1;
		      }
		    break;
		    /*-------------------------------------------------------------------------
		     * H5Z_FILTER_NBIT
		     *-------------------------------------------------------------------------
		     */
		  case H5Z_FILTER_NBIT:
			*compcode = 2; /* HE5_HDFE_COMP_NBIT */
			/* Initialize to zero */
			for (i = 0; i < 4; i++)
			  {
			    compparm[i] = 0.0;
			  }
			done_loop = 1;
		    break;
		    /*-------------------------------------------------------------------------
		     * H5Z_FILTER_SZIP       4 , szip compression
		     *-------------------------------------------------------------------------
		     */
		  case H5Z_FILTER_SZIP:
		    if(numfilt == 1)
		      {
			*compcode = 7; /* HE5_HDFE_COMP_SZIP_CHIP */
			compparm[0] = 16;
			compparm[1] = 4;  /* SZ_EC */
			done_loop = 1;
		      }
		    else
		      {
			*compcode = 8; /* HE5_HDFE_COMP_SZIP_K13 */
			compparm[0] = 16;
			compparm[1] = 32;  /* SZ_NN */
			done_loop = 1;
		      }
		    break;
		    /*-------------------------------------------------------------------------
		     * H5Z_FILTER_SHUFFLE    2 , shuffle the data
		     *-------------------------------------------------------------------------
		     */
		  case H5Z_FILTER_SHUFFLE:
		    if(numfilt == 2)
		      {
			*compcode = 11;  /* HE5_HDFE_COMP_SHUF_DEFLATE */
			compparm[0] = 6;
			done_loop = 1;
		      }
		    else if(numfilt > 2)
		      {
			*compcode = 12;  /* HE5_HDFE_COMP_SHUF_SZIP_CHIP */
			compparm[0] = 16;
			done_loop = 1;
		      }
		    break;
		    /*-------------------------------------------------------------------------
		     * H5Z_FILTER_FLETCHER32 3 , fletcher32 checksum of EDC
		     *-------------------------------------------------------------------------
		     */
		  case H5Z_FILTER_FLETCHER32:
		    done_loop =  1;
		    break;
		       
		    /*-------------------------------------------------------------------------
		     * H5Z_FILTER_SCALEOFFSET
		     *-------------------------------------------------------------------------
		     */
		  case H5Z_FILTER_SCALEOFFSET:
		    done_loop =  1;
		    break;
		  }/*switch*/
		if(done_loop ==  1) break;
	      }/*for*/
	    }
	  got_compparm = 1;
	}	  

      /* if compression parameters are obtained from field itself when
	 calling SDgetcompinfo, we will skip next if statement */
  
      
      /* If user wants compression parameters ... */
      /* ---------------------------------------- */
      if (compparm != NULL && compcode != NULL && got_compparm != 1)
	{
	  /* Initialize to zero */
	  for (i = 0; i < 5; i++)
	    {
	      compparm[i] = 0;
	    }

	  /*
	   * Get compression parameters 
	   */
	  if(*compcode == HE5_HDFE_COMP_NBIT)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "CompressionParams", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"CompressionParams\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
					
		  return( FAIL );
		}
	      sscanf(utlstr, "(%d,%d,%d,%d)",&compparm[0], &compparm[1],&compparm[2], &compparm[3]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_DEFLATE)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "DeflateLevel", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"DeflateLevel\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
					
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SZIP_CHIP)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SZIP_K13)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SZIP_EC)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SZIP_NN)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SZIP_K13orEC)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SZIP_K13orNN)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_DEFLATE)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "DeflateLevel", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"DeflateLevel\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_SZIP_CHIP)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_SZIP_K13)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_SZIP_EC)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_SZIP_NN)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_SZIP_K13orEC)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }
	  else if (*compcode == HE5_HDFE_COMP_SHUF_SZIP_K13orNN)
	    {
	      statmeta = HE5_EHgetmetavalue(metaptrs, "BlockSize", utlstr);
	      if (statmeta == FAIL)
		{
		  sprintf(errbuf,"\"BlockSize\" string not found in metadata.\n");
		  H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
 
		  return( FAIL);
		}
	      sscanf(utlstr, "%d", &compparm[0]);
	    }

	}
    }
  else
    {   
      status = FAIL;
      sprintf(errbuf, "Fieldname \"%s\" not found.\n", fldname);
      H5Epush(__FILE__, "HE5_GDcompinfo", __LINE__, H5E_FILE, H5E_SEEKERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(metabuf);
  free(utlstr);
  free(errbuf);
  
  metabuf = NULL;
  utlstr  = NULL;
  errbuf  = NULL;
  
 COMPLETION:
  return (status);

}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDfieldinfo                                                  |
|                                                                             |
|  DESCRIPTION: Retrieve information about a specific geolocation or data     |
|                field in the grid.                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               name of field                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int                 rank of field (# of dims)               |
|  dims           hsize_t             field dimensions                        |
|  ntype          hid_t               field number types                      |
|  dimlist        char*               field dimension list                    |
|  maxdimlist     char*               field maximum dimension list            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dopen                                                         |
|             H5Dget_type                                                     |
|             H5Tget_class                                                    |
|             H5Dclose                                                        |
|             H5Dget_space                                                    |
|             H5Sget_simple_extent_ndims                                      |
|             H5Sget_simple_extent_dims                                       |
|             H5Sclose                                                        |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid. Changed the type of statmeta from intn  |
|                         to int   , and  initialized the return status to    |
|                         -1.                                                 |
|  9/27/99  A.Muslimov    Added proper error handlings.                       |
|  10/18/99 A.Muslimov    Replace memcpy() by memmove() to avoid a problem    |
|                         when arguments 1 and 2 overlap in memory.           |
| 01/13/00  A.Muslimov    Added "maxdimlist" parameter to make it possible    |
|                         working with the appendable datasets. Modified the  |
|                         blocks retrieving the dimension lists. Added proper |
|                         error handlings after the function calls.           |
| Feb 00    A.Muslimov    Casted the type of a variable assigned to rank to   |
|                         "int".                                              |
| Mar 00    A.Muslimov    Changed the ID of field group from gd_id to data_id.|
| Apr 00    A.Muslimov    Changed type of 'slen' from long to size_t.         |
| 5/10/00   A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| Jan 03    S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
| Oct. 03   S.Zhao        Added the H5Tclose(datatype) call.                  |
| Jan. 04   S.Zhao        Modified to enable a character string dataset.      |
| Mar  04   S.Zhao        Modified for a character string dataset.            |
| Apr  04   S.Zhao        Added the  HE5_GDfldnameinfo() call.                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDfieldinfo(hid_t gridID, const char *fieldname, int *rank, hsize_t dims[], hid_t ntype[], char *dimlist, char *maxdimlist)
{

  herr_t            status   = FAIL;   /* routine return status variable     */
  herr_t            statmeta = FAIL;   /* EHgetmetavalue return status       */
  herr_t            Dstatus  = FAIL;   /* Status for H5Dclose                */

  int               i;                 /* Loop index                         */
  
  hid_t             fid       = FAIL;  /* HDF-EOS file ID                    */
  hid_t             gid       = FAIL;  /* "HDFEOS" group ID                  */
  hid_t             datasetid = FAIL;  /* dataset ID                         */
  hid_t             datatype  = FAIL;  /* data type ID                       */
  hid_t             fieldID   = FAIL;  /* field ID                           */
  hid_t             dspace    = FAIL;  /* data space ID                      */

  size_t            slen[HE5_DTSETRANKMAX];/* Length of each entry in a list */
  
  long              idx   = FAIL;      /* Grid index                         */
  long              ndims = 0;         /* Number of dimensions               */
  long              xdim  = 0;         /* X dim size                         */
  long              ydim  = 0;         /* Y dim size                         */
     
  H5T_class_t       classid = H5T_NO_CLASS;        /* Data type class ID     */
  
  char              *metabuf = (char *)NULL;       /* Pointer to structural metadata (SM) */
  char              *metaptrs[2] = {NULL,NULL};    /* Pnts to begin and end of SM section */
  char              *utlstr = (char *)NULL;        /* Utility string                      */
  char              *ptr[HE5_DTSETRANKMAX];        /* String pointers for parsed string   */
  char              dimstr[HE5_HDFE_DIMBUFSIZE];   /* Individual dimension entry string   */
  char              maxdimstr[HE5_HDFE_DIMBUFSIZE];/* Maximum dimension entry string      */
  char              errbuf[HE5_HDFE_ERRBUFSIZE];
  int               nameflag    = FAIL;            /* Actual(1)/Alias(0) field name       */
  char              fldname[HE5_HDFE_NAMBUFSIZE];  /* field name buffer                   */
  char              fldactualname[HE5_HDFE_NAMBUFSIZE];/* Actual field name               */
  htri_t            str_is_variable;               /* boolean: TRUE if string is variable 
						      lengeth FALSE if string is fixed length
						      -1 if error in H5Tis_variavle_str() */
  
  CHECKPOINTER(fieldname);

  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
		
      return(FAIL);
    }
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/  
  status = HE5_GDchkgdid(gridID, "HE5_GDfieldinfo", &fid, &gid, &idx);
  if(status == FAIL)
    {
      sprintf(errbuf,"Checking for Grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
		
      return(FAIL);
    }
  
  /* Call HE5_GDfldnameinfo() to get actual field name */
  /* ------------------------------------------------- */
  nameflag = HE5_GDfldnameinfo(gridID, fieldname, fldactualname);
  if ( nameflag == FAIL )
    {
      sprintf(errbuf, "Cannot get actual name of the field.\n");
      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
 
      return(FAIL);
    }

  /* Name is not alias */
  /* ----------------- */
  if (nameflag == TRUE)
    {
      strcpy(fldname,"");
      strcpy(fldname,fieldname);
    }

  /* Name is alias */
  /* ------------- */
  if (nameflag == FALSE)
    {
      strcpy(fldname,"");
      strcpy(fldname,fldactualname);
    }

  /* Allocate memory for metabuf string */
  /* ---------------------------------- */
  metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g", "DataField", metaptrs);
  if(metabuf == NULL)
    {
      sprintf(errbuf, "cannot allocate memory for metabuffer.\n");
      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(utlstr);
		
      return(FAIL);
    }
  
  /* Search for field */
  /* ---------------- */
  sprintf(utlstr, "%s%s%s", "\"", fldname, "\"\n");
  metaptrs[0] = strstr(metaptrs[0], utlstr);
  
  /* If field found ... */
  /* ------------------ */
  if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
    {
      /* initialize the rank value */
      /* ------------------------- */
      *rank = FAIL;
	    
		
      /* Set endptr at end of dimension definition entry */
      /* ----------------------------------------------- */
      metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");

      /* Get "DataType" string */
      /* --------------------- */
      statmeta = HE5_EHgetmetavalue(metaptrs, "DataType", utlstr);
	  
      /* Convert to numbertype code */
      /* -------------------------- */
      if (statmeta == SUCCEED)
	{
	  datasetid     = H5Dopen(HE5_GDXGrid[idx].data_id, fldname);
	  if (datasetid == FAIL)
	    {
	      sprintf(errbuf, "Cannot open the dataset \"%s\".", fldname);
	      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (utlstr  != NULL) free(utlstr);
	      if (metabuf != NULL) free(metabuf);
			  
	      return(FAIL);
	    }

	  /* Get data type ID */
	  /* ---------------- */
	  datatype      = H5Dget_type(datasetid);
	  if (datatype == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the data type for \"%s\" dataset.", fldname);
	      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (utlstr  != NULL) free(utlstr);
	      if (metabuf != NULL) free(metabuf);
			  
	      return(FAIL);
	    }

	  /* Get data class ID */
	  /* ----------------- */
	  classid       = H5Tget_class(datatype);
	  if (classid == H5T_NO_CLASS)
	    {
	      sprintf(errbuf, "Cannot get the data type class ID for \"%s\" dataset.", fldname);
	      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (utlstr  != NULL) free(utlstr);
	      if (metabuf != NULL) free(metabuf);
			  
	      return(FAIL);
	    }

	  if (classid == H5T_STRING)
	    {
	      /* HE5T_CHARSTRING has variable length for data fields */
	      str_is_variable = H5Tis_variable_str(datatype);
	      if(str_is_variable == TRUE)
		{
		  ntype[0] = HE5T_CHARSTRING;
		}
	      else if(str_is_variable == FALSE)
		{
		  ntype[0] = HE5T_NATIVE_CHAR;
		}
	      else
		{
		  status = FAIL;
		  sprintf(errbuf, "Failed to see if string field is varaible or fixed length for the \"%s\" field.\n",fldname);
		  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);

		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  if (utlstr  != NULL) free(utlstr);
		  if (metabuf != NULL) free(metabuf);
		  return(status);
		}
		      
	      /*HE5_GDgetstringtype(swathID, fieldname,classid);*/
	      /*ntype[0] = HE5T_CHARSTRING;*/
	    }
	  else
	    {
	      /* ntype[0]      = classid; */
	      ntype[0] = HE5_EHdtype2numtype(datatype);
	      if (ntype[0] == FAIL)
		{
		  sprintf(errbuf, "Cannot get the number type for \"%s\" dataset.", fldname);
		  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  if (utlstr  != NULL) free(utlstr);
		  if (metabuf != NULL) free(metabuf);
			  
		  return(FAIL);
		}
	    }

	  /* Release datatype ID */
	  /* ------------------- */
	  status = H5Tclose(datatype);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Cannot close the datatype \"%s\".", fldname);
	      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (utlstr  != NULL) free(utlstr);
	      if (metabuf != NULL) free(metabuf);
 
	      return(FAIL);
	    }

	  /* Release dataset ID */
	  /* ------------------ */
	  Dstatus       = H5Dclose(datasetid);
	  if (Dstatus == FAIL)
	    {
	      sprintf(errbuf, "Cannot close the dataset \"%s\".", fldname);
	      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (utlstr  != NULL) free(utlstr);
	      if (metabuf != NULL) free(metabuf);
			  
	      return(FAIL);
	    }          
	}
      else
	{
	  sprintf(errbuf, "\"DataType\" string not found in metadata.");
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);
			
	  return(FAIL);
	}
      /*
       * Get DimList string and trim off leading and trailing parens
       * "()"
       */
      statmeta = HE5_EHgetmetavalue(metaptrs, "DimList", utlstr); 		
      if (statmeta == SUCCEED)
	{
	  /* Initialize slen[] array */
	  /* ----------------------- */
	  for (i = 0; i < HE5_DTSETRANKMAX; i++)
	    slen[ i ] = 0;

	  memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
	  utlstr[strlen(utlstr) - 2] = 0;
			
	  /* Parse trimmed DimList string and get rank */
	  /* ----------------------------------------- */
	  ndims = HE5_EHparsestr(utlstr, ',', ptr, slen);
	  *rank = (int)ndims;
	}
      else
	{
	  sprintf(errbuf, "\"DimList\" string not found in metadata.");
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);
			
	  return(FAIL);
	}
		
      /* Get information about grid */
      /* -------------------------- */
      status = HE5_GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
      if(status == FAIL)
	{
	  sprintf(errbuf, "Cannot get information about Grid.\n");
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);

	  return(FAIL);
	}
		

      for (i = 0; i < ndims; i++)
	{
	  memmove(dimstr, ptr[i] + 1, slen[i] - 2);
	  dimstr[slen[i] - 2] = 0;
			
	  if (strcmp(dimstr, "XDim") == 0)
	    {
	      dims[i] = (hsize_t)xdim;
	    }
	  else if (strcmp(dimstr, "YDim") == 0)
	    {
	      dims[i] = (hsize_t)ydim;
	    }
	  else
	    {
	      /* Get dimension size */
	      /* ------------------ */
	      dims[i] = (hsize_t)HE5_GDdiminfo(gridID, dimstr);
	      if ( dims[i] == FAIL)
		{
		  sprintf(errbuf, "Cannot get the size of dimension.\n");
		  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(utlstr);
		  free(metabuf);
					
		  return(FAIL);
		}				
	    }
			

	  /* If DimList string is requested ... */
	  /* ---------------------------------- */
	  if (dimlist != NULL)
	    {
	      if (i == 0)
		{
		  dimlist[0] = 0;
		}

	      if (i > 0)
		{
		  strcat(dimlist, ",");
		}
	      strcat(dimlist, dimstr);
	    }
	}

	    
      /* If MaxdimList is requested ...   */  
      /* -------------------------------  */
      if (maxdimlist != NULL )
	{
	  statmeta = HE5_EHgetmetavalue(metaptrs, "MaxdimList", utlstr);
	  if (statmeta == SUCCEED)
	    {
	      memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
	      utlstr[strlen(utlstr) - 2] = 0;
				
	      /* Parse trimmed MaxdimList string and get rank */
	      /* -------------------------------------------- */
	      ndims = HE5_EHparsestr(utlstr, ',', ptr, slen);
	    }
	  else
	    {
	      sprintf(errbuf, "\"MaxdimList\" string not found in metadata.");
	      H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(utlstr);
	      free(metabuf);
				
	      return(FAIL);
	    }

	  strcpy(maxdimstr,"");
	  strcpy(maxdimlist,"");
			
	  for (i = 0; i < ndims; i++)
	    {
	      memmove(maxdimstr, ptr[i] + 1, slen[i] - 2);
	      maxdimstr[slen[i] - 2] = 0;
				
	      /* If MaxdimList string is requested ... */
	      /* ------------------------------------- */
	      if (maxdimlist != NULL)
		{
		  if (i > 0)
		    {
		      strcat(maxdimlist, ",");
		    }
		  strcat(maxdimlist, maxdimstr);
		}
	    }
			
	}
	    

      /* Get field-related dataset ID */
      /* ---------------------------- */
      status = HE5_GDgetfieldID(gridID, fldname, &fieldID);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot get the dataset ID for the \"%s\" field.\n", fldname);
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);
			
	  return(status);
	}
   	    
      /* Get data space ID */
      /* ----------------- */
      dspace = H5Dget_space( fieldID );
      if (dspace == FAIL)
	{
	  sprintf(errbuf, "Cannot get the dataspace ID for the \"%s\" field.\n", fldname);
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);
			
	  return(FAIL);
	}
	    
      /* Get dataset rank */
      /* ---------------- */
      *rank = H5Sget_simple_extent_ndims(dspace);
      if ( *rank == FAIL )
	{
	  sprintf(errbuf, "Cannot get the dataset rank for the \"%s\" field.\n", fldname);
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);
			
	  return(FAIL);
	}
	    
      /* Get dataset dimension sizes */
      /* --------------------------- */
      status = H5Sget_simple_extent_dims(dspace,dims, NULL);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot get the dataset dimension sizes for the \"%s\" field.\n", fldname);
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);
			
	  return(status);
	}

	    
      /* Release the dataspace ID */
      /* ------------------------ */
      status = H5Sclose(dspace);
      if ( status == FAIL)
	{
	  sprintf(errbuf, "Cannot release the dataset ID for the \"%s\" field.\n", fldname);
	  H5Epush(__FILE__, "HE5_GDfieldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(utlstr);
	  free(metabuf);

	  return(status);
	}
	   
   
    }
  
  free(metabuf);
  free(utlstr);
   
  metabuf = NULL;
  utlstr  = NULL;
  
 COMPLETION:
  return (status);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDtileinfo                                                   |
|                                                                             |
|  DESCRIPTION: Retrieves tiling information                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  fldname        char*               name of field                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  tilecode       int*                tile code                               |
|  tilerank       int*                number of tiling dimensions             |
|  tiledims       hsize_t             the array containing sizes              |
|                                     of each dimension of a tile             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  Date        Programmer    Description                                      |
|  =========   ============  ==============================================   |
|  Dec 03      S.Zhao        Original development                             |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDtileinfo(hid_t gridID, char *fldname, int *tilecode, int *tilerank,  hsize_t tiledims[])
{
  herr_t          status   = FAIL;/* Return status variable */
 
  hid_t           fid      = FAIL;/* HDF-EOS file ID        */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID      */
  long            idx      = FAIL;/* Grid index             */
  hid_t           fieldID  = FAIL;/* field dataset ID       */
  hid_t           plist    = FAIL;/* field dataset property list ID   */
  hid_t           dspace   = FAIL;/* "fieldname" Dataspace ID         */
 
  int             ndims    = 0;   /* Number of dimensions   */
 
  H5D_layout_t    layout = H5D_LAYOUT_ERROR; /* Storage layout type   */
 
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer */
 
 
  HE5_LOCK;
  CHECKPOINTER(fldname);
 
 
  /* Get HDF-EOS file ID, "HDFEOS" group ID and Grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDtileinfo", &fid, &gid, &idx);
  if (status == FAIL)
    {
      sprintf(errbuf,"Checking for valid grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }
 
  /* Check out the field group and get field ID */
  /* ------------------------------------------ */
  status = HE5_GDgetfieldID(gridID, fldname, &fieldID);
  if(status == FAIL)
    {
      sprintf(errbuf, "Cannot get the field ID for the \"%s\" field.\n", fldname);
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Get the property list ID */
  /* ------------------------ */
  plist = H5Dget_create_plist(fieldID);
  if (plist == FAIL)
    {
      sprintf(errbuf, "Cannot get the property list ID for the \"%s\" data field.\n", fldname);
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_PLIST, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Get the data space ID */
  /* --------------------- */
  dspace = H5Dget_space(fieldID);
  if(dspace == FAIL)
    {
      sprintf(errbuf, "Cannot get the data space ID for the \"%s\" data field.\n", fldname);
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_DATASPACE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Get the dataset rank */
  /* -------------------- */
  ndims  = H5Sget_simple_extent_ndims(dspace);
  if(ndims == FAIL)
    {
      sprintf(errbuf, "Cannot get the rank of the dataset.\n");
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Get Layout */
  /* ---------- */
  layout = H5Pget_layout(plist);
  if (layout == H5D_LAYOUT_ERROR)
    {
      sprintf(errbuf, "Cannot get the layout of the raw data. \n");
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_PLIST, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
  else if (layout == H5D_CHUNKED)
    {
      *tilecode = HE5_HDFE_TILE;

      /* Get chunking */
      /* ------------ */
      *tilerank = H5Pget_chunk(plist, ndims, tiledims);
      if (*tilerank == FAIL)
	{
	  sprintf(errbuf, "Cannot get the sizes of chunks. \n");
	  H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
    }
  else
    {
      *tilecode = HE5_HDFE_NOTILE;
      *tilerank = 0;
    }
 
  /* Release property list ID */
  /* ------------------------ */
  status = H5Pclose(plist);
  if (status == FAIL )
    {
      sprintf(errbuf, "Cannot release property list ID. \n");
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_PLIST, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Release the data space ID */
  /* ------------------------- */
  status = H5Sclose(dspace);
  if( status == FAIL)
    {
      sprintf(errbuf, "Cannot release the data space ID.\n");
      H5Epush(__FILE__, "HE5_GDtileinfo", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
 
 COMPLETION:
  HE5_UNLOCK;
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeffield                                                   |
|                                                                             |
|  DESCRIPTION: Defines a new data field within the grid.                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               fieldname                               |
|  dimlist        char*               Dimension list (comma-separated list)   |
|  maxdimlist     char*               Maximum Dimension list                  |
|  ntype          hid_t               Data type ID of the field               |
|  merge          int                 merge code                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Tequal                                                        |
|             H5Pget_layout                                                   |
|             H5Screate_simple                                                |
|             H5Dcreate                                                       |
|             H5Dextend                                                       |
|             H5Tget_size                                                     |
|             H5Pget_fill_value                                               |
|             H5Pclose                                                        |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/20/99  A.Muslimov    In the call to EHinsertmeta() replaced the argument |
|                         gid by fid. Added error handling after the function |
|                         calls. In the call to H5Dcreate() replaced the first|
|                         argument by gd_id (data field group ID).            |
|  9/30/99  A.Muslimov    Added more error handlings after the function calls.|
|                         Removed 'if(status == -1){}' block from the         |
|                         'if((tilecode == HDFE_TILE ){}' block.              |
|  10/18/99 A.Muslimov    Replace memcpy() by memmove() to avoid a problem    |
|                         when arguments 1 and 2 overlap in memory.           |
| 10/18/99  A.Taaheri     Replaced strcpy() by memmove() to avoid a problem   |
|                         when arguments 1 and 2 overlap in memory.           |
| Jan 2000  A.Muslimov    Modified to enable the functioning of routines      |
|                         dealing with extendible datsets.                    |
| Mar,2000  A.Muslimov    Changed the ID of field group from gd_id to         |
|                         data_id.                                            |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| Nov 2000  A.Muslimov    Modified to enable appendability of any dimension.  |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  Aug  03  S.Zhao        Added checking for SOMBlockDim in the dimlist.      |
|  Aug  03  S.Zhao        Added Szip compression methods.                     |
|  Jan  04  S.Zhao        Added to create a character string dataset.         |
|  Mar  04  S.Zhao        Modified for a character string dataset.            |
|  Apr  04  S.Zhao        Modified for a character string dataset.            |
|  May  04  S.Zhao        Added to check in the maxdimlist section for "XDim" |
|                         set to xdimsize and "YDim" set to ydimsize.         |
|  May  05  S.Zhao        Added HE5_EHdtype2numtype() and HE5_EHhid2hsize()   |
|                         functions calls.                                    |
|  Aug  08  Abe Taaheri   Fixed problem with fillvalue setting. Value set for |
|                         fillvalue is used only in the field that intended.  |
|                         It must be set before defining the field.           |
|  Sep  11  Abe Taaheri   Modified for correcting Unlimited dimension         |
|                         behavior and extension, removing hardcoded name     |
|                         Unlim                                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDdeffield(hid_t gridID, const char *fieldname, char *dimlist, char *maxdimlist, hid_t numbertype_in, int merge)
{

  herr_t          status      = FAIL; /* routine return status variable */

  hid_t           fid         = FAIL; /* HDF-EOS file ID                */
  hid_t           gid         = FAIL; /* "HDFEOS" group ID              */ 
  hid_t           data_id     = FAIL; /* "Data Fields" group ID         */          
  hid_t           dataset     = FAIL; /* dataset ID                     */
  hid_t           data_space  = FAIL; /* dataspace ID                   */

  int             i;		      /* Loop index                     */
  int             found       = 0;    /* "Found" flag                   */
  int             foundNT     = 0;    /* "Found number type" flag       */
  int             foundAllDim = 1;    /* "Found all dimensions" flag    */
  int             first       = 1;    /* "First entry" flag             */
  int             append      = FALSE;/* "Appendability" flag           */
  int             tilecode    = FAIL; /* Tiling code                    */
  int             projcode    = FAIL; /* Projection Code                */
  int             rank        = 0;    /* Field rank                     */
  int             maxrank     = 0;    /* Maximum dimension  rank        */

  long            idx         = FAIL; /* Grid index                     */
  long            xdim        = 0;    /* Grid "X" dimension size        */
  long            ydim        = 0;    /* Grid "Y" dimension size        */

  hsize_t         dims[HE5_DTSETRANKMAX];   /* Dimension size array     */
  hsize_t         maxdims[HE5_DTSETRANKMAX];/* Max.Dimension size array */
  hsize_t         count[]     = { 1 } ;	    /* Number of elements array */
  hsize_t         dimsize     = 0;	    /* Dimension size           */
    
  double          projparm[13];	            /* Projection Parameters    */

  H5D_layout_t    layout = H5D_LAYOUT_ERROR;/* Type of storage ID       */

  void            *value;	            /* Fill value buffer        */

  size_t          tsize = 0;	            /* Size of a data type      */

  char            compmethod[HE5_HDFE_NAMBUFSIZE];/* Compression code            */
  char            *dimbuf   = (char *)NULL;       /* Dimension buffer            */
  char            *dimlist0 = (char *)NULL;       /* Auxilliary dimension list   */
  char            *comma    = (char *)NULL;       /* Pointer to ","              */
  char            *dimcheck = (char *)NULL;       /* Individual dimen. string    */
  char            *utlbuf   = (char *)NULL;       /* Utility buffer              */
  char            *utlbuf2  = (char *)NULL;       /* Utility buffer 2            */
  char            gridname[HE5_HDFE_NAMBUFSIZE];  /* Grid name buffer            */
  char            parmbuf[HE5_HDFE_NAMBUFSIZE];	  /* Parameter string buffer     */
  char            *errbuf1  = (char *)NULL;       /* Error message buffer #1     */
  char            *errbuf2  = (char *)NULL;       /* Error message buffer #2     */
  char            *errmsg1  = "Dimension: %d (size: %lu) not divisible by ";
  char            *errmsg2  = "tile dimension (size:  %lu).\n";
  char            *errmsg   = (char *)NULL;        /* Tiling error message       */
  /*  char            *HDFcomp[5] = {"HE5_HDFE_COMP_NONE", "HE5_HDFE_COMP_RLE","HE5_HDFE_COMP_NBIT", "HE5_HDFE_COMP_SKPHUFF","HE5_HDFE_COMP_DEFLATE"};                      Compression code names */
  char            compparmbuf[HE5_HDFE_NAMBUFSIZE]; /* Compression string buffer */
  char            maxdimlstbuf[HE5_HDFE_NAMBUFSIZE];/* Max.Dimension list buffer */
  char            *errbuf   = (char *)NULL;         /* Error message buffer      */
  char            *nameptr = (char *)NULL;
  char            tempname[HE5_HDFE_NAMBUFSIZE];
  hid_t           numbertype = FAIL;                /* Number type ID            */
  int             attr      = 0;                    /* attribute value           */

  H5D_fill_value_t fill_status;      /* to see if fill value is set or not  */

  hid_t           numtype   = FAIL;
  hsize_t         metavalue = 0;                    /* Metavalue to insert       */
  hid_t           ntype;
  H5T_class_t     classid = H5T_NO_CLASS;


  HE5_LOCK;
  CHECKNAME(fieldname);
  CHECKPOINTER(dimlist);
  	
  /* assuming that fillvalue is undefined for the field */
  fill_status = H5D_FILL_VALUE_UNDEFINED;
 
  /* Convert HDF-EOS5 datatype to HDF5 datatype */
  if (
      H5Tequal(numbertype_in, H5T_NATIVE_CHAR)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_USHORT) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_INT)    == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UINT)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LONG)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULLONG) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)== SUCCEED ||
      H5Tequal(numbertype_in, H5T_C_S1) == SUCCEED)
    {
      ntype = numbertype_in;
    }
  else
    {
      ntype = HE5_EHconvdatatype((int) numbertype_in);
    }

  if(ntype == FAIL)
    {
      sprintf(errbuf,"Cannot convert to HDF5 type data type ID for defining field.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  errbuf1 = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf1 == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for error buffer1.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
     
      return(FAIL);
    }

  errbuf2 = (char *)calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf2 == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for error buffer2.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
		
      return(FAIL);
    }

  /* Allocate memory for tiling error message */
  /* ---------------------------------------- */
  errmsg  = (char *)calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errmsg == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for tiling error message.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);

      return(FAIL);
    }

  /* Setup error message strings */
  /* --------------------------- */
  strcpy(errbuf1, "HE5_GDXSDname array too small.\nPlease increase ");
  strcat(errbuf1, "size of HE5_HDFE_NAMBUFSIZE in \"HE5_HdfEosDef.h\".\n");
  strcpy(errbuf2, "HE5_GDXSDdims array too small.\nPlease increase ");
  strcat(errbuf2, "size of HE5_HDFE_DIMBUFSIZE in \"HE5_HdfEosDef.h\".\n");

  /* Build tiling dimension error message */
  /* ------------------------------------ */
  strcpy(errmsg, errmsg1);
  strcat(errmsg, errmsg2);

  /* Initialize dims and maxdims arrays */
  /* ---------------------------------- */
  for(i = 0; i < HE5_DTSETRANKMAX; i++)
    {
      dims[i]    = 0;
      maxdims[i] = 0;
    }
  
  /* Initialize projparm[] array */
  /* --------------------------- */
  for ( i = 0; i < 13; i++)
    projparm[ i ] = 0.;
	

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdeffield", &fid, &gid, &idx);
  if(status == FAIL)
    {
      sprintf(errbuf,"Checking for Grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
		
      return(FAIL);
    }

  /* Allocate memory for utility buffers */
  /* ----------------------------------- */
  utlbuf   = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if( utlbuf == NULL )
    {
      sprintf(errbuf,"Can not allocate memory for utility buffer.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
		
      return(FAIL);
    }
  utlbuf2  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if( utlbuf2 == NULL )
    {
      sprintf(errbuf,"Can not allocate memory for utility buffer2.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
		
      return(FAIL);
    }
	
  strcpy(gridname, HE5_GDXGrid[idx].gdname);
	
  /* Allocate space for dimension buffer and auxilliary dimension list */
  /* ----------------------------------------------------------------- */
  dimbuf = (char *)calloc(strlen(dimlist) + 64, sizeof(char));
  if(dimbuf == NULL)
    {
      sprintf(errbuf,"Can not allocate memory for dimension buffer.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
      free(utlbuf2);
    
      return(FAIL);
    }

  dimlist0 = (char *)calloc(strlen(dimlist) + 64, sizeof(char));
  if(dimlist0 == NULL)
    {
      sprintf(errbuf,"Can not allocate memory for dimension list string.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
      free(utlbuf2);
      free(dimbuf);

      return(FAIL);
    }

  status = HE5_GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot get information about Grid.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
      free(utlbuf2);
      free(dimbuf);
      free(dimlist0);
		
      return(FAIL);
    }

 /* Get Grid and Projection info */
  /* ---------------------------- */	
  status = HE5_GDprojinfo(gridID, &projcode, NULL, NULL, projparm);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot get Grid projection information.\n");  
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
      free(utlbuf2);
      free(dimbuf);
      free(dimlist0);
		
      return(FAIL);
    }


  /* Setup Block Dimension if "Blocked" SOM projection */
  /* ------------------------------------------------- */
  if (projcode == HE5_GCTP_SOM && (long)projparm[11] != 0)
    {
      dimsize = HE5_GDdiminfo(gridID, "SOMBlockDim");
		
      /* If "SOMBlockDim" not yet defined then do it */
      if (dimsize == 0)
	{
	  status = HE5_GDdefdim(gridID, "SOMBlockDim", (hsize_t)projparm[11]);
	  if(status == FAIL)
	    {
	      sprintf(errbuf,"Cannot define \"SOMBlockDim\" dimension.\n");  
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      free(dimbuf);
	      free(dimlist0);

	      return(FAIL);
	    }
			
	}
		
      /* If not 1D field then prepend to dimension list */
      if (strchr(dimlist, ',') != NULL)
	{
	  strcpy(tempname, dimlist);
	  nameptr = strchr( tempname, ',' );
	  if ( nameptr != NULL )
	    {
	      nameptr[0] = '\0';
	    }
 
	  if ( strcmp(tempname, "SOMBlockDim") != 0)
	    {
	      strcpy(dimbuf, "SOMBlockDim,");
	      strcat(dimbuf, dimlist);
	    }
	  else
	    {
	      strcpy(dimbuf, dimlist);
	    }
	}
      else
	{
	  strcpy(dimbuf, dimlist);
	}
    }
  else
    {
      /* If not "Blocked" SOM then just copy dim list to dim buffer */
      strcpy(dimbuf, dimlist);
    }

  /*
   * Copy dimension buffer to auxilliary dimlist and Append comma to
   * end of dimension list
   */
  strcpy(dimlist0, dimbuf);
  strcat(dimbuf, ",");


  /* Find comma */
  /* ---------- */
  comma = strchr(dimbuf, ',');
	
  /*
   * Loop through entries in dimension list to make sure they are
   * defined in grid
   */
  while (comma != NULL)
    {
      /* Copy dimension list entry to dimcheck */
      /* ------------------------------------- */
      dimcheck = (char *)calloc(comma - dimbuf + 1, sizeof(char));
      if(dimcheck == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory.\n");
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if(dimbuf != NULL) free(dimbuf);
	  if(dimlist0 != NULL) free(dimlist0);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);

	  return(FAIL);
	}
      memmove(dimcheck, dimbuf, comma - dimbuf);
		
      /* Get Dimension Size */
      /* ------------------ */
      if (strcmp(dimcheck, "XDim") == 0)
	{
	  /* If "XDim" then use xdim value for grid definition */
	  /* ------------------------------------------------- */
	  dimsize = (hsize_t)xdim;
	  found = 1;
	  dims[ rank ] = dimsize;
	  rank++;
	}
      else if (strcmp(dimcheck, "YDim") == 0)
	{
	  /* If "YDim" then use ydim value for grid definition */
	  /* ------------------------------------------------- */
	  dimsize = (hsize_t)ydim;
	  found = 1;
	  dims[ rank ] = dimsize;
	  rank++;
	}
      else
	{
	  /* "Regular" Dimension */
	  /* ------------------- */
	  dimsize = HE5_GDdiminfo(gridID, dimcheck);
	  if (dimsize > 0)
	    {
	      found = 1;
	      dims[ rank ] = dimsize;
	      rank++;
	    }
	  else
	    {
	      found = 0;
	    }
	}

      /*
       * If dimension list entry not found - set error return status,
       * append name to utility buffer for error report
       */
      if (found == 0)
	{
	  foundAllDim = 0;
	  if (first == 1)
	    {
	      strcpy(utlbuf, dimcheck);
	    }
	  else
	    {
	      strcat(utlbuf, ",");
	      strcat(utlbuf, dimcheck);
	    }
	  first = 0;
	}
	  
      /*
       * Go to next dimension entry, find next comma, & free up
       * dimcheck buffer
       */
      memmove(dimbuf, comma + 1, strlen(comma)-1);
      dimbuf[strlen(comma)-1]= 0;
      comma = strchr(dimbuf, ',');
      if(dimcheck != NULL) free(dimcheck);
    }
  if(dimbuf != NULL) free(dimbuf);
	
	
  /* If all dimensions not found then report error */
  /* --------------------------------------------- */
  if (foundAllDim == 0)
    {
      status = FAIL;
      sprintf(errbuf, "Cannot find dimensions for \"%s\" field.\n", fieldname);
      H5Eclear();
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FILE, H5E_SEEKERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (dimlist0 != NULL) 
	free(dimlist0);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
      free(utlbuf2);
		
      return (status);
    }

  /* Check maxdimlist  */
  /* Allocate space for dimbuf, copy dimlist into it, & append comma */
  /*----------------------------------------------------------------*/
  if(maxdimlist != NULL)
    {
      dimbuf = (char *)calloc(strlen(maxdimlist) + 64, sizeof(char));
      strcpy(dimbuf, maxdimlist);
      strcat(dimbuf, ",");
		
      /* Find comma */
      comma = strchr(dimbuf, ',');
		
      /*
       * Loop through entries in dimension list to make sure they are
       * defined in grid
       */
      while (comma != NULL)
	{
	  /* Copy dimension list entry to dimcheck buffer */
	  /* -------------------------------------------- */
	  dimcheck = (char *)calloc(comma - dimbuf + 1, sizeof(char));
	  if(dimcheck == NULL)
	    {
	      sprintf(errbuf, "Cannot allocate memory.\n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (dimbuf != NULL) 
		free(dimbuf);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
				
	      return(FAIL);
	    }
	  memmove(dimcheck, dimbuf, comma - dimbuf);
			
	  /* Get dimension size */
	  /* ------------------ */
	  if (strcmp(dimcheck, "XDim") == 0)
	    {
	      /* If "XDim" then use xdim value for grid definition */
	      /* ------------------------------------------------- */
	      dimsize = (hsize_t)xdim;
	      maxdims[ maxrank ] = dimsize;
	      maxrank++;
	    }
	  else if (strcmp(dimcheck, "YDim") == 0)
	    {
	      /* If "YDim" then use ydim value for grid definition */
	      /* ------------------------------------------------- */
	      dimsize = (hsize_t)ydim;
	      maxdims[ maxrank ] = dimsize;
	      maxrank++;
	    }
	  else
	    {
	      dimsize = HE5_GDdiminfo(gridID, dimcheck);
	      if ( (dimsize > 0) || (dimsize == H5S_UNLIMITED)  )
		{
		  maxdims[ maxrank ] = dimsize;
		  maxrank++;
		}
	      else
		{
		  /*
		   * If dimension list entry not found - set error return
		   * status, append name to utility buffer for error report
		   */
		  foundAllDim = 0;
		  if (first == 1)
		    strcpy(utlbuf, dimcheck);
		  else
		    {
		      strcat(utlbuf, ",");
		      strcat(utlbuf, dimcheck);
		    }
		  first = 0;
		}
	    }
			
			
	  /*
	   * Go to next dimension entry, find next comma, & free up
	   * dimcheck buffer
	   */

	  memmove(dimbuf, comma + 1, strlen(comma + 1) + 1); 
	  comma = strchr(dimbuf, ',');
	  if (dimcheck != NULL) free(dimcheck);
        }
		
      if(dimbuf != NULL) free(dimbuf);

      /* If all dimensions not found then report error */
      /* --------------------------------------------- */
      if (foundAllDim == 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "Cannot find dimensions for \"%s\" field.\n", fieldname);
	  H5Eclear();
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FILE, H5E_SEEKERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);
	  if (dimlist0 != NULL)
	    free(dimlist0);
		  
	  return(status);	 
        }
		

    } /* end if */
	
  /* max dimmension equal to dims */
  else
    {
      for(i = 0; i < rank; i++ )
	maxdims[ i ] = dims[ i ];
    }

	
  /* Check out if dataset dimension is appendable */
  /* -------------------------------------------- */
  for(i = 0; i < rank; i++)
    {
      if(   dims[i] == maxdims[i] )
	append = FALSE;
      else if ( (dims[i] < maxdims[i]) || (maxdims[i] == H5S_UNLIMITED))
	{
	  append = TRUE;
	  break;
	}
      else
	{
	  status = FAIL;
	  sprintf(errbuf, "Maximum dimension size is smaller than dimension size.\n");
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);
	  if (dimlist0 != NULL)
	    free(dimlist0);
			  
	  return(status);
	}
    } 
	

  /* Check for valid data type ID  */
  /* ----------------------------- */
  if (ntype == HE5T_CHARSTRING)
    {
      foundNT=1;
    }
  else
    {
      if (H5Tequal(ntype, H5T_NATIVE_CHAR))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_UCHAR))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_SHORT))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_USHORT))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_INT))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_UINT))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_LONG))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_ULONG))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_LLONG))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_ULLONG))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_FLOAT))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_DOUBLE))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_NATIVE_LDOUBLE))
	foundNT=1;
      else if (H5Tequal(ntype, H5T_C_S1))
        foundNT=1;
      else
	foundNT=0;
    }
	
  classid    = H5Tget_class(ntype);
  if( foundNT == 0 && classid == H5T_STRING)
    {
      /* we have string datatype H5T_C_S1  with a size larger than 1 */
      foundNT=1;
    }

  if (foundNT == 0)
    {
      status = FAIL;
      sprintf(errbuf, "Invalid number type for \"%s\" field.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_DATATYPE, H5E_BADTYPE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(errbuf1);
      free(errbuf2);
      free(errmsg);
      free(utlbuf);
      free(utlbuf2);
      if (dimlist0 != NULL)
	free(dimlist0);
			
      return(status);
    }
	
  if (status == SUCCEED)
    {
      /* Get Field group ID, compresion code, & tiling code */
      /* -------------------------------------------------- */
      data_id = HE5_GDXGrid[idx].data_id;
      strcpy(compmethod, HE5_GDXGrid[idx].compmethod);
      tilecode = HE5_GDXGrid[idx].tilecode;

      /* Check that field dims are divisible by tile dims */
      /* ------------------------------------------------ */
      if (tilecode == HE5_HDFE_TILE)
	{
	  for (i = 0; i < HE5_GDXGrid[idx].tilerank; i++)
	    {
	      if ((dims[ i ] % HE5_GDXGrid[ idx ].tiledims[ i ]) != 0)
		{
		  status = FAIL;
		  sprintf(errbuf, errmsg, i, (unsigned long)dims[i],(unsigned long)HE5_GDXGrid[idx].tiledims[i]);
		  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(errbuf1);
		  free(errbuf2);
		  free(errmsg);
		  free(utlbuf);
		  free(utlbuf2);
		  if (dimlist0 != NULL)
		    free(dimlist0);
					
		  return(status);
		}
	    }
			
	}
		

      /*      Create dataspace then create dataset       */
      /* dataset creation property is not set outside by */
      /*         GDdefchunksize() or GDdefcom()          */
		

      if(HE5_GDXGrid[ idx ].plist == FAIL)
	{
	  HE5_GDXGrid[ idx ].plist = H5Pcreate(H5P_DATASET_CREATE);
	  if(HE5_GDXGrid[ idx ].plist == FAIL)
	    {
	      sprintf(errbuf,"Cannot create a new property list.\n");  
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
				
	      return(FAIL);
	    }
	}
		
      /* Get layout information */
      /* ---------------------- */		
      layout = H5Pget_layout(HE5_GDXGrid[ idx ].plist);
      if(layout == H5D_LAYOUT_ERROR)
	{
	  sprintf(errbuf,"Cannot get layout information for the dataset.\n");  
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);
	  if (dimlist0 != NULL)
	    free(dimlist0);
			
	  return(FAIL);
	}
		

      if(append == FALSE)
	{
	  data_space = H5Screate_simple(rank, dims, NULL);
	  if(data_space == FAIL)
	    {
	      sprintf(errbuf,"Cannot create dataspace for the dataset.\n");  
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
				
	      return(FAIL);
	    }
	}
      else
	{
	  if( layout == H5D_CHUNKED)
	    {
	      data_space = H5Screate_simple(rank, dims, maxdims);
	      if(data_space == FAIL)
		{
		  sprintf(errbuf,"Cannot create dataspace for the dataset.\n");  
		  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(errbuf1);
		  free(errbuf2);
		  free(errmsg);
		  free(utlbuf);
		  free(utlbuf2);
		  if (dimlist0 != NULL)
		    free(dimlist0);
							
		  return(FAIL);
		}
	    }
	  else
	    {
	      status = FAIL;
	      sprintf(errbuf, "Dataset MUST BE CHUNKED if it is extendible.\n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_DATASPACE, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
						
	      return(status);
	    }
	}

      /* Note: in inquiry routines HE5T_CHARSTRING is distinguished 
	 from HE5T_NATIVE_CHAR for the field data (not attributes) based
	 on whether string has variable or fixed length as set below.
	 The field data of type HE5T_NATIVE_CHAR has fixed length of 1, and
	 the field is array of characters, not strings. However, HE5T_CHARSTRING
	 sets array of vaiable length strings for the field data.
	 Currently HE5_EHattr treats HE5T_NATIVE_CHAR, HE5T_CHARSTRING, and
	 H5T_C_S1 as fixed (any size) for attributes. 
      */
	
      numbertype = ntype;
      if (ntype == HE5T_CHARSTRING)
	{
	  numbertype = H5Tcopy(H5T_C_S1);
	  status = H5Tset_size(numbertype, H5T_VARIABLE);
	  if( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set the total size for \"%s\" field. \n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      return(status);
	    }

	  /* Create dataset */
	  /* -------------- */
	  dataset = H5Dcreate(data_id, fieldname, numbertype, data_space, HE5_GDXGrid[ idx ].plist);
	  if (dataset == FAIL)
	    {
	      sprintf(errbuf, "Cannot create dataset for \"%s\" field. \n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
                free(dimlist0);
	      return(FAIL);
	    }
	}
      else if (/*numbertype == H5T_C_S1*/ classid == H5T_STRING && (int)H5Tget_size((hid_t)numbertype) > 1)
	{

	  /*
	  numbertype = H5Tcopy(H5T_C_S1);
	  status = H5Tset_size(numbertype, H5T_VARIABLE);
	  if( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set the total size for \"%s\" field. \n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      return(status);
	    }
	  */

	  /* Create dataset */
	  /* -------------- */
	  dataset = H5Dcreate(data_id, fieldname, numbertype, data_space, HE5_GDXGrid[ idx ].plist);
	  if (dataset == FAIL)
	    {
	      sprintf(errbuf, "Cannot create dataset for \"%s\" field. \n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
                free(dimlist0);
	      return(FAIL);
	    }
	}
      else if (numbertype == H5T_NATIVE_CHAR)
	{
	  numbertype = H5Tcopy(H5T_C_S1);
	  status = H5Tset_size(numbertype, 1);
	  if( status == FAIL)
	    {
	      sprintf(errbuf, "Cannot set the total size for \"%s\" field. \n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      return(status);
	    }

	  /* Create dataset */
	  /* -------------- */
	  dataset = H5Dcreate(data_id, fieldname, numbertype, data_space, HE5_GDXGrid[ idx ].plist);
	  if (dataset == FAIL)
	    {
	      sprintf(errbuf, "Cannot create dataset for \"%s\" field. \n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
                free(dimlist0);
	      return(FAIL);
	    }
	}
      else
	{
	  /* Create dataset */
	  /* -------------- */

	  dataset = H5Dcreate(data_id, fieldname, ntype, data_space, HE5_GDXGrid[ idx ].plist);
	  if(dataset == FAIL)
	    {
	      sprintf(errbuf, "Cannot create dataset \"%s\".\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
			
	      return(FAIL);
	    }
	}
		
      /* Extend dataset. Assure that dataset is at least dims */
      /* ---------------------------------------------------- */
      if(append == TRUE)
	{
	  status = H5Dextend(dataset,dims);
	  if(status == FAIL)
	    {
	      sprintf(errbuf,"Cannot extend the dataset.\n");  
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
				
	      return(status);
	    }
	}
		
      /* Allocate space for the ID array */
      /* ------------------------------- */
      if (HE5_GDXGrid[idx].nDFLD > 0)
	{
	  /* Array already exists therefore reallocate */
	  /* ----------------------------------------- */
	  HE5_GDXGrid[idx].ddataset = (HE5_DTSinfo *) realloc((void *)HE5_GDXGrid[idx].ddataset,(HE5_GDXGrid[idx].nDFLD + 1) * sizeof(HE5_DTSinfo));
	  if(HE5_GDXGrid[idx].ddataset == NULL)
	    {
	      sprintf(errbuf,"Cannot reallocate memory for the dataset.\n"); 
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
				
	      return(FAIL);
	    }
	}
      else
	{
	  /* Array does not exist */
	  /* -------------------- */
	  HE5_GDXGrid[idx].ddataset = (HE5_DTSinfo *) calloc(1, sizeof(HE5_DTSinfo));
	  if(HE5_GDXGrid[idx].ddataset == NULL)
	    {
	      sprintf(errbuf,"Cannot allocate memory for the dataset.\n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
				
	      return(FAIL);
	    }
	}

      /* Allocate memory for the dataset name string */
      /* ------------------------------------------- */
      HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name = (char *)calloc( (strlen(fieldname)+1), sizeof(char) );
      if(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory for the dataset name string.\n");
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);
	  if (dimlist0 != NULL)
	    free(dimlist0);
	  free(HE5_GDXGrid[idx].ddataset);
			
	  return(FAIL);
	}

      /* Save the field/dataset ID and field/dataset name */
      /* ------------------------------------------------ */
      HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].ID = dataset;
      strcpy( HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name, fieldname);
		
      HE5_GDXGrid[idx].nDFLD++;
		
      if ((ntype != HE5T_CHARSTRING) && (ntype != H5T_NATIVE_CHAR) && (ntype != H5T_C_S1))
	{
	  /* Get the data size (bytes) */
	  /* ------------------------- */
	  tsize = H5Tget_size(ntype);

	  /* Allocate memory for the fillvalue buffer */
	  /* ---------------------------------------- */
	  value = (void *)calloc( 1,  tsize );
	  if(value == (void *)NULL)
	    {
	      sprintf(errbuf,"Cannot allocate memory for the \"value\" variable.\n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      free(HE5_GDXGrid[idx].ddataset);
	      free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
			
	      return(FAIL);
	    }


	  /* Try to get fill value */
	  /* --------------------- */
	  H5E_BEGIN_TRY {
	    status = H5Pfill_value_defined(HE5_GDXGrid[idx].plist, &fill_status );
	  }
	  H5E_END_TRY;
	  if (fill_status == H5D_FILL_VALUE_USER_DEFINED)
	    {
	      H5E_BEGIN_TRY {
		status = H5Pget_fill_value( HE5_GDXGrid[idx].plist,  ntype,  value);
	      }
	      H5E_END_TRY;
	      
	      /* Store fill value in the dataset attribute "_FillValue" */
	      /* -----------------------------------------------------  */ 
	      if( status != FAIL )
		{
		  status = HE5_EHattr( dataset, "_FillValue", ntype, count, "w", value);
		  if(status == FAIL)
		    {
		      sprintf(errbuf, "Cannot write fill value to the \"_FillValue\" attribute.\n");
		      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(errbuf);
		      free(errbuf1);
		      free(errbuf2);
		      free(errmsg);
		      free(utlbuf);
		      free(utlbuf2);
		      if (dimlist0 != NULL) free(dimlist0);
		      free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
		      free(HE5_GDXGrid[idx].ddataset);
		      free(value);
		      return(FAIL);
		    }
		}
	    }
	  free( value);
		
	}

/* 
************************************************************
*             SET  UP  METADATA   STRINGS                  *
************************************************************
*/
	  
	  
      /* set up "DimList" string content */
      /* ------------------------------- */
      strcpy(utlbuf,"");
      sprintf(utlbuf, "%s%s%s", fieldname, ":", dimlist0);
		
      /* set up max dim list string */
      /* -------------------------- */
      if ( maxdimlist != NULL)
	{
	  /* Make metadata string list for max dimension list */
	  /* ------------------------------------------------ */
	  strcpy(utlbuf2,"");
	  strcpy(maxdimlstbuf,"");
	  status = HE5_EHmetalist(maxdimlist , maxdimlstbuf);
	  if(status == FAIL)
	    {
	      sprintf(errbuf, "Cannot make metadata string list for the max dimension list.\n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
	      free(HE5_GDXGrid[idx].ddataset);
				
	      return(FAIL);
	    }
	  sprintf(utlbuf2,"%s%s",":\n\t\t\t\tMaxdimList=",maxdimlstbuf);
	  strcat(utlbuf,utlbuf2);
	}
      if ( maxdimlist == NULL )
	{
	  strcpy(utlbuf2,"");
	  strcpy(maxdimlstbuf,"");
	  status = HE5_EHmetalist(dimlist0, maxdimlstbuf);
	  if(status == FAIL)
	    {
	      sprintf(errbuf, "Cannot make metadata string list for the max dimension list.\n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
	      free(HE5_GDXGrid[idx].ddataset);
				
	      return(FAIL);
	    }
	  sprintf(utlbuf2,"%s%s",":\n\t\t\t\tMaxdimList=",maxdimlstbuf);
	  strcat(utlbuf,utlbuf2);
	}
		
      /* Setup compression metadata */
      /* -------------------------- */
      strcpy(compmethod, HE5_GDXGrid[idx].compmethod);
		
      if ( strcmp(compmethod,  "HE5_HDFE_COMP_NONE" ) != 0 )
	{
	  if(maxdimlist != NULL)
	    {
	      sprintf(utlbuf2, "%s%s", "\n\t\t\t\tCompressionType=", compmethod);
	    }
	  else
	    {
	      sprintf(utlbuf2, "%s%s", "\n\t\t\t\tCompressionType=", compmethod);
	    }
			
	  if( strcmp(compmethod,"HE5_HDFE_COMP_NBIT") == 0 )
	    {
	      strcpy(compparmbuf,""); 
	      sprintf(compparmbuf, "%s%d,%d,%d,%d%s","\n\t\t\t\tCompressionParams=(", HE5_GDXGrid[idx].compparm[0], HE5_GDXGrid[idx].compparm[1], HE5_GDXGrid[idx].compparm[2], HE5_GDXGrid[idx].compparm[3], ")");
	      strcat(utlbuf2, compparmbuf);
	    }
			
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_DEFLATE") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tDeflateLevel=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SZIP_CHIP") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SZIP_K13") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SZIP_EC") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SZIP_NN") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SZIP_K13orEC") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SZIP_K13orNN") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }

	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_DEFLATE") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tDeflateLevel=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_SZIP_CHIP") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_SZIP_EC") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_SZIP_NN") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13orEC") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  else if ( strcmp(compmethod, "HE5_HDFE_COMP_SHUF_SZIP_K13orNN") == 0)
	    {
	      strcpy(compparmbuf,"");
	      sprintf(compparmbuf,"%s%d","\n\t\t\t\tBlockSize=", HE5_GDXGrid[idx].compparm[0]);
	      strcat(utlbuf2, compparmbuf);
	    }
 
	  /* Append compression parameters with compression code */
	  /* --------------------------------------------------- */
	  strcat(utlbuf, utlbuf2);
	}
		
      /* Setup tiling information metadata */
      /* --------------------------------- */
      if (tilecode == HE5_HDFE_TILE)
	{
	  if ( strcmp(compmethod,  "HE5_HDFE_COMP_NONE" ) != 0 )
	    {
	      strcpy(utlbuf2,"");
	      sprintf(utlbuf2,"%s%li","\n\t\t\t\tTilingDimensions=(", (long)HE5_GDXGrid[idx].tiledims[0]);
	    }
	  else
	    {
	      strcpy(utlbuf2,"");
	      sprintf(utlbuf2, "%s%li","\n\t\t\t\tTilingDimensions=(", (long)HE5_GDXGrid[idx].tiledims[0]);
	    }
			
	  for (i = 1; i < HE5_GDXGrid[idx].tilerank; i++)
	    {
	      sprintf(parmbuf, ",%li", (long)HE5_GDXGrid[idx].tiledims[ i ]);
	      strcat(utlbuf2, parmbuf);
	    }
	  strcat(utlbuf2, ")");
	  strcat(utlbuf, utlbuf2);
	}
		
      if (classid == H5T_STRING && (int)H5Tget_size((hid_t)numbertype) > 1)
	{
	  ntype = H5T_C_S1;
	}
      
      numtype = HE5_EHdtype2numtype(ntype);

      if (numtype == FAIL)
	{
	  sprintf(errbuf, "Cannot get the number type ID. \n");
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);
	  if (dimlist0 != NULL)
	    free(dimlist0);
	  free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
	  free(HE5_GDXGrid[idx].ddataset);

	  return(FAIL);
	}
      else if (numtype == 0)
	{
	  metavalue = 0;
	}
      else
	{

	  metavalue = HE5_EHhid2hsize(numtype);

	  if (metavalue == 0)
	    {
	      sprintf(errbuf, "Cannot convert \"hid_t\" to \"hsize_t\" data type. \n");
	      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(errbuf1);
	      free(errbuf2);
	      free(errmsg);
	      free(utlbuf);
	      free(utlbuf2);
	      if (dimlist0 != NULL)
		free(dimlist0);
	      free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
	      free(HE5_GDXGrid[idx].ddataset);

	      return(FAIL);
	    }
	}

      /* Insert field metadata within File Structural Metadata */
      /* ----------------------------------------------------- */
      status = HE5_EHinsertmeta(fid, gridname, "g", 4L, utlbuf, &metavalue);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot insert metadata.\n");
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(errbuf1);
	  free(errbuf2);
	  free(errmsg);
	  free(utlbuf);
	  free(utlbuf2);
	  if (dimlist0 != NULL)
	    free(dimlist0);
	  free(HE5_GDXGrid[idx].ddataset[HE5_GDXGrid[idx].nDFLD].name);
	  free(HE5_GDXGrid[idx].ddataset);
			
	  return(FAIL);
	}
    }
	
  /* Release the property list ID */
  /* ---------------------------- */

  status = H5Pclose(HE5_GDXGrid[idx].plist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot release the property list ID.\n");
      H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_PLIST, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }	

  /* Reset property list ID */
  /* ---------------------- */

  HE5_GDXGrid[idx].plist = FAIL;
  strcpy(HE5_GDXGrid[idx].compmethod,"HE5_HDFE_COMP_NONE");
  HE5_GDXGrid[idx].tilecode         = HE5_HDFE_NOTILE;

  if (dimlist0 != NULL) free(dimlist0);
  if (utlbuf   != NULL) free(utlbuf);
  if (utlbuf2  != NULL) free(utlbuf2);
  if (errbuf   != NULL) free(errbuf);
  if (errbuf1  != NULL) free(errbuf1);
  if (errbuf2  != NULL) free(errbuf2);
  if (errmsg   != NULL) free(errmsg);

  if ((ntype == HE5T_CHARSTRING) || (ntype == H5T_C_S1))
    {
      attr = HE5T_CHARSTRING;
      status = HE5_GDwritelocattr(gridID, fieldname, "ARRAYOFSTRINGS", H5T_NATIVE_INT, count, &attr);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot write attribute to the field \"%s\".",fieldname) ;
	  H5Epush(__FILE__, "HE5_GDdeffield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
 
    }

 COMPLETION:
  HE5_UNLOCK;
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDupdatedim                                                  |
|                                                                             |
|  DESCRIPTION: Updates numerical value of dimension                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  swathID        hid_t               Grid structure ID                       |
|  dimname        char*               Dimension name                          |
|  dim            hsize_t             Dimension size                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date      Programmer   Description                                        |
|  ========   ============  ================================================  |
|  Sep 2011   Abe Taaheri  Original development                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static herr_t
HE5_GDupdatedim(hid_t gridID,  char *dimname, hsize_t dim)
{
  herr_t       status    = FAIL;/* routine return status variable  */
 
  hid_t        fid       = FAIL;/* HDF-EOS file ID                 */
  hid_t        gid       = FAIL;/* "HDFEOS" group ID               */
 
  long         idx       = FAIL;/* Grid index                     */
 
  char         errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer */

  hsize_t      predims;
  long        xdim  = 0;                  /* X dim size                */
  long        ydim  = 0;                  /* Y dim size                */
 
  HE5_LOCK;
  CHECKNAME(dimname);
 

  /* Get HDF-EOS file ID, "HDFEOS" group ID and Swath index */
  /* ------------------------------------------------------ */
status = HE5_GDchkgdid(gridID, "HE5_GDupdatedim", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDupdatedim", __LINE__,  
	      H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  /* Make certain that dim != 0 */
  /* -------------------------- */
  if ( dim == 0 )
    {
      status = FAIL;
      sprintf(errbuf, "Invalid (zero) dimension size.\n");
      H5Epush(__FILE__, "HE5_GDupdatedim", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }

  /* Get dimension size */
  /* ------------------ */
  if ((strcmp(dimname, "XDim") == 0) || (strcmp(dimname, "YDim") == 0))
    {
      status = HE5_GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
      if(status == FAIL)
	{
	  sprintf(errbuf, "Cannot get information about Grid.\n");
	  H5Epush(__FILE__, "HE5_GDupdatedim", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
      
      if(strcmp(dimname, "XDim") == 0)
	{
	  predims =  (hsize_t)xdim;
	}
      else if(strcmp(dimname, "YDim") == 0)
	{
	  predims = (hsize_t)ydim;
	}
    }
  else
    {
      predims = HE5_GDdiminfo(gridID, dimname);
    }

  if (predims == 0)
    {
      status = FAIL;
      sprintf(errbuf, "Failed to retrieve the size of \"%s\" dimension. \n", dimname);
      H5Epush(__FILE__, "HE5_GDupdatedim", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }
 

  /* Write updated dimension back to the dataset "StructMetadata.0" */
  /* -------------------------------------------------------------- */
  if (dim > predims)
    {
      status = HE5_EHupdatemeta(fid, HE5_GDXGrid[idx].gdname, "g", 0L, dimname, &dim);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot update the value for \"%s\" dimension in Metadata.\n", dimname);
	  H5Epush(__FILE__, "HE5_GDupdatedim", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }
 
 COMPLETION:
  HE5_UNLOCK;
  return(status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefdimscale                                                |
|                                                                             |
|  DESCRIPTION: Defines dimension scale for all fields that use the given     |
|               dimesion (default dimscale name)                              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  dimname        char                dim name                                |
|  dimsize        hsize_t             Dimemsion size value                    |
|  numbertype_in  hid_t               dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES: This function finds out which field in a grid has the dimension     |
|         and sets dimension scale for that field calling HE5_GDsetdimscale() |
|         User must detach grid after creating fields and attach again before |
|         calling the routine.                                                |
|                                                                             |
|                                                                             |
|   Date      Programmer    Description                                       |
|  ========   ============  ===============================================   |
|  Dec 2013   Abe Taaheri   Original Programmer                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDdefdimscale(hid_t gridID,  char *dimname,
		  const hsize_t dimsize, hid_t numbertype_in, void * data)
{
  herr_t       status    = FAIL;/* routine return status variable  */
  hid_t        fid       = FAIL;/* HDF-EOS file ID                 */
  hid_t        gid       = FAIL;/* "HDFEOS" group ID               */
  long         idx       = FAIL;/* Swath index                     */
  char         errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer */
  char         *fieldlist = NULL;
  long         strbufsize;
  long         nflds   = FAIL;

  HE5_LOCK;
  CHECKNAME(dimname);

  /* Get HDF-EOS file ID, "HDFEOS" group ID and Swath index */
  /* ------------------------------------------------------ */
  status = HE5_GDchkgdid(gridID, "HE5_GDdefdimscale", &fid, &gid, &idx); 
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for Grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }

  /* Make certain that dimsize != 0 */
  /* ------------------------------ */
  if ( dimsize == 0 )
    {
      status = FAIL;
      sprintf(errbuf, "Invalid (zero) dimension size.\n");
      H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }

  /* Loop over all fields in the grid and find out if 
     field's dimension list  has the dimension name. 
     If true then set the dimension scale for the dim 
     in that field
  */

  /* Inquire Data Fields first*/
  /* ------------------------ */
  nflds = HE5_GDnentries(gridID, HE5_HDFE_NENTDFLD, &strbufsize);
  if (nflds == FAIL)
    {
      sprintf(errbuf, "Cannot get the number of fields in \"Data Fields\" group. \n");
      H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, 
	      H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
  else
    {
      fieldlist = (char *) calloc(strbufsize + 1, sizeof(char));
      if(fieldlist == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory.\n");
	  H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, 
		  H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}

      nflds = HE5_GDinqfields(gridID, fieldlist, NULL, NULL);
      if (nflds == FAIL)
	{
	  sprintf(errbuf, "Cannot get the list of fields in \"Data Fields\" group. \n");
	  H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, 
		  H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(fieldlist);
	  return(FAIL);
	}

      if(nflds > 0)
	{
	  size_t        fldnmlen[HE5_FLDNUMBERMAX];      /* Array of namelengths */
	  char          *fldnm[HE5_FLDNUMBERMAX];        /* Array of names       */
	  char          tempdimlist[HE5_HDFE_DIMBUFSIZE];/* Dimension list       */
	  int           rank     = FAIL;                 /* Rank of dataset       */
	  hsize_t	tempdims[HE5_DTSETRANKMAX];      /* Dimension sizes array*/
	  hid_t         dtype[1] = {FAIL};               /* Data type            */
	  long          ntflds   =  0;                   /* field counter        */
	  int           i;
	  char          *tempfield = NULL;
	  unsigned int  Dimindex;

	  ntflds = HE5_EHparsestr(fieldlist, ',', fldnm,fldnmlen);
	  if(ntflds != FAIL)
	    {
	      for(i = 0; i < ntflds; i++)
		{
		  tempfield      = (char *)calloc(fldnmlen[i] + 1, sizeof(char));
		  memmove(tempfield,fldnm[i],fldnmlen[i]);
		  tempfield[fldnmlen[i]]='\0';

		  /* for this field see if the dimlist contains dimname */
		  status = HE5_GDfieldinfo(gridID, tempfield, &rank, tempdims, 
					   dtype, tempdimlist, NULL);

		  if (status != SUCCEED)
		    {
		      sprintf(errbuf, "Field \"%s\" not found.\n", tempfield);
		      H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, H5E_ARGS, 
			      H5E_NOTFOUND, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(tempfield);
		      free(fieldlist);
		      return(FAIL);
		    }

		  Dimindex = FAIL;
		  Dimindex = HE5_EHstrwithin(dimname, tempdimlist, ',');
		  if (Dimindex == FAIL) /* dimension not found */
		    {
		      continue; /*dimlist does not contain dim name */
		    }
		  else
		    {
		      /* call HE5_GDsetdimscle */
		      status = HE5_GDsetdimscale(gridID, (char *)tempfield, 
						 dimname,
						 dimsize, 
						 numbertype_in, 
						 data);
		      if ( status == FAIL )
			{
			  sprintf(errbuf,"Cannot set dimension scale %s for the field %s. \n", 
				  dimname, tempfield);
			  H5Epush(__FILE__, "HE5_GDdefdimscale", __LINE__, 
				  H5E_OHDR, H5E_NOTFOUND, errbuf);
			  HE5_EHprint(errbuf, __FILE__, __LINE__);
			  free(tempfield);
			  free(fieldlist);
			  return(status);
			}
		    }
		}
	      free(tempfield);
	      tempfield = NULL;
	    }
	}
      free(fieldlist);
      fieldlist = NULL;
    }


 COMPLETION:
  HE5_UNLOCK;
  return(status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefdimscale 2                                              |
|                                                                             |
|  DESCRIPTION: Defines dimension scale for all fields that use the given     |
|               dimesion (user defined dimscale name)                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  dimname        char                dim name                                |
|  dimscalename   char                user defined dimscale name              |
|  dimsize        hsize_t             Dimemsion size value                    |
|  numbertype_in  hid_t               dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES: This function finds out which field in a grid has the dimension     |
|         and sets dimension scale for that field calling HE5_GDsetdimscale2()|
|         User must detach grid after creating fields and attach again before |
|         calling the routine.                                                |
|                                                                             |
|                                                                             |
|   Date      Programmer    Description                                       |
|  ========   ============  ===============================================   |
|  Dec 2017   Abe Taaheri   Original Programmer                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDdefdimscale2(hid_t gridID,  char *dimname, char *dimscalename,
		  const hsize_t dimsize, hid_t numbertype_in, void * data)
{
  herr_t       status    = FAIL;/* routine return status variable  */
  hid_t        fid       = FAIL;/* HDF-EOS file ID                 */
  hid_t        gid       = FAIL;/* "HDFEOS" group ID               */
  long         idx       = FAIL;/* Swath index                     */
  char         errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer */
  char         *fieldlist = NULL;
  long         strbufsize;
  long         nflds   = FAIL;

  HE5_LOCK;
  CHECKNAME(dimname);

  /* Get HDF-EOS file ID, "HDFEOS" group ID and Swath index */
  /* ------------------------------------------------------ */
  status = HE5_GDchkgdid(gridID, "HE5_GDdefdimscale2", &fid, &gid, &idx); 
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for Grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }

  /* Make certain that dimsize != 0 */
  /* ------------------------------ */
  if ( dimsize == 0 )
    {
      status = FAIL;
      sprintf(errbuf, "Invalid (zero) dimension size.\n");
      H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }

  /* Loop over all fields in the grid and find out if 
     field's dimension list  has the dimension name. 
     If true then set the dimension scale for the dim 
     in that field
  */

  /* Inquire Data Fields first*/
  /* ------------------------ */
  nflds = HE5_GDnentries(gridID, HE5_HDFE_NENTDFLD, &strbufsize);
  if (nflds == FAIL)
    {
      sprintf(errbuf, "Cannot get the number of fields in \"Data Fields\" group. \n");
      H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, 
	      H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
  else
    {
      fieldlist = (char *) calloc(strbufsize + 1, sizeof(char));
      if(fieldlist == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory.\n");
	  H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, 
		  H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}

      nflds = HE5_GDinqfields(gridID, fieldlist, NULL, NULL);
      if (nflds == FAIL)
	{
	  sprintf(errbuf, "Cannot get the list of fields in \"Data Fields\" group. \n");
	  H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, 
		  H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(fieldlist);
	  return(FAIL);
	}

      if(nflds > 0)
	{
	  size_t        fldnmlen[HE5_FLDNUMBERMAX];      /* Array of namelengths */
	  char          *fldnm[HE5_FLDNUMBERMAX];        /* Array of names       */
	  char          tempdimlist[HE5_HDFE_DIMBUFSIZE];/* Dimension list       */
	  int           rank     = FAIL;                 /* Rank of dataset       */
	  hsize_t	tempdims[HE5_DTSETRANKMAX];      /* Dimension sizes array*/
	  hid_t         dtype[1] = {FAIL};               /* Data type            */
	  long          ntflds   =  0;                   /* field counter        */
	  int           i;
	  char          *tempfield = NULL;
	  unsigned int  Dimindex;

	  ntflds = HE5_EHparsestr(fieldlist, ',', fldnm,fldnmlen);
	  if(ntflds != FAIL)
	    {
	      for(i = 0; i < ntflds; i++)
		{
		  tempfield      = (char *)calloc(fldnmlen[i] + 1, sizeof(char));
		  memmove(tempfield,fldnm[i],fldnmlen[i]);
		  tempfield[fldnmlen[i]]='\0';

		  /* for this field see if the dimlist contains dimname */
		  status = HE5_GDfieldinfo(gridID, tempfield, &rank, tempdims, 
					   dtype, tempdimlist, NULL);

		  if (status != SUCCEED)
		    {
		      sprintf(errbuf, "Field \"%s\" not found.\n", tempfield);
		      H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, H5E_ARGS, 
			      H5E_NOTFOUND, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(tempfield);
		      free(fieldlist);
		      return(FAIL);
		    }

		  Dimindex = FAIL;
		  Dimindex = HE5_EHstrwithin(dimname, tempdimlist, ',');
		  if (Dimindex == FAIL) /* dimension not found */
		    {
		      continue; /*dimlist does not contain dim name */
		    }
		  else
		    {
		      /* call HE5_GDsetdimscle */
		      status = HE5_GDsetdimscale2(gridID, (char *)tempfield, 
						  dimname, dimscalename,
						  dimsize, 
						  numbertype_in, 
						  data);
		      if ( status == FAIL )
			{
			  sprintf(errbuf,"Cannot set dimension scale %s for the field %s. \n", 
				  dimscalename, tempfield);
			  H5Epush(__FILE__, "HE5_GDdefdimscale2", __LINE__, 
				  H5E_OHDR, H5E_NOTFOUND, errbuf);
			  HE5_EHprint(errbuf, __FILE__, __LINE__);
			  free(tempfield);
			  free(fieldlist);
			  return(status);
			}
		    }
		}
	      free(tempfield);
	      tempfield = NULL;
	    }
	}
      free(fieldlist);
      fieldlist = NULL;
    }


 COMPLETION:
  HE5_UNLOCK;
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetdimscale                                                |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale for a dimension for fields of a grid|
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char                field name                              |
|  dimname        char                Dimension name                          |
|  dimsize        hsize_t             Dimemsion size value                    |
|  numbertype_in  hid_t               dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDsetdimscale(hid_t gridID, char *fieldname, char *dimname,
		  const hsize_t dimsize, hid_t numbertype_in, void * data)
{
  herr_t         status;
  hid_t          ntype;
  hsize_t        dims[HE5_DTSETRANKMAX];
  int            rankSDS;
  hid_t          field_ntype[1] = {FAIL};       /* number types       */ 
  char           dimlist[HE5_HDFE_DIMBUFSIZE];
  char           maxdimlist[HE5_HDFE_DIMBUFSIZE];
  long           xdimsize;
  long           ydimsize;
  double         upleftpt[2];
  double         lowrightpt[2];
  double         pixsizeX;
  double         pixsizeY;
  hid_t          fid    = FAIL; 	       /* HDF-EOS file ID     */
  hid_t          gid    = FAIL;	               /* "HDFEOS" group ID   */
  hid_t          did;
  hid_t          dsid;
  hid_t          fspace   = FAIL;              /* File dataspace ID   */
  unsigned int   Dimindex;
  hid_t          dsplist  = FAIL;              /* Property list ID    */
  H5D_layout_t   layout   = H5D_LAYOUT_ERROR;  /* Type of storage     */
  hid_t          data_space  = FAIL;           /* dataspace ID        */
  long           idx         = FAIL;           /* Grid index          */
  char          *errbuf      = (char *)NULL;   /* buffer for error message*/
  double        *data_bufff64= NULL;
  void          *data_buff;
  int            i, found;
  int            rankds;
  hsize_t        dimsds[1];

  int projcode;
  int zonecode;
  int spherecode;
  double projparm[13];

  HE5_LOCK;
  CHECKNAME(fieldname);
  CHECKNAME(dimname);
  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
    
  /* Convert HDF-EOS5 datatype to HDF5 datatype */
  if (
      H5Tequal(numbertype_in, H5T_NATIVE_CHAR)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_USHORT) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_INT)    == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UINT)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LONG)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULLONG) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)== SUCCEED ||
      H5Tequal(numbertype_in, H5T_C_S1) == SUCCEED)
    {
      ntype = numbertype_in;
    }
  else
    {
      ntype = HE5_EHconvdatatype((int) numbertype_in);
    }

  if(ntype == FAIL)
    {
      sprintf(errbuf,"Cannot convert to HDF5 type data type ID for dimscale.\n");
      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  /* Get the data size (bytes) */
  /* ------------------------- */
  /*tsize = H5Tget_size(ntype);*/
  if((data == NULL) || 
     (strcmp(dimname, "XDim") == 0) || 
     (strcmp(dimname, "YDim") == 0))
    {
      data_bufff64 = (double *)calloc(dimsize, sizeof(double));
      
      if(data_bufff64 == NULL)
	{ 
	  sprintf(errbuf, "Cannot allocate memory for buffer.\n");
	  H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
    }

  /************************************************************************
   * Check for proper grid ID and return HDF-EOS file ID, SDinterface ID, *
   * and grid root Vgroup ID                                              *
   ************************************************************************/
  status = HE5_GDchkgdid(gridID, "HE5_GDsetdimscale", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      if(data_bufff64 != NULL) free(data_bufff64);
      return(FAIL);
    }

  if (status == 0)
    {
      /* Check that field exists */
      /* ----------------------- */
      status = HE5_GDfieldinfo(gridID, fieldname, &rankSDS, dims, field_ntype, dimlist, maxdimlist);

      if (status != 0)
	{
	  sprintf(errbuf, "Fieldname \"%s\" does not exist.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  if(data_bufff64 != NULL) free(data_bufff64);
	  return(FAIL);
	}
      
      /* get gridname */
      /*strcpy(gridname, HE5_GDXGrid[idx].gdname);*/
      
      /* if dimname is XDim or YDim, data scale will be recalculated 
	 using xdim, ydim, upleft and lowright for the grid*/
      
      if((data == NULL) || 
	 (strcmp(dimname, "XDim") == 0) || 
	 (strcmp(dimname, "YDim") == 0))
	{
	  status = HE5_GDgridinfo(gridID, &xdimsize, &ydimsize, upleftpt, lowrightpt);


	  /* Get proj info */
	  /* ------------- */
	  status = HE5_GDprojinfo(gridID, &projcode, &zonecode,
				  &spherecode, projparm);
	  
	  
	  /* If no projection code defined then bail */
	  /* --------------------------------------- */
	  if (projcode == -1 || status == FAIL)
	    {
	      sprintf(errbuf,"Cannot get Grid projection information.\n");  
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      if(data_bufff64 != NULL) free(data_bufff64);
	      return(FAIL);
	    }
	  
	  /* Get default values for upleft and lowright if necessary */
	  /* ------------------------------------------------------- */
	  if (upleftpt[0] == 0 && upleftpt[1] == 0 &&
	      lowrightpt[0] == 0 && lowrightpt[1] == 0)
	    {
	      status = HE5_GDgetdefaults(projcode, zonecode, projparm, spherecode,
				     upleftpt, lowrightpt);
	      
	      /* If error then bail */
	      /* ------------------ */
	      if (status != 0)
		{
		  sprintf(errbuf,"Failed to get default values for uplft and lowrght points.\n" );
		  H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  if(data_bufff64 != NULL) free(data_bufff64);
		  status = -1;
		  return (status);
		}
	    }
	  
	  if (projcode == HE5_GCTP_GEO)
	    {
	      /* GEO projection */
	      /* -------------- */
	      /* Convert upleft and lowright X coords from DMS to degrees */
	      /* -------------------------------------------------------- */
	      upleftpt[0] = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_DEG);
	      lowrightpt[0] = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_DEG);
	      upleftpt[1] = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_DEG);
	      lowrightpt[1] = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_DEG);
	    }

	  if(strcmp(dimname, "XDim") == 0)
	    {
	      pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
	      for (i = 0; i <dimsize ; i++)
		{
		  data_bufff64[i] = upleftpt[0] + i * pixsizeX;
		}
	      data_buff = data_bufff64;
	    }
	  else if(strcmp(dimname, "YDim") == 0)
	    {
	      pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
	      for (i = 0; i <dimsize ; i++)
		{
		  data_bufff64[i] = upleftpt[1] + i * pixsizeY;
		}
	      data_buff = data_bufff64;
	    }
	}
      else
	{
	  data_buff = data;
	}
      
      /* Loop through all datasets in grid */
      /* ------------------------------ */
	for (i = 0; i < HE5_GDXGrid[idx].nDFLD; i++)
	  {
	    /* Get dataset name */
	    if( strcmp(fieldname, HE5_GDXGrid[ idx ].ddataset[ i ].name) == 0 )
	      {
		found = 1; 
		did = HE5_GDXGrid[ idx ].ddataset[ i ].ID;
		break;
	      } 
	  }

	if(found != 1) /* did not find fieldname */
	  {
	    sprintf(errbuf, "Fieldname \"%s\" does not exist.\n", fieldname);
	    H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    if(data_bufff64 != NULL) free(data_bufff64);
	    return(FAIL);
	  }
	/* Dimension index */

	Dimindex = FAIL;
	Dimindex = HE5_EHstrwithin(dimname, dimlist, ',');

	if (Dimindex == FAIL) /* dimension not found */
	  {
	    status = FAIL;
	    sprintf( errbuf, "Dimname \"%s\" does not exist for field \"%s\".\n", 
		     dimname, fieldname );
	    H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    if(data_bufff64 != NULL) free(data_bufff64); 
	    return(status);
	  }
	
	/* If dimension found ... */
	/* Found the dimname; Use its dimid to set Dimension Scale*/
	
	/* See if dimscale dataset already exist */
	
	dsid = H5Dopen(HE5_GDXGrid[idx].gd_id, dimname);

	if(dsid < 0) /* dimscale dataset does not exist. Create it */
	  {
	    /* create Dim Scale dataset */
	    /* Try to open the " group */
	    /* =================================== */
	    
	    dsplist = H5Pcreate(H5P_DATASET_CREATE);
	    if(dsplist == FAIL)
	      {
		sprintf(errbuf,"Cannot create a new property list.\n");  
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 		
		return(FAIL);
	      }
	    /* Get layout information */
	    /* ---------------------- */		
	    layout = H5Pget_layout(dsplist);
	    if(layout == H5D_LAYOUT_ERROR)
	      {
		sprintf(errbuf,"Cannot get layout information for the dataset.\n");  
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 	
		return(FAIL);
	      }

	    rankds = 1;
	    dimsds[0] = dims[Dimindex];

	    data_space = H5Screate_simple(rankds, dimsds, NULL);
	    if(data_space == FAIL)
	      {
		sprintf(errbuf,"Cannot create dataspace for the dimension scale dataset.\n");  
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 	
		return(FAIL);
	      }
	    
	    dsid = H5Dcreate(HE5_GDXGrid[idx].gd_id,dimname,ntype, data_space, dsplist);
	    
	    if( dsid == FAIL )
	      {
		sprintf(errbuf, "Cannot create dataset for Dimension Scale \"%s\" field. \n", dimname);
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		return(FAIL);
	      }

	    /* write data_buff to it */

	    /* Get the field space ID */
	    /* --------------------- */
	    fspace = H5Dget_space(dsid);
	    if ( fspace == FAIL)
	      {
		sprintf(errbuf, "Cannot get the file data space ID.\n");
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_DATASPACE, H5E_NOTFOUND, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		return(FAIL);
	      }

	    status = H5Dwrite(dsid, ntype, data_space, fspace,  H5P_DEFAULT, data_buff);
	    if( status == FAIL )
	      {
		sprintf(errbuf,"Cannot write data to the dataset.\n");
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		return(FAIL);
	      }    
	  }

	/* Dataset exist. See if it is dimension Scale already. If not make it */
	if ((H5DSis_scale(dsid)) <= 0 )
	  {

	    status = H5DSset_scale(dsid, dimname);
	    if( status < 0)
	      {
		status = -1;
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		goto COMPLETION;
	      }

	    if(H5DSattach_scale(did, dsid, Dimindex) < 0)
	      {
		status = -1;
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		goto COMPLETION;
	      }
	  }
	else
	  {
	    if(H5DSattach_scale(did, dsid, Dimindex) < 0)
	      {
		status = -1;
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		goto COMPLETION;
	      }
	  }
   
	if( H5Dclose(dsid) < 0)
	  {
	    status = -1;
	    free(errbuf);
	    if(data_bufff64 != NULL) free(data_bufff64); 
	    goto COMPLETION;
	  }
    }
  free(errbuf);
  if(data_bufff64 != NULL) free(data_bufff64);

 COMPLETION:  
  HE5_UNLOCK;

  return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetdimscale2                                               |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale (with any name) for a dimension     |
|               for fields of a grid                                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char                field name                              |
|  dimname        char                Dimension name                          |
|  dimscalename   char                Dimension scale name                    |
|  dimsize        hsize_t             Dimemsion size value                    |
|  numbertype_in  hid_t               dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|             None                                                            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 2017  Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDsetdimscale2(hid_t gridID, char *fieldname, char *dimname,
		   char *dimscalename, const hsize_t dimsize, 
		   hid_t numbertype_in, void * data)
{
  herr_t         status;
  hid_t          ntype;
  hsize_t        dims[HE5_DTSETRANKMAX];
  int            rankSDS;
  hid_t          field_ntype[1] = {FAIL};       /* number types       */ 
  char           dimlist[HE5_HDFE_DIMBUFSIZE];
  char           maxdimlist[HE5_HDFE_DIMBUFSIZE];
  long           xdimsize;
  long           ydimsize;
  double         upleftpt[2];
  double         lowrightpt[2];
  double         pixsizeX;
  double         pixsizeY;
  hid_t          fid    = FAIL; 	       /* HDF-EOS file ID     */
  hid_t          gid    = FAIL;	               /* "HDFEOS" group ID   */
  hid_t          did;
  hid_t          dsid;
  hid_t          fspace   = FAIL;              /* File dataspace ID   */
  unsigned int   Dimindex;
  hid_t          dsplist  = FAIL;              /* Property list ID    */
  H5D_layout_t   layout   = H5D_LAYOUT_ERROR;  /* Type of storage     */
  hid_t          data_space  = FAIL;           /* dataspace ID        */
  long           idx         = FAIL;           /* Grid index          */
  char          *errbuf      = (char *)NULL;   /* buffer for error message*/
  double               *data_bufff64= NULL;
  float                *data_bufff32= NULL;
  long double          *data_bufflong64= NULL;
  unsigned long long   *data_buffullong= NULL;
  long long            *data_buffllong= NULL;
  unsigned long        *data_buffulong= NULL;
  long                 *data_bufflong= NULL;
  unsigned int         *data_buffuint= NULL;
  int                  *data_buffint= NULL;
  unsigned short       *data_buffushort= NULL;
  short                *data_buffshort= NULL;
  signed char          *data_buffschar= NULL;
  unsigned char        *data_buffuchar= NULL;
  char                 *data_buffchar= NULL;

  void          *data_buff;
  int            i, found;
  int            rankds;
  hsize_t        dimsds[1];

  int projcode;
  int zonecode;
  int spherecode;
  double projparm[13];

  HE5_LOCK;
  CHECKNAME(fieldname);
  CHECKNAME(dimname);
  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
    
  /* Convert HDF-EOS5 datatype to HDF5 datatype */
  if (
      H5Tequal(numbertype_in, H5T_NATIVE_CHAR)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_USHORT) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_INT)    == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UINT)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LONG)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULLONG) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)== SUCCEED ||
      H5Tequal(numbertype_in, H5T_C_S1) == SUCCEED)
    {
      ntype = numbertype_in;
    }
  else
    {
      ntype = HE5_EHconvdatatype((int) numbertype_in);
    }

  if(ntype == FAIL)
    {
      sprintf(errbuf,"Cannot convert to HDF5 type data type ID for dimscale.\n");
      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  if(data == NULL && ((strcmp(dimname, "XDim") == 0) || 
     (strcmp(dimname, "YDim") == 0)))
    { /* use XDim or YDim data for dimscale */
      if (H5Tequal(numbertype_in, H5T_NATIVE_CHAR)   == SUCCEED)
	{
	  data_buffchar = (char *)calloc(dimsize, sizeof(char));      
	  if(data_buffchar == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffchar.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_SCHAR)  == SUCCEED)
	{
	  data_buffschar = (signed char *)calloc(dimsize, sizeof(signed char));      
	  if(data_buffschar == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffschar.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_UCHAR)  == SUCCEED)
	{
	  data_buffuchar = (unsigned char *)calloc(dimsize, sizeof(unsigned char));      
	  if(data_buffuchar == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffuchar.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED)
	{
	  data_buffshort = (short *)calloc(dimsize, sizeof(short));      
	  if(data_buffshort == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffshort.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_USHORT) == SUCCEED)
	{
	  data_buffushort = (unsigned short *)calloc(dimsize, sizeof(unsigned short));     
	  if(data_buffushort == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffushort.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_INT)    == SUCCEED)
	{
	  data_buffint = (int *)calloc(dimsize, sizeof(int));     
	  if(data_buffint == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffint.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_UINT)   == SUCCEED)
	{
	  data_buffuint = (unsigned int *)calloc(dimsize, sizeof(unsigned int));     
	  if(data_buffuint == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffuint.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_LONG)   == SUCCEED)
	{
	  data_bufflong = (long *)calloc(dimsize, sizeof(long));     
	  if(data_bufflong == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_bufflong.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED)
	{
	  data_buffulong = (unsigned long *)calloc(dimsize, sizeof(unsigned long));    
	  if(data_buffulong == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffulong.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED)
	{
	  data_buffllong = (long long *)calloc(dimsize, sizeof(long long));    
	  if(data_buffllong == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffllong.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_ULLONG) == SUCCEED)
	{
	  data_buffullong = (unsigned long long *)calloc(dimsize, sizeof(unsigned long long));    
	  if(data_buffullong == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffullong.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED)
	{
	  data_bufff32 = (float *)calloc(dimsize, sizeof(float));
      
	  if(data_bufff32 == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_bufff32.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED)
	{
	  data_bufff64 = (double *)calloc(dimsize, sizeof(double));
	  
	  if(data_bufff64 == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_bufff64.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if(H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)== SUCCEED)
	{
	  data_bufflong64 = (long double *)calloc(dimsize, sizeof(long double));
	  if(data_bufflong64 == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_bufflong64.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}
      else if( H5Tequal(numbertype_in, H5T_C_S1) == SUCCEED)
	{
	  data_buffchar = (char *)calloc(dimsize, sizeof(char));      
	  if(data_buffchar == NULL)
	    { 
	      sprintf(errbuf, "Cannot allocate memory for buffer data_buffchar.\n");
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return(FAIL);
	    }
	}  
    }

  /* Get the data size (bytes) */
  /* ------------------------- */
  /*tsize = H5Tget_size(ntype);*/
  /*
  if((data == NULL) || 
     (strcmp(dimname, "XDim") == 0) || 
     (strcmp(dimname, "YDim") == 0))
    {
      data_bufff64 = (double *)calloc(dimsize, sizeof(double));
      
      if(data_bufff64 == NULL)
	{ 
	  sprintf(errbuf, "Cannot allocate memory for buffer.\n");
	  H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
    }
  */
  /************************************************************************
   * Check for proper grid ID and return HDF-EOS file ID, SDinterface ID, *
   * and grid root Vgroup ID                                              *
   ************************************************************************/
  status = HE5_GDchkgdid(gridID, "HE5_GDsetdimscale", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      if(data_bufff64 != NULL) free(data_bufff64);
      if(data_bufff32 != NULL) free(data_bufff32);
      if(data_bufflong64 != NULL) free(data_bufflong64);
      if(data_buffullong != NULL) free(data_buffullong);
      if(data_buffllong != NULL) free(data_buffllong);
      if(data_buffulong != NULL) free(data_buffulong);
      if(data_bufflong != NULL) free(data_bufflong);
      if(data_buffuint != NULL) free(data_buffuint);
      if(data_buffint != NULL) free(data_buffint);
      if(data_buffushort != NULL) free(data_buffushort);
      if(data_buffshort != NULL) free(data_buffshort);
      if(data_buffschar != NULL) free(data_buffschar);
      if(data_buffuchar != NULL) free(data_buffuchar);
      if(data_buffchar != NULL) free(data_buffchar);
      return(FAIL);
    }

  if (status == 0)
    {
      /* Check that field exists */
      /* ----------------------- */
      status = HE5_GDfieldinfo(gridID, fieldname, &rankSDS, dims, field_ntype, dimlist, maxdimlist);

      if (status != 0)
	{
	  sprintf(errbuf, "Fieldname \"%s\" does not exist.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  if(data_bufff64 != NULL) free(data_bufff64);
	  if(data_bufff32 != NULL) free(data_bufff32);
	  if(data_bufflong64 != NULL) free(data_bufflong64);
	  if(data_buffullong != NULL) free(data_buffullong);
	  if(data_buffllong != NULL) free(data_buffllong);
	  if(data_buffulong != NULL) free(data_buffulong);
	  if(data_bufflong != NULL) free(data_bufflong);
	  if(data_buffuint != NULL) free(data_buffuint);
	  if(data_buffint != NULL) free(data_buffint);
	  if(data_buffushort != NULL) free(data_buffushort);
	  if(data_buffshort != NULL) free(data_buffshort);
	  if(data_buffschar != NULL) free(data_buffschar);
	  if(data_buffuchar != NULL) free(data_buffuchar);
	  if(data_buffchar != NULL) free(data_buffchar);
	  return(FAIL);
	}
      
      /* get gridname */
      /*strcpy(gridname, HE5_GDXGrid[idx].gdname);*/
      
      /* if dimname is XDim or YDim, data scale will be recalculated 
	 using xdim, ydim, upleft and lowright for the grid*/
      
      if((data == NULL) && 
	 (strcmp(dimname, "XDim") == 0) || 
	 (strcmp(dimname, "YDim") == 0))
	{
	  status = HE5_GDgridinfo(gridID, &xdimsize, &ydimsize, upleftpt, lowrightpt);


	  /* Get proj info */
	  /* ------------- */
	  status = HE5_GDprojinfo(gridID, &projcode, &zonecode,
				  &spherecode, projparm);
	  
	  
	  /* If no projection code defined then bail */
	  /* --------------------------------------- */
	  if (projcode == -1 || status == FAIL)
	    {
	      sprintf(errbuf,"Cannot get Grid projection information.\n");  
	      H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      if(data_bufff64 != NULL) free(data_bufff64);
	      if(data_bufff32 != NULL) free(data_bufff32);
	      if(data_bufflong64 != NULL) free(data_bufflong64);
	      if(data_buffullong != NULL) free(data_buffullong);
	      if(data_buffllong != NULL) free(data_buffllong);
	      if(data_buffulong != NULL) free(data_buffulong);
	      if(data_bufflong != NULL) free(data_bufflong);
	      if(data_buffuint != NULL) free(data_buffuint);
	      if(data_buffint != NULL) free(data_buffint);
	      if(data_buffushort != NULL) free(data_buffushort);
	      if(data_buffshort != NULL) free(data_buffshort);
	      if(data_buffschar != NULL) free(data_buffschar);
	      if(data_buffuchar != NULL) free(data_buffuchar);
	      if(data_buffchar != NULL) free(data_buffchar);
	      return(FAIL);
	    }
	  
	  /* Get default values for upleft and lowright if necessary */
	  /* ------------------------------------------------------- */
	  if (upleftpt[0] == 0 && upleftpt[1] == 0 &&
	      lowrightpt[0] == 0 && lowrightpt[1] == 0)
	    {
	      status = HE5_GDgetdefaults(projcode, zonecode, projparm, spherecode,
				     upleftpt, lowrightpt);
	      
	      /* If error then bail */
	      /* ------------------ */
	      if (status != 0)
		{
		  sprintf(errbuf,"Failed to get default values for uplft and lowrght points.\n" );
		  H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  if(data_bufff64 != NULL) free(data_bufff64);
		  if(data_bufff32 != NULL) free(data_bufff32);
		  if(data_bufflong64 != NULL) free(data_bufflong64);
		  if(data_buffullong != NULL) free(data_buffullong);
		  if(data_buffllong != NULL) free(data_buffllong);
		  if(data_buffulong != NULL) free(data_buffulong);
		  if(data_bufflong != NULL) free(data_bufflong);
		  if(data_buffuint != NULL) free(data_buffuint);
		  if(data_buffint != NULL) free(data_buffint);
		  if(data_buffushort != NULL) free(data_buffushort);
		  if(data_buffshort != NULL) free(data_buffshort);
		  if(data_buffschar != NULL) free(data_buffschar);
		  if(data_buffuchar != NULL) free(data_buffuchar);
		  if(data_buffchar != NULL) free(data_buffchar);
		  status = -1;
		  return (status);
		}
	    }
	  
	  if (projcode == HE5_GCTP_GEO)
	    {
	      /* GEO projection */
	      /* -------------- */
	      /* Convert upleft and lowright X coords from DMS to degrees */
	      /* -------------------------------------------------------- */
	      upleftpt[0] = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_DEG);
	      lowrightpt[0] = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_DEG);
	      upleftpt[1] = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_DEG);
	      lowrightpt[1] = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_DEG);
	    }

	  if(strcmp(dimname, "XDim") == 0)
	    {
	      if(H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufff64[i] = upleftpt[0] + i * pixsizeX;
		    }
		  data_buff = data_bufff64;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufff32[i] = (float)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_bufff32;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufflong64[i] = (long double)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_bufflong64;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_ULLONG)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffullong[i] = (unsigned long long)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_buffullong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffllong[i] = (long long)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_buffllong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffulong[i] = (unsigned long)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_buffulong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_LONG)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufflong[i] = (long)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_bufflong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_UINT)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffuint[i] = (unsigned int)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_buffuint;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_INT)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffint[i] = (int)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_buffint;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_USHORT)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufff32[i] = (unsigned short)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_bufff32;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED)
		{
		  pixsizeX = (lowrightpt[0] - upleftpt[0])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffushort[i] = (short)(upleftpt[0] + i * pixsizeX);
		    }
		  data_buff = data_buffushort;
		}
	    }
	  else if(strcmp(dimname, "YDim") == 0)
	    {
	      if(H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufff64[i] = upleftpt[1] + i * pixsizeY;
		    }
		  data_buff = data_bufff64;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufff32[i] = (float)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_bufff32;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufflong64[i] = (long double)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_bufflong64;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_ULLONG)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffullong[i] = (unsigned long long)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_buffullong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffllong[i] = (long long)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_buffllong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffulong[i] = (unsigned long)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_buffulong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_LONG)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufflong[i] = (long)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_bufflong;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_UINT)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffuint[i] = (unsigned int)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_buffuint;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_INT)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffint[i] = (int)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_buffint;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_USHORT)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_bufff32[i] = (unsigned short)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_bufff32;
		}
	      else if(H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED)
		{
		  pixsizeY = (lowrightpt[1] - upleftpt[1])/dimsize;
		  for (i = 0; i <dimsize ; i++)
		    {
		      data_buffushort[i] = (short)(upleftpt[1] + i * pixsizeY);
		    }
		  data_buff = data_buffushort;
		}
	    }
	}
      else
	{
	  data_buff = data;
	}
      
      /* Loop through all datasets in grid */
      /* ------------------------------ */
	for (i = 0; i < HE5_GDXGrid[idx].nDFLD; i++)
	  {
	    /* Get dataset name */
	    if( strcmp(fieldname, HE5_GDXGrid[ idx ].ddataset[ i ].name) == 0 )
	      {
		found = 1; 
		did = HE5_GDXGrid[ idx ].ddataset[ i ].ID;
		break;
	      } 
	  }

	if(found != 1) /* did not find fieldname */
	  {
	    sprintf(errbuf, "Fieldname \"%s\" does not exist.\n", fieldname);
	    H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    if(data_bufff64 != NULL) free(data_bufff64);
	    if(data_bufff32 != NULL) free(data_bufff32);
	    if(data_bufflong64 != NULL) free(data_bufflong64);
	    if(data_buffullong != NULL) free(data_buffullong);
	    if(data_buffllong != NULL) free(data_buffllong);
	    if(data_buffulong != NULL) free(data_buffulong);
	    if(data_bufflong != NULL) free(data_bufflong);
	    if(data_buffuint != NULL) free(data_buffuint);
	    if(data_buffint != NULL) free(data_buffint);
	    if(data_buffushort != NULL) free(data_buffushort);
	    if(data_buffshort != NULL) free(data_buffshort);
	    if(data_buffschar != NULL) free(data_buffschar);
	    if(data_buffuchar != NULL) free(data_buffuchar);
	    if(data_buffchar != NULL) free(data_buffchar);
	    return(FAIL);
	  }
	/* Dimension index */

	Dimindex = FAIL;
	Dimindex = HE5_EHstrwithin(dimname, dimlist, ',');

	if (Dimindex == FAIL) /* dimension not found */
	  {
	    status = FAIL;
	    sprintf( errbuf, "Dimname \"%s\" does not exist for field \"%s\".\n", 
		     dimname, fieldname );
	    H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    if(data_bufff64 != NULL) free(data_bufff64); 
	    if(data_bufff32 != NULL) free(data_bufff32); 
	    if(data_bufflong64 != NULL) free(data_bufflong64);
	    if(data_buffullong != NULL) free(data_buffullong);
	    if(data_buffllong != NULL) free(data_buffllong);
	    if(data_buffulong != NULL) free(data_buffulong);
	    if(data_bufflong != NULL) free(data_bufflong);
	    if(data_buffuint != NULL) free(data_buffuint);
	    if(data_buffint != NULL) free(data_buffint);
	    if(data_buffushort != NULL) free(data_buffushort);
	    if(data_buffshort != NULL) free(data_buffshort);
	    if(data_buffschar != NULL) free(data_buffschar);
	    if(data_buffuchar != NULL) free(data_buffuchar);
	    if(data_buffchar != NULL) free(data_buffchar);
	    return(status);
	  }
	
	/* If dimension found ... */
	/* Found the dimname; Use its dimid to set Dimension Scale*/
	
	/* See if dimscale dataset already exist */
	
	dsid = H5Dopen(HE5_GDXGrid[idx].gd_id, dimscalename);

	if(dsid < 0) /* dimscale dataset does not exist. Create it */
	  {
	    /* create Dim Scale dataset */
	    /* Try to open the " group */
	    /* =================================== */
	    
	    dsplist = H5Pcreate(H5P_DATASET_CREATE);
	    if(dsplist == FAIL)
	      {
		sprintf(errbuf,"Cannot create a new property list.\n");  
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64);
		if(data_bufff32 != NULL) free(data_bufff32);
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar);  		
		return(FAIL);
	      }
	    /* Get layout information */
	    /* ---------------------- */		
	    layout = H5Pget_layout(dsplist);
	    if(layout == H5D_LAYOUT_ERROR)
	      {
		sprintf(errbuf,"Cannot get layout information for the dataset.\n");  
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		if(data_bufff32 != NULL) free(data_bufff32); 
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar);	
		return(FAIL);
	      }

	    rankds = 1;
	    /*dimsds[0] = dims[Dimindex];*/
	    dimsds[0] = dimsize;
	    data_space = H5Screate_simple(rankds, dimsds, NULL);
	    if(data_space == FAIL)
	      {
		sprintf(errbuf,"Cannot create dataspace for the dimension scale dataset.\n");  
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		if(data_bufff32 != NULL) free(data_bufff32); 
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar);	
		return(FAIL);
	      }
	    
	    dsid = H5Dcreate(HE5_GDXGrid[idx].gd_id,dimscalename,ntype, data_space, dsplist);
	    
	    if( dsid == FAIL )
	      {
		sprintf(errbuf, "Cannot create dataset for Dimension Scale \"%s\" field. \n", dimscalename);
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		if(data_bufff32 != NULL) free(data_bufff32); 
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar);
		return(FAIL);
	      }

	    /* write data_buff to it */

	    /* Get the field space ID */
	    /* --------------------- */
	    fspace = H5Dget_space(dsid);
	    if ( fspace == FAIL)
	      {
		sprintf(errbuf, "Cannot get the file data space ID.\n");
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_DATASPACE, H5E_NOTFOUND, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		if(data_bufff32 != NULL) free(data_bufff32); 
		return(FAIL);
	      }

	    status = H5Dwrite(dsid, ntype, data_space, fspace,  H5P_DEFAULT, data_buff);
	    if( status == FAIL )
	      {
		sprintf(errbuf,"Cannot write data to the dataset.\n");
		H5Epush(__FILE__, "HE5_GDsetdimscale", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
		HE5_EHprint(errbuf, __FILE__, __LINE__);
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		if(data_bufff32 != NULL) free(data_bufff32);
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar); 
		return(FAIL);
	      }    
	  }

	/* Dataset exist. See if it is dimension Scale already. If not make it */
	if ((H5DSis_scale(dsid)) <= 0 )
	  {

	    status = H5DSset_scale(dsid, dimscalename);
	    if( status < 0)
	      {
		status = -1;
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64); 
		if(data_bufff32 != NULL) free(data_bufff32); 
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar);
		goto COMPLETION;
	      }

	    if(H5DSattach_scale(did, dsid, Dimindex) < 0)
	      {
		status = -1;
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64);
		if(data_bufff32 != NULL) free(data_bufff32); 
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar); 
		goto COMPLETION;
	      }
	  }
	else
	  {
	    if(H5DSattach_scale(did, dsid, Dimindex) < 0)
	      {
		status = -1;
		free(errbuf);
		if(data_bufff64 != NULL) free(data_bufff64);
		if(data_bufff32 != NULL) free(data_bufff32);
		if(data_bufflong64 != NULL) free(data_bufflong64);
		if(data_buffullong != NULL) free(data_buffullong);
		if(data_buffllong != NULL) free(data_buffllong);
		if(data_buffulong != NULL) free(data_buffulong);
		if(data_bufflong != NULL) free(data_bufflong);
		if(data_buffuint != NULL) free(data_buffuint);
		if(data_buffint != NULL) free(data_buffint);
		if(data_buffushort != NULL) free(data_buffushort);
		if(data_buffshort != NULL) free(data_buffshort);
		if(data_buffschar != NULL) free(data_buffschar);
		if(data_buffuchar != NULL) free(data_buffuchar);
		if(data_buffchar != NULL) free(data_buffchar);  
		goto COMPLETION;
	      }
	  }
   
	if( H5Dclose(dsid) < 0)
	  {
	    status = -1;
	    free(errbuf);
	    if(data_bufff64 != NULL) free(data_bufff64); 
	    if(data_bufff32 != NULL) free(data_bufff32); 
	    if(data_bufflong64 != NULL) free(data_bufflong64);
	    if(data_buffullong != NULL) free(data_buffullong);
	    if(data_buffllong != NULL) free(data_buffllong);
	    if(data_buffulong != NULL) free(data_buffulong);
	    if(data_bufflong != NULL) free(data_bufflong);
	    if(data_buffuint != NULL) free(data_buffuint);
	    if(data_buffint != NULL) free(data_buffint);
	    if(data_buffushort != NULL) free(data_buffushort);
	    if(data_buffshort != NULL) free(data_buffshort);
	    if(data_buffschar != NULL) free(data_buffschar);
	    if(data_buffuchar != NULL) free(data_buffuchar);
	    if(data_buffchar != NULL) free(data_buffchar);
	    goto COMPLETION;
	  }
    }
  free(errbuf);
  if(data_bufff64 != NULL) free(data_bufff64); 
  if(data_bufff32 != NULL) free(data_bufff32);
  if(data_bufflong64 != NULL) free(data_bufflong64);
  if(data_buffullong != NULL) free(data_buffullong);
  if(data_buffllong != NULL) free(data_buffllong);
  if(data_buffulong != NULL) free(data_buffulong);
  if(data_bufflong != NULL) free(data_bufflong);
  if(data_buffuint != NULL) free(data_buffuint);
  if(data_buffint != NULL) free(data_buffint);
  if(data_buffushort != NULL) free(data_buffushort);
  if(data_buffshort != NULL) free(data_buffshort);
  if(data_buffschar != NULL) free(data_buffschar);
  if(data_buffuchar != NULL) free(data_buffuchar);
  if(data_buffchar != NULL) free(data_buffchar);

 COMPLETION:  
  HE5_UNLOCK;

  return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetdimscale                                                |
|                                                                             |
|  DESCRIPTION: Get dimension scale for a dimension of a field in a grid      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         long                return databuffsize  SUCCEED, (-1) FAIL |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimsize        hsize_t             dimension size                          |
|  ntype          hid_t               dtata type of dimension scale           |
|  databuff       void                data buffer for read                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long
HE5_GDgetdimscale(hid_t gridID, char *fieldname, char *dimname,
		  hsize_t *dimsize, hid_t *ntype, void * databuff)
{
  int             i,j;		                   /* Loop index             */
  long            status;	                   /* routine return status  */
  long            idx    = FAIL;                   /* Grid index             */
  hid_t           fid    = FAIL; 	           /* HDF-EOS file ID        */
  hid_t           gid    = FAIL;	           /* "HDFEOS" group ID      */
  hid_t           did    = FAIL;                   /* dataset ID             */
  hid_t           dsid   = FAIL;                   /* dimscale dataset ID    */
  hid_t           dspace = FAIL;                   /* data space ID          */
  hid_t           mspace = FAIL;                   /* memory data space ID   */
  hid_t           dtype  = FAIL;                   /* data type ID           */
  hid_t           mtype  = FAIL;                   /* memory data type ID    */
  H5T_class_t     classid = H5T_NO_CLASS;          /* Data type class ID     */
  hsize_t         dimsds[HE5_DTSETRANKMAX];        /* Field dimensions       */
  char           *errbuf = (char *)NULL;           /* buff for error message */
  long            size   = 0;                      /* data buffer size(bytes)*/
  int             rankds;
  size_t          sd_type_size = 0;	           /* Size of a data type    */
  unsigned int    Dimindex;
  int             rankSDS;
  hid_t           *field_ntype = (hid_t *)NULL;    /* number types           */
  char            dimlist[HE5_HDFE_DIMBUFSIZE];
  char            maxdimlist[HE5_HDFE_DIMBUFSIZE];
  hsize_t         dims[HE5_DTSETRANKMAX];
  int             found = 0;
  htri_t          str_is_variable; /* boolean: TRUE if string is variable 
				      lengeth FALSE if string is fixed length
				      -1 if error in H5Tis_variavle_str() */
  HE5_LOCK;
  CHECKNAME(fieldname);
  CHECKNAME(dimname);


  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgetdimscale", &fid, &gid, &idx);
  if(status == FAIL)
    {
      sprintf(errbuf,"Checking for Grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* See if dimscale dataset exist */

  dsid = H5Dopen(HE5_GDXGrid[idx].gd_id, dimname);
  if(dsid < 0)
    {
      status = FAIL;
      sprintf( errbuf, "Dimension scale dataset \"%s\" does not exist.\n", 
	       dimname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(status);
    }

  /* Loop through all datasets in grid */
  /* ------------------------------ */
  for (i = 0; i < HE5_GDXGrid[idx].nDFLD; i++)
    {
      /* Get dataset name */
      if( strcmp(fieldname, HE5_GDXGrid[ idx ].ddataset[ i ].name) == 0 )
	{
	  found = 1; 
	  did = HE5_GDXGrid[ idx ].ddataset[ i ].ID;
	  break;
	}
    }
  if(found != 1) /* did not find fieldname */
    {
      sprintf(errbuf, "Fieldname \"%s\" does not exist.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Check that field exists */
  /* ----------------------- */
  status = HE5_GDfieldinfo(gridID, fieldname, &rankSDS, dims, field_ntype, dimlist, maxdimlist);
  
  if (status != 0)
    {
      sprintf(errbuf, "Fieldname \"%s\" does not exist.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__,  H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* find the index of the dimension in the field */

  Dimindex = FAIL;
  Dimindex = HE5_EHstrwithin(dimname, dimlist, ',');
  if (Dimindex == FAIL) /* dimension not found */
    {
      status = FAIL;
      sprintf( errbuf, "Dimname \"%s\" does not exist for field \"%s\".\n", 
	       dimname, fieldname );
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(status);
    }

  /* check that dimname is dimension scale name for the field dimname */
  status = H5DSis_attached(did, dsid, Dimindex);

  if( status < 0)
    {
      status = FAIL;
      sprintf( errbuf, "Dimname \"%s\" is not dimension scale for a dimension in the field \"%s\".\n", dimname, fieldname );
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(status);
    }

  /* OK. dsid is a dimension scale for did. It is time to read Dimension 
     Scale dataset for output */

  /* get size first ... */
  /* ------------------ */
  dtype = H5Dget_type(dsid);
  if ( dtype == FAIL )
    {
      size = 0;
      sprintf(errbuf, "Cannot get data type ID.\n");
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Get data type size (bytes) */
  /* -------------------------- */   
  sd_type_size = H5Tget_size(dtype);
  if ( sd_type_size == 0 )
    {
      sprintf(errbuf, "Cannot retrieve data type size.\n");
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Get data space ID */
  /* ----------------- */
  dspace = H5Dget_space( dsid );
  if (dspace == FAIL)
    {
      sprintf(errbuf, "Cannot get the dataspace ID for the \"%s\" dataset.\n", dimname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  /* Get dataset rank */
  /* ---------------- */
  rankds = H5Sget_simple_extent_ndims(dspace);
  if ( rankds == FAIL )
    {
      sprintf(errbuf, "Cannot get the dataset rank for the \"%s\" dataset.\n", dimname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  /* Get dataset dimension sizes */
  /* --------------------------- */
  status = H5Sget_simple_extent_dims(dspace,dimsds, NULL);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot get the dataset dimension sizes for the \"%s\" dataset.\n", dimname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(status);
    }
  
  /*----------------------------------------------------------------------*/

  /* Get data class ID */
  /* ----------------- */
  classid       = H5Tget_class(dtype);
  if (classid == H5T_NO_CLASS)
    {
      sprintf(errbuf, "Cannot get the data type class ID for \"%s\" dataset.",
	      dimname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, 
	      H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (errbuf  != NULL) free(errbuf);
      return(FAIL);
    }
  
  if (classid == H5T_STRING)
    {
      /* HE5T_CHARSTRING has variable length for data fields */
      str_is_variable = H5Tis_variable_str(dtype);
      if(str_is_variable == TRUE)
	{
	  *ntype = HE5T_CHARSTRING;
	}
      else if(str_is_variable == FALSE)
	{
	  *ntype = HE5T_NATIVE_CHAR;
	}
      else
	{
	  sprintf(errbuf, "Failed to see if string field is varaible or fixed length for the \"%s\" field.\n",dimname);
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, 
		  H5E_NOTFOUND, errbuf);
	  
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (errbuf  != NULL) free(errbuf);
	  return(FAIL);
	}
    }
  else
    {
      *ntype = HE5_EHdtype2numtype(dtype);
       if (*ntype == FAIL)
	{
	  sprintf(errbuf, "Cannot get the number type for \"%s\" dataset.", 
		  dimname);
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, 
		  H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (errbuf  != NULL) free(errbuf);
	  return(FAIL);
	}
    }
  /*----------------------------------------------------------------------*/
		
  status = H5Tclose(dtype);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Cannot release the datatype ID.\n");
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  /* Release the dataspace ID */
  /* ------------------------ */
  status = H5Sclose(dspace);
  if ( status == FAIL)
    {
      sprintf(errbuf, "Cannot release the dataset ID for the \"%s\" dataset.\n", dimname);
      H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(status);
    }

  size = (long)dimsds[ 0 ];
  *dimsize = (hsize_t)size;

  for (j = 1; j < rankds; j++)
    size *= (long)dimsds[j];
 
  size *= (long)sd_type_size;

  /* If data values are requested ... */
  /* -------------------------------- */
  if (databuff != NULL)
    {
      /* Create a data space in memory */
      /* ----------------------------- */ 		
      mspace = H5Screate_simple(rankds, (const hsize_t *)dimsds, NULL);
      if ( mspace == FAIL )
	{
	  sprintf(errbuf,"Cannot create the data space.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATASPACE, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}

      dspace = H5Dget_space(dsid );
      if (dspace == FAIL)
	{
	  sprintf(errbuf, "Cannot get the dataspace ID for the \"%s\" dataset.\n", dimname);
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
		
      dtype = H5Dget_type(dsid);
      if ( dtype == FAIL )
	{
	  sprintf(errbuf,"Cannot get the datatype ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}

      /* Get the memory data type ID */
      /* --------------------------- */
      mtype = HE5_EHdtype2mtype(dtype);
      if ( mtype == FAIL )
	{
	  sprintf(errbuf,"Cannot get the memory data type.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}

      /* Read the selected points into the buffer */
      /* ---------------------------------------  */
      status = H5Dread(dsid, mtype, mspace, dspace, H5P_DEFAULT, databuff);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot read out the data from the dataset.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
				
      status = H5Tclose(dtype);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot release the datatype ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATATYPE, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
		
      status = H5Sclose(mspace);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot release the memory data space ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
		
      status = H5Sclose(dspace);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot release the file data space ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetdimscale", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
    }

  free(errbuf);
 COMPLETION:
  HE5_UNLOCK;
  return (size);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreaddscaleattr                                             |
|                                                                             |
|  DESCRIPTION: Reads attribute associated with a dimension scale field       |
|               from a grid.                                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char                field name                              |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 10   Abe Taaheri   Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDreaddscaleattr(hid_t gridID, const char *fieldname, const char *attrname, void *datbuf)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      ntype         = FAIL;/* hdf5 type data type ID         */
  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
     
  long       idx           = FAIL;/* Grid index                     */
     
  hsize_t    count[]={0};	   /* array with the number of elements */

  char       errbuf[HE5_HDFE_ERRBUFSIZE]; /* Error message buffer   */


  HE5_LOCK;
  CHECKPOINTER(fieldname);
  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDreaddscaleattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get field ID */
      /* ------------ */
      fieldID = H5Dopen(HE5_GDXGrid[idx].gd_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDreaddscaleattr", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
		
      /* Call EHattr to perform I/O */
      /* -------------------------- */
      status = HE5_EHattr(fieldID, attrname, ntype, count, "r", datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot read Attribute \"%s\" associated wth the \"%s\" field.\n", attrname,fieldname);
	  H5Epush(__FILE__, "HE5_GDreaddscaleattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
        
      /* Release dataset ID */
      /* ------------------ */
      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDreaddscaleattr", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}			
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION:  HE5_GDwritedscaleattr                                           |
|                                                                             |
|  DESCRIPTION: Writes/updates attribute associated with a dimension scale    |
|               field in a grid.                                              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char*               dimension scale SDS name                |
|  attrname       char*               attribute name                          |
|  numtype        hid_t               attribute datatype ID                   |
|  count[]        hsize_t             Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10   Abe Taaheri   Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t    
HE5_GDwritedscaleattr(hid_t gridID, const char *fieldname, const char *attrname, hid_t numtype, hsize_t  count[],  void *datbuf)
{
  herr_t     status        = FAIL;/* routine return status variable */
  
  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
  
  long       idx           = FAIL;/* Grid index                     */
  
  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */
  hid_t      ntype;
  
  HE5_LOCK;
  CHECKPOINTER(fieldname);
  CHECKNAME(attrname);
  CHECKPOINTER(count);
  CHECKPOINTER(datbuf);
  
  /* 
     if numtype is HE5 numbertype, rather than H5 numbertype, then convert
     it, otherwise use ntype itself
  */
  ntype = HE5_EHconvdatatype(numtype);
  if(ntype == FAIL)
    {
      ntype = numtype;
    }
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDwritedscaleattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      
      /* Get field ID */
      /* ------------ */
      fieldID = H5Dopen(HE5_GDXGrid[idx].gd_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDwritedscaleattr", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
      
      /* Call EHattr to perform I/O */
      /* -------------------------- */
      status = HE5_EHattr(fieldID, attrname, ntype, count,"w", datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot write Attribute \"%s\" for the \"%s\" field.\n", attrname, fieldname);
	  H5Epush(__FILE__, "HE5_GDwritedscaleattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
      
      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDwritedscaleattr", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	
    }
  
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdscaleattrinfo                                             |
|                                                                             |
|  DESCRIPTION: Retrieves information about dimension scale attribute         |
|               (attribute associated with a specified dimension scale field) |
|                in a grid.                                                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               attribute data type ID                  |
|  count          hsize_t             Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10   Abe Taaheri   Original Development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDdscaleattrinfo(hid_t gridID, const char *fieldname, const char *attrname, hid_t *ntype, hsize_t *count)
{
  herr_t     status        = FAIL;       /* routine return status variable */
  hsize_t    *bufsize      = (hsize_t *)NULL;
  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer           */
  
  status = HE5_GDdscaleattrinfo2(gridID, fieldname, attrname, ntype, count, bufsize);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot retrieve information about Attribute \"%s\" \n", attrname);
      H5Epush(__FILE__, "HE5_GDdscaleattrinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(status);
    }
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdscaleattrinfo2                                            |
|                                                                             |
|  DESCRIPTION: Retrieves information about dimension scale attribute         |
|               (attribute associated with a specified dimension scale field) |
|                in a grid.                                                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               attribute data type ID                  |
|  count          hsize_t *           Number of attribute elements            |
|  size           hsize_t *           buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10   Abe Taaheri   Original Development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDdscaleattrinfo2(hid_t gridID, const char *fieldname, const char *attrname, hid_t *ntype, hsize_t *count, hsize_t *size)
{
  herr_t     status        = FAIL;/* routine return status variable */
  
  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
  
  long       idx           = FAIL;/* Grid index                     */
  
  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */
  
  CHECKPOINTER(fieldname);
  CHECKPOINTER(attrname);
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdscaleattrinfo2", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get field ID */
      /* ------------ */

      fieldID = H5Dopen(HE5_GDXGrid[idx].gd_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDdscaleattrinfo2", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}

      /* Call EHattrinfo */
      /* --------------- */
      if(strcmp(attrname,"REFERENCE_LIST") !=0)/* do not need ntype for 
						  internal dimension
						  scale attribute */
	{
	  status = HE5_EHattrinfo2(fieldID, attrname, ntype, count, size);
	  if(status == FAIL)
	    {
	      sprintf(errbuf,"Cannot retrieve information about Attribute \"%s\" associated with the dimension scale\"%s\".\n", attrname, fieldname);
	      H5Epush(__FILE__, "HE5_GDdscaleattrinfo2", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(status);
	    }
	}
      else
	{
	  status = -1;
	  *ntype = -1;
	  *count = 0;
	  sprintf(errbuf,"Will not retrieve information about internal Attribute \"%s\" associated with the dimension scale \"%s\" .\n", attrname, fieldname);
	  H5Epush(__FILE__, "HE5_GDdscaleattrinfo2", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}

      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDdscaleattrinfo2", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	
    }

 COMPLETION:
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwritefieldmeta                                             |
|                                                                             |
|  DESCRIPTION: Writes field meta data for an existing grid field not         |
|               defined within the grid API routine "HE5_GDdeffield".         |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               fieldname                               |
|  dimlist        char*               Dimension list (comma-separated list)   |
|  ntype          hid_t               Data type ID metadata value             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/20/99  A.Muslimov    In the call to EHinsertmeta() replaced the argument |
|                         gid by fid.                                         |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  May  05  S.Zhao        Added HE5_EHdtype2numtype() function call.          |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDwritefieldmeta(hid_t gridID, const char *fieldname, char *dimlist, hid_t ntype)
{
  herr_t          status     = FAIL; /* routine return status variable */

  hsize_t         metavalue  = 0;    /* Metavalue to insert            */
  hid_t           fid        = FAIL; /* HDF-EOS file ID                */
  hid_t           gid        = FAIL; /* "HDFEOS" group ID              */
  
  long            idx        = FAIL; /* Grid index                     */

  char            utlbuf[HE5_HDFE_DIMBUFSIZE]; /* Utility buffer       */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* error message buffer */
  hid_t           numtype    = FAIL;           /* Number type ID       */

  HE5_LOCK;
  CHECKNAME(fieldname);
  CHECKPOINTER(dimlist);

  numtype = HE5_EHdtype2numtype(ntype);
  if (numtype == FAIL)
    {
      sprintf(errbuf, "Cannot get the number type ID. \n");
      H5Epush(__FILE__, "HE5_GDwritefieldmeta", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
  else if (numtype == 0)
    {
      metavalue = 0;
    }
  else
    {
      metavalue = HE5_EHhid2hsize(numtype);
      if ( metavalue == 0 )
	{
	  sprintf(errbuf, "Cannot convert metadata value. \n");
	  H5Epush(__FILE__, "HE5_GDwritefieldmeta", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
    }


  status = HE5_GDchkgdid(gridID, "HE5_GDwritefieldmeta", &fid, &gid,  &idx);
  if (status == SUCCEED)
    {
      sprintf(utlbuf, "%s%s%s", fieldname, ":", dimlist);
      status = HE5_EHinsertmeta(fid, HE5_GDXGrid[idx].gdname, "g", 4L, utlbuf, &metavalue);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot insert metadata value. \n");
	  H5Epush(__FILE__, "HE5_GDwritefieldmeta", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrrdfield                                                  |
|                                                                             |
|  DESCRIPTION: Writes/Reads fields                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char*               fieldname                               |
|  code           char*               Write/Read code (w/r)                   |
|  start          hssize_t            start array                             |
|  stride         hsize_t             stride array                            |
|  edge           hsize_t             edge array                              |
|  count          hsize_t             array of the size of each dimension     |
|  datbuf         void                data buffer for read                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                data buffer for write                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|              H5Dextend                                                      |
|              H5Dget_space                                                   |
|              H5Sselect_hyperslab                                            |
|              H5Screate_simple                                               |
|              H5Dget_type                                                    |
|              H5Dwrite                                                       |
|              H5Dread                                                        |
|              H5Sclose                                                       |
|              H5Tclose                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    Changed the data type of status variable from intn  |
|                         to int   . Checked for the statuses returned by     |
|                         H5Tclose() and H5Sclose(). Removed second call to   |
|                         H5Sselect_hyperslab(). Renamed  variable numbertype |
|                         by tid. Initialized dims[] array. In the call to    |
|                         H5Screate_simple() replaced the second argument by  |
|                         count. In the call to H5Tclose() passed tid as an   |
|                         argument.                                           |
| Jan 00   A.Muslimov     Modified to enable extendibility of a  dataset.     |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 07/17/00  A.Muslimov    Added EHdtype2mtype() before the call to H5Dread(). |
| Dec 4,00  A.Muslimov    Modified to fix a problem with appending data to the|
|                          extendible dataset.                                |
|  Aug  03  S.Zhao        Added checking for SOMBlockDim in the dimlist.      |
|  Jan  04  S.Zhao        Added to create a character string dataset.         |
|  Apr  04  S.Zhao        Added the HE5_GDfldnameinfo() call.                 |
|  Apr  04  S.Zhao        Modified for a character string dataset.            |
|  Feb  05  S.Zhao        Replaced the "count" array by the "dims" array if   |
|                         it was declared larger than the dimension size.     |
|  Sep  11  Abe Taaheri   Modified for correcting Unlimited dimension         |
|                         behavior and extension                              |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static herr_t  
HE5_GDwrrdfield(hid_t gridID, const char *fieldname, char *code, const hssize_t start[], 
const hsize_t stride[], const hsize_t  count[], void * datbuf)
{
  herr_t          status   = FAIL; /* routine return status variable     */

  int             i;		   /* Loop index                         */
  int             startf   =  0;   /* flag (if start is NULL)            */
  int             countf   =  0;   /* flag (if counf is NULL)            */
  int             bothf    =  0;   /* flag (if start and count are NULL) */
  hssize_t        *tstart =(hssize_t *)NULL;/* Not NULL "start" value    */
  hsize_t         *tcount = (hsize_t *)NULL;/* Not NULL "count" value    */
  hsize_t         *lcount = (hsize_t *)NULL;
  int             append   = FALSE;/* Flag                            */
  int             rank     = FAIL; /* Rank of dataset                 */
  int             rankidx1 = 0;	   /* Dummy rank index                */
  int             rankidx2 = 0;	   /* Dummy rank index                */
  int             projcode = FAIL; /* Projection Code                 */
     

  hid_t           fid      = FAIL;/* HDF-EOS file ID                  */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID                */
  hid_t           tid      = FAIL;/* datatype ID                      */
  hid_t           fspace   = FAIL;/* File dataspace ID                */
  hid_t           dtsid    = FAIL;/* field dataset ID                 */
  hid_t	          mid      = FAIL;/* Memory dataspace ID              */
  hid_t           mtype    = FAIL;/* Memory data type ID              */

  long            idx      = FAIL;/* Grid index                       */
  long            xdim     = FAIL;/* Grid X dimension size            */
  long            ydim     = FAIL;/* Grid Y dimension size            */
     
  hsize_t         dims[HE5_DTSETRANKMAX]    = {0, 0, 0, 0, 0, 0, 0, 0 };/* Field dataset dimensions      */
  hsize_t         maxdims[HE5_DTSETRANKMAX] = {0, 0, 0, 0, 0, 0, 0, 0 };/* Field dataset max. dimensions */
  hsize_t         dimsize                   = 0;		                /* Dimension size                */
  hsize_t         size[HE5_DTSETRANKMAX]    = {0, 0, 0, 0, 0, 0, 0, 0 };/* Size to extend the dataset to */
    
  hid_t           *ntype                    = (hid_t *)NULL;            /* number types                  */ 

  double          projparm[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};/* Projection Parameters        */

  char            errbuf[HE5_HDFE_ERRBUFSIZE];
  char            maxdimlist[HE5_HDFE_DIMBUFSIZE];
  char            dimlist[HE5_HDFE_DIMBUFSIZE];
  char            *dimcheck = (char *)NULL;
  char            *comma    = (char *)NULL;
  char            *dimbuf   = (char *)NULL;
  char            *dimlist0 = (char *)NULL;	     /* Auxilliary dimension list */
  char            *nameptr  = (char *)NULL;
  char            tempname[HE5_HDFE_NAMBUFSIZE];
  H5T_class_t     classid = H5T_NO_CLASS;            /* data type class ID     */
  int             nameflag = FAIL;                   /* Actual (1)/Alias (0) field name    */
  char            fldname[HE5_HDFE_NAMBUFSIZE];      /* Field name buffer      */
  char            fldactualname[HE5_HDFE_NAMBUFSIZE];/* Actual field name      */

  int             ibuf;                /* Loop index                        */
  char            **chardatbuf = NULL; /* string data buffer                */
  int             maxlen = 0;          /* max length in array of string     */
  int             strsize = 0;         /* each str length in array of str   */
  hsize_t         numattr[1];          /* number of attribute elements      */
  int             mycount = 0;         /* flag                              */
  long            strbufsize1;         /* string buffer size                */
  long            strbufsize2;         /* string buffer size                */
  long            nattr = 0;           /* number of attributes              */
  char            *attrlist1 = (char *)NULL;/* attribute list               */
  char            *attrlist2 = (char *)NULL;/* attribute list               */
  char            *attptr = (char *)NULL;   /* attribute pointer            */
  hsize_t	  dimsize_dim, dimsize_maxdim;
  char            *dimname[HE5_DTSETRANKMAX];
  CHECKNAME(fieldname);
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDwrrdfield", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
		
      return(FAIL);
    }

  /* Call HE5_GDfldnameinfo() to get actual field name */
  /* ------------------------------------------------- */
  nameflag = HE5_GDfldnameinfo(gridID, fieldname, fldactualname);
  if ( nameflag == FAIL )
    {
      sprintf(errbuf, "Cannot get actual name of the field.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
 
      return(FAIL);
    }
 
  /* Name is not alias */
  /* ----------------- */
  if (nameflag == TRUE)
    {
      strcpy(fldname,"");
      strcpy(fldname,fieldname);
    }
 
  /* Name is an alias */
  /* ---------------- */
  if (nameflag == FALSE)
    {
      strcpy(fldname,"");
      strcpy(fldname,fldactualname);
    }

  /* Check that field exists */
  /* ----------------------- */
  ntype = (hid_t *)calloc(1, sizeof(hid_t));
  if(ntype == (hid_t *)NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
 		
      return(FAIL);
    } 
    
  strcpy(dimlist,"");
  strcpy(maxdimlist,"");

  /* Get Field info */
  /* -------------- */
  status = HE5_GDfieldinfo(gridID, fldname, &rank, dims, ntype, dimlist, maxdimlist);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot get information about %s field.\n", fldname );
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(ntype);
	
      return(FAIL);
    }
  free(ntype);
    
	
  /* Allocate space for dimension buffer  */
  /* ------------------------------------ */
  dimbuf = (char *)calloc(strlen(dimlist) + 64, sizeof(char));
  if(dimbuf == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for dimension buffer.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      
      return(FAIL);
    }
	
  /* Allocate space for an auxilliary dimension list */
  /* ----------------------------------------------- */
  dimlist0 = (char *)calloc(strlen(dimlist) + 64, sizeof(char));
  if(dimlist0 == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for dimension list string.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(dimbuf);
		
      return(FAIL);
    }
	

  /* Get Grid info */
  /* ------------- */
  status = HE5_GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot get information about Grid.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(dimbuf);
      free(dimlist0);
	  
      return(FAIL);
    }
	
  /* Get Projection info */
  /* ------------------- */
  status = HE5_GDprojinfo(gridID, &projcode, NULL, NULL, projparm);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot get Grid projection information.\n");  
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(dimbuf);
      free(dimlist0);
		
      return(FAIL);
    }
	
	
  /* Setup Block Dimension if "Blocked" SOM projection */
  /* ------------------------------------------------- */
  if (projcode == HE5_GCTP_SOM && (long)projparm[11] != 0)
    {
      dimsize = HE5_GDdiminfo(gridID, "SOMBlockDim");
		
      /* If not 1D field then prepend to dimension list */
      /* ---------------------------------------------- */
      if (strchr(dimlist, ',') != NULL)
	{
	  strcpy(tempname, dimlist);
	  nameptr = strchr( tempname, ',' );
	  if ( nameptr != NULL )
	    {
	      nameptr[0] = '\0';
	    }
 
	  if ( strcmp(tempname, "SOMBlockDim") != 0)
	    {
	      strcpy(dimbuf, "SOMBlockDim,");
	      strcat(dimbuf, dimlist);
	    }
	  else
	    {
	      strcpy(dimbuf, dimlist);
	    }
	}
      else
	{
	  strcpy(dimbuf, dimlist);
	}
    }
  else
    {
      /* If not "Blocked" SOM then just copy dim list to dim buffer */
      strcpy(dimbuf, dimlist);
    }
	
  /*
   * Copy dimension buffer to auxilliary dimlist and Append comma to
   * end of dimension list
   */
  strcpy(dimlist0, dimbuf);
  strcat(dimbuf, ",");
	
	
  /* Find comma */
  /* ---------- */
  comma = strchr(dimbuf, ',');
	
  /*
   * Loop through entries in dimension list to make sure they are
   * defined in grid
   */
  while (comma != NULL)
    {
      /* Copy dimension list entry to dimcheck */
      /* ------------------------------------- */
      dimcheck = (char *) calloc(comma - dimbuf + 1, sizeof(char));
      if(dimcheck == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory.\n");
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if(dimbuf != NULL) free(dimbuf);
	  if(dimlist0 != NULL) free(dimlist0);
			
	  return(FAIL);
	}
      memmove(dimcheck, dimbuf, comma - dimbuf);
		
      /* Get Dimension Size */
      /* ------------------ */
      if (strcmp(dimcheck, "XDim") == 0)
	{
	  /* If "XDim" then use xdim value for grid definition */
	  /* ------------------------------------------------- */
	  dimsize        = (hsize_t)xdim;
	  dims[rankidx1] = dimsize;
	  dimname[rankidx1] = (char *)malloc(HE5_HDFE_NAMBUFSIZE * sizeof(char));
	  strcpy(dimname[rankidx1],dimcheck);
	  rankidx1++;
	}
      else if (strcmp(dimcheck, "YDim") == 0)
	{
	  /* If "YDim" then use ydim value for grid definition */
	  /* ------------------------------------------------- */
	  dimsize        = (hsize_t)ydim;
	  dims[rankidx1] = dimsize;
	  dimname[rankidx1] = (char *)malloc(HE5_HDFE_NAMBUFSIZE * sizeof(char));
	  strcpy(dimname[rankidx1],dimcheck);
	  rankidx1++;
	}
      else
	{
	  /* "Regular" Dimension */
	  /* ------------------- */
	  dimsize = HE5_GDdiminfo(gridID, dimcheck);
	  if (dimsize > 0)
	    {
	      dims[rankidx1] = dimsize;
	      dimname[rankidx1] = (char *)malloc(HE5_HDFE_NAMBUFSIZE * sizeof(char));
	      strcpy(dimname[rankidx1],dimcheck);
	      rankidx1++;
	    }
	  else
	    {
	      sprintf(errbuf, "Dimension \"%s\" not found.\n", dimcheck);
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if(dimbuf != NULL) free(dimbuf);
	      if(dimlist0 != NULL) free(dimlist0);
				
	      return(FAIL);
	    }
	}

      memmove(dimbuf, comma + 1, strlen(comma)-1);
      dimbuf[strlen(comma)-1]= 0;
      comma = strchr(dimbuf, ',');
      if(dimcheck != NULL) free(dimcheck);
    }

  if(dimbuf != NULL)
    free(dimbuf);
	
  free(dimlist0);
    
	
  /* Initialize maxdims[] array with dims[] array values */
  /* --------------------------------------------------- */
  for (i = 0; i < rank; i++)
    maxdims[i] = dims[i];
  
	
  /* Check out if the field is appendable */
  /* in the following it is assumed that XDim and YDim 
     cannot be appendable since they define a grid that
     has a preset corner lat/lon (x/y) coordinates. The other
     dimensions represent band, etc abd can be appendable */
  /* ---------------------------------------------------- */
  dimbuf = (char *)calloc(strlen(maxdimlist) + 64, sizeof(char));   
  if(dimbuf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
		
      return(FAIL);
    }
	
  strcpy(dimbuf, maxdimlist);
  strcat(dimbuf,",");
  comma = strchr(dimbuf,',');
    
  while(comma != NULL)
    {
      dimcheck = (char *)calloc(comma-dimbuf +1, 1);
      memmove(dimcheck,dimbuf,comma-dimbuf);
      if (strcmp(dimcheck,"XDim") == 0)
	{
	  dimsize = (hsize_t)xdim; /* XDim will not be appendable */
	}
      else if (strcmp(dimcheck,"YDim") == 0)
	{
	  dimsize = (hsize_t)ydim; /* YDim will not be appendable */
	}
      else 
	dimsize = HE5_GDdiminfo(gridID, dimcheck);
	
      /* update maxdim array */	
      if ( (dimsize > 0) || (dimsize == H5S_UNLIMITED)  )
	{
	  maxdims[ rankidx2 ] = dimsize;

	  /* see if we need to update dim in the structuremetadata */

	  if ( (dims[rankidx2] < maxdims[rankidx2]) || 
	       (maxdims[rankidx2] == H5S_UNLIMITED))
	    {
	      /* update dim if new dim is still <= maxdim */
	      if((start[rankidx2]+1) > maxdims[rankidx2] && 
		 (maxdims[rankidx2] != H5S_UNLIMITED))
		{
		  sprintf(errbuf, "Cannot update the dimension, new dimension size is larger than the max dimension size in the datafiled.\n");
		  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, 
			  H5E_DATASET, H5E_WRITEERROR, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  return(FAIL);
		}
	      else
		{
		  status = HE5_GDupdatedim(gridID,dimname[rankidx2], start[rankidx2]+1);
		  if( status == FAIL )
		    {
		      sprintf(errbuf, "Cannot update the dimension.\n");
		      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, 
			      H5E_DATASET, H5E_WRITEERROR, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      return(FAIL);
		    } 
		}
	    }

	  rankidx2++;
	}

      memmove(dimbuf,comma+1,strlen(comma+1)+1); 
      comma=strchr(dimbuf,',');
      free(dimcheck);
    }
  free(dimbuf);

  for(i = 0; i < rank; i++)
    {
      if(dimname[i] != NULL)
	{
	  free(dimname[i]);
	  dimname[i] = NULL;
	}
    }

  for(i = 0; i < rank; i++)
    {
      if( dims[i] == maxdims[i] )
	append = FALSE;
      else if ( (dims[i] < maxdims[i]) || (maxdims[i] == H5S_UNLIMITED))
	{
	  append = TRUE;
	  break;
	}
      else
	{
	  status = FAIL;
	  sprintf(errbuf, "Maximum dimension size is smaller than dimension size.\n");
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
			
	  return(status);
	}
    } 
 
  /* ============================================================== */
  /* start and count are being passed as NULL from GDdefvrtregion   */
  /* which calls GDreadfield, which have NULL for start and count.  */
  /* H5Sselect_hyperslab won't take NULL values for start and count */
  /* ============================================================== */
  if(start == NULL)
    {
      tstart = (hssize_t *)calloc(rank, sizeof(hssize_t));
      for(i = 0; i < rank; i++)
	tstart[ i ] = 0;
      startf = 1;
    }
  if(count == NULL)
    {
      tcount = (hsize_t *)calloc(rank, sizeof(hsize_t));
      for(i = 0; i < rank; i++)
	tcount[ i ] = dims[ i ];
      if(startf == 1)
	bothf = 1;
      else
	countf = 1;
    }
  else
    {
      lcount =  (hsize_t *)calloc(rank, sizeof(hsize_t));

      /* get dims and maxdims for the field after 
	 dim update for appendable dim*/
      status = HE5_GDflddiminfo(gridID, fldname, &rank, dims, maxdims);

      for(i = 0; i < rank; i++)
	{
	  if(count[ i ] > dims[ i ])
	    lcount[ i ] = dims[ i ];
	  else
	    lcount[ i ] = count[ i ];
	}
    }

  if (append == TRUE)
    {
      /* Get the field-related dataset ID */
      /* -------------------------------- */
      status = HE5_GDgetfieldID(gridID, fldname, &dtsid);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot get %s field ID.\n", fldname );
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (start == NULL)
	    {
	      if (tstart != NULL)
		free(tstart);
	    }
	  if (count == NULL)
	    {
	      if (tcount != NULL)
		free(tcount);
	    }
	  if (lcount != NULL)
	    free(lcount);
			
	  return(FAIL);
	}

      if(bothf == 1)
	status = H5Dextend(dtsid, tcount);
      else if(startf == 1)
	status = H5Dextend(dtsid, lcount);
      else if(countf == 1)
	status = H5Dextend(dtsid, tcount);
      else
	{
	  /* Calculate the size to extend the dataset to */
	  /* ------------------------------------------- */
	  for (i = 0; i < rank; i++)
	    size[ i ] = start[ i ] + lcount[ i ]; 
	  
	  /* Extend the dataset size */
	  /* ----------------------- */
	  status = H5Dextend(dtsid, size);
	}

      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot extend dataset for the \"%s\" field.\n", fldname );
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (start == NULL)
	    {
	      if (tstart != NULL)
		free(tstart);
	    }
	  if (count == NULL)
	    {
	      if (tcount != NULL)
		free(tcount);
	    }
	  if (lcount != NULL)
	    free(lcount);
			
	  return(FAIL);
	}	
		
    }
	
  if (append == FALSE)
    {
      /* Get the field-related dataset ID only */
      status = HE5_GDgetfieldID(gridID, fldname, &dtsid);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot get %s field ID.\n", fldname );
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (start == NULL)
	    {
	      if (tstart != NULL)
		free(tstart);
	    }
	  if (count == NULL)
	    {
	      if (tcount != NULL)
		free(tcount);
	    }
	  if (lcount != NULL)
	    free(lcount);
			
	  return(FAIL);
	}
		
    }
    
	
  /* Get the field space ID */
  /* --------------------- */
  fspace = H5Dget_space(dtsid);
  if ( fspace == FAIL)
    {
      sprintf(errbuf, "Cannot get the file data space ID.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASPACE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (start == NULL)
	{
	  if (tstart != NULL)
	    free(tstart);
	}
      if (count == NULL)
	{
	  if (tcount != NULL)
	    free(tcount);
	}
      if (lcount != NULL)
	free(lcount);
		
      return(FAIL);
    }

  /* Select the hyperslab */
  /* -------------------- */
  if(bothf == 1)
    status = H5Sselect_hyperslab( fspace, H5S_SELECT_SET, (const hsize_t *)tstart,stride,tcount,NULL);
  else if(startf == 1)
    status = H5Sselect_hyperslab( fspace, H5S_SELECT_SET, (const hsize_t *)tstart,stride,lcount,NULL);
  else if(countf == 1)
    status = H5Sselect_hyperslab( fspace, H5S_SELECT_SET, (const hsize_t *)start,stride,tcount,NULL);
  else
    status = H5Sselect_hyperslab(fspace,H5S_SELECT_SET,(const hsize_t *)start,stride,lcount,NULL) ;

  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot select the hyperslab.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (start == NULL)
	{
	  if (tstart != NULL)
	    free(tstart);
	}
      if (count == NULL)
	{
	  if (tcount != NULL)
	    free(tcount);
	}
      if (lcount != NULL)
	free(lcount);
		
      return(FAIL);
    }
    
  /* Create dataspace for the dataset */
  /* -------------------------------- */
  if(countf == 1 || bothf == 1)
    mid = H5Screate_simple(rank, tcount, NULL);
  else
    mid = H5Screate_simple(rank,lcount, NULL);

  if ( mid == FAIL )
    {
      sprintf(errbuf, "Cannot create the dataspace for the dataset.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (start == NULL)
	{
	  if (tstart != NULL)
	    free(tstart);
	}
      if (count == NULL)
	{
	  if (tcount != NULL)
	    free(tcount);
	}
      if (lcount != NULL)
	free(lcount);
		
      return(FAIL);
    }
	
  /* Get the data type ID */
  /* -------------------- */
  tid = H5Dget_type( dtsid );
  if ( tid == FAIL)
    {
      sprintf(errbuf, "Cannot get the data type ID.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (start == NULL)
	{
	  if (tstart != NULL)
	    free(tstart);
	}
      if (count == NULL)
	{
	  if (tcount != NULL)
	    free(tcount);
	}
      if (lcount != NULL)
	free(lcount);
		
      return(FAIL);
    }

  /* Get the data type class ID */
  /* -------------------------- */
  classid = H5Tget_class(tid);
  if (classid == H5T_NO_CLASS)
    {
      sprintf(errbuf, "Cannot get the data type ID.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      if (start == NULL)
	{
	  if (tstart != NULL)
	    free(tstart);
	}
      if (count == NULL)
	{
	  if (tcount != NULL)
	    free(tcount);
	}
      if (lcount != NULL)
	free(lcount);
 
      return(FAIL);
    }

  /* Write whole data to dataset */
  /* --------------------------- */
  if( strcmp(code,"w")==0)
    {
      strbufsize1 = 0;
      nattr = HE5_GDinqlocattrs(gridID, fldname, NULL, &strbufsize1);
      if ( nattr < 0 )
	{
	  sprintf(errbuf, "Cannot retrieve the attributes. \n");
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (start == NULL)
	    {
	      if (tstart != NULL)
		free(tstart);
	    }
	  if (count == NULL)
	    {
	      if (tcount != NULL)
		free(tcount);
	    }
	  if (lcount != NULL)
	    free(lcount);
 
	  return(FAIL);
 
	}
 
      attrlist1 = (char *) calloc(strbufsize1 + 2, sizeof(char));
      if (attrlist1 == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for attrlist1.\n") ;
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (start == NULL)
	    {
	      if (tstart != NULL)
		free(tstart);
	    }
	  if (count == NULL)
	    {
	      if (tcount != NULL)
		free(tcount);
	    }
	  if (lcount != NULL)
	    free(lcount);
 
	  return(FAIL);
 
	}
 
      nattr = HE5_GDinqlocattrs(gridID, fldname, attrlist1, &strbufsize1);
      if ( nattr < 0 )
	{
	  sprintf(errbuf, "Cannot retrieve the attributes. \n");
	  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (attrlist1 != NULL)
	    {
	      free(attrlist1);
	      attrlist1 = NULL;
	    }
	  if (start == NULL)
	    {
	      if (tstart != NULL)
		free(tstart);
	    }
	  if (count == NULL)
	    {
	      if (tcount != NULL)
		free(tcount);
	    }
	  if (lcount != NULL)
	    free(lcount);
 
	  return(FAIL);
 
	}
 
      attptr = strstr(attrlist1,"ARRAYOFSTRINGS");
      if ( (classid == H5T_STRING) && (attptr == NULL) )
	{
	  status = H5Dwrite(dtsid, tid, mid, fspace,  H5P_DEFAULT, datbuf);
	  if( status == FAIL )
	    {
	      sprintf(errbuf,"Cannot write data to the dataset.\n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(status);
	    }
	}
 
      else if ( (classid == H5T_STRING) && (attptr != NULL) )
	{
	  strbufsize2 = 0;
	  nattr = HE5_GDinqlocattrs(gridID, fldname, NULL, &strbufsize2);
	  if ( nattr < 0 )
	    {
	      sprintf(errbuf, "Cannot retrieve the attributes. \n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(FAIL);
 
	    }
 
	  attrlist2 = (char *) calloc(strbufsize2 + 2, sizeof(char));
	  if (attrlist2 == NULL)
	    {
	      sprintf(errbuf, "Cannot allocate memory for attrlist2.\n") ;
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(FAIL);
 
	    }
 
	  nattr = HE5_GDinqlocattrs(gridID, fldname, attrlist2, &strbufsize2);
	  if ( nattr < 0 )
	    {
	      sprintf(errbuf, "Cannot retrieve the attributes. \n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (attrlist2 != NULL)
		{
		  free(attrlist2);
		  attrlist2 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(FAIL);
 
	    }
 
	  if ( (nattr == 0) || ((attptr = strstr(attrlist2,"StringLengthAttribute")) == NULL) )
	    {
	      htri_t  str_is_variable = FALSE;
	      chardatbuf = (char **)datbuf;
	      str_is_variable = H5Tis_variable_str(tid);
	      if(str_is_variable == TRUE)
		{
		  if (count == NULL) mycount = tcount[0];
		  if (count != NULL) mycount = *lcount;
		  for (ibuf = 0; ibuf < mycount; ibuf++)
		    {
		      if (chardatbuf[ibuf] == NULL)
			{
			  strsize = 0;
			}
		      else
			{
			  strsize = strlen(chardatbuf[ibuf]);
			}

		      if (strsize > maxlen)
			maxlen = strsize;
		    }
		}
	      else
		{
		  strsize=(int)H5Tget_size(tid);
		  maxlen = strsize;
		}

	      numattr[0] = 1;
	      status = HE5_GDwritelocattr(gridID, fldname, "StringLengthAttribute", H5T_NATIVE_INT, numattr, &maxlen);
	      if (status == FAIL)
		{
		  sprintf(errbuf, "Cannot write attribute to the field \"%s\".",fldname) ;
		  H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  if (attrlist1 != NULL)
		    {
		      free(attrlist1);
		      attrlist1 = NULL;
		    }
		  if (attrlist2 != NULL)
		    {
		      free(attrlist2);
		      attrlist2 = NULL;
		    }
		  if (start == NULL)
		    {
		      if (tstart != NULL)
			free(tstart);
		    }
		  if (count == NULL)
		    {
		      if (tcount != NULL)
			free(tcount);
		    }
		  if (lcount != NULL)
		    free(lcount);
 
		  return(status);
		}
 
	    }
 
	  status = H5Dwrite(dtsid, tid, mid, fspace,  H5P_DEFAULT, datbuf);
	  if( status == FAIL )
	    {
	      sprintf(errbuf,"Cannot write data to the dataset.\n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (attrlist2 != NULL)
		{
		  free(attrlist2);
		  attrlist2 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(status);
	    }
	}
      else
	{
	  /* Get memory data type ID */
	  /* ----------------------- */
	  mtype  = HE5_EHdtype2mtype(tid);
	  if( mtype == FAIL )
	    {
	      sprintf(errbuf,"Cannot convert to memory data type.\n");
	      status = FAIL;
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(status);
	    }
 
	  status = H5Dwrite(dtsid, mtype, mid, fspace, H5P_DEFAULT, datbuf);
	  if( status == FAIL )
	    {
	      sprintf(errbuf,"Cannot write data to the dataset.\n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (attrlist1 != NULL)
		{
		  free(attrlist1);
		  attrlist1 = NULL;
		}
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(status);
	    }
	}
 
      if (attrlist1 != NULL)
	{
	  free(attrlist1);
	  attrlist1 = NULL;
	}
      if (attrlist2 != NULL)
	{
	  free(attrlist2);
	  attrlist2 = NULL;
	}
 
    }	
  else
    {
      if (classid == H5T_STRING)
	{
	  /* Read the data buffer */
	  /* -------------------- */
	  status = H5Dread(dtsid, tid, mid, fspace , H5P_DEFAULT, datbuf);
	  if( status == FAIL )
	    {
	      sprintf(errbuf,"Cannot read out data from the dataset.\n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
 
	      return(status);
	    }
 
	}
      else
	{
	  /* Get memory data type ID */
	  /* ----------------------- */
          mtype  = HE5_EHdtype2mtype(tid);
	  if ( mtype == FAIL )
	    {
	      sprintf(errbuf, "Cannot get the memory data type.\n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
			
	      return(FAIL);
	    }

	  status = H5Dread(dtsid, mtype, mid,fspace , H5P_DEFAULT, datbuf);
	  if ( status == FAIL )
	    {
	      sprintf(errbuf, "Cannot read out data from the dataset.\n");
	      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      if (start == NULL)
		{
		  if (tstart != NULL)
		    free(tstart);
		}
	      if (count == NULL)
		{
		  if (tcount != NULL)
		    free(tcount);
		}
	      if (lcount != NULL)
		free(lcount);
			
	      return(FAIL);
	    }
	}
		
    }

  if ( count  == NULL)
    {
      if(tcount != NULL) free(tcount);
    }
  if( start == NULL)
    {
      if(tstart != NULL) free(tstart);
    }
  if (lcount != NULL)
    free(lcount);
	
  /* Release data space ID */
  /* --------------------- */
  status = H5Sclose(fspace);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot release the dataspace ID.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);

      return(FAIL);
    }
	
  /* Release data space ID */
  /* --------------------- */
  status = H5Sclose(mid);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot release the dataspace ID.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
		   
      return(FAIL);
    }
	
  /* Release data type  ID */
  /* --------------------- */
  status = H5Tclose( tid );
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot release the datatype ID.\n");
      H5Epush(__FILE__, "HE5_GDwrrdfield", __LINE__, H5E_DATATYPE, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
		
      return(FAIL);
    }
	
 COMPLETION:
  return(status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwritefield                                                 |
|                                                                             |
|  DESCRIPTION: Writes data to a grid field.                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               fieldname                               |
|  start          hssize_t            start array                             |
|  stride         hsize_t             stride array                            |
|  edge           hsize_t             edge array                              |
|  data           void                data buffer for write                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
| 09/29/11  Abe Taaheri   Modified for correcting Unlimited dimension         |
|                         behavior and extension                              |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDwritefield(hid_t gridID, const char *fieldname, const hssize_t start[], const hsize_t stride[], const hsize_t edge[], void *data)
{
  herr_t          status = FAIL;            /* routine return status variable */
  hsize_t         dims[HE5_DTSETRANKMAX];   /* Field dimensions          */
  int   	  rank     = 0;             /* Field rank                */
  int             unlimdim;
  hsize_t         maxdims[HE5_DTSETRANKMAX];/* Field maximum dimensions  */
  int             append   = FALSE;         /* FLAG (if field is appendable)*/
  int             i;                        /* Loop index                   */
  char            *errbuf = (char *)NULL;   /* error message buffer        */
  char            *temp_fieldname = (char *)NULL;
  int             stlen;

  HE5_LOCK;
  CHECKNAME(fieldname);
  CHECKPOINTER(data);

  /* If a field is appendable and need to be extended, do extension here 
     before writing extended data into it 
  */
  stlen = strlen(fieldname);
  temp_fieldname = (char *)malloc((stlen+1)*sizeof(char));
  if(temp_fieldname == (char *)NULL)
    {
      H5Epush(__FILE__, "HE5_GDwritefield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, 
	      "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for temp_fieldname, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  else
    {
      strcpy(temp_fieldname,fieldname);
      temp_fieldname[stlen] = '\0';
    }

  /* get maxdims for the field */

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == (char *)NULL)
    {
      H5Epush(__FILE__, "HE5_GDwritefield", __LINE__, H5E_RESOURCE, H5E_NOSPACE, 
	      "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      free(temp_fieldname);
      temp_fieldname = (char *)NULL;
      return(FAIL);
    }

  status = HE5_GDflddiminfo(gridID, temp_fieldname, &rank, dims, maxdims);
  
/* see if we need first to extend data dimensions for unlimited 
     dimensions */
  
  for (i = 0; i < rank; i++)
    {
      if( dims[i] == maxdims[i] )
	append = FALSE;
      else if ( (dims[i] < maxdims[i]) || (maxdims[i] == H5S_UNLIMITED))
	{
	  append = TRUE;
	  break;
	}
    }
  unlimdim = i;

  if((append == TRUE) && (edge[unlimdim] > dims[unlimdim]))
    {
      hssize_t newstart[8];
      hsize_t newedge[8];
      
      for (i = 0; i < rank; i++)
	{
	  if (start != NULL)
	    {
	      newstart[i]=start[i];
	    }
	  else
	    {
	      newstart[i]= 0;
	    }

	  if (edge!= NULL)
	    {
	      newedge[i] = edge[i];
	    }
	  else
	    {
	      newedge[i]=dims[i];
	    }
	}
      newstart[unlimdim]=edge[unlimdim]-1;

      newedge[unlimdim] = 1;

      status = HE5_GDwrrdfield(gridID, fieldname, "w", newstart, stride, newedge, data);

      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot write data to the field \"%s\".",fieldname) ;
	  H5Epush(__FILE__, "HE5_GDwritefield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(temp_fieldname);
	  temp_fieldname = (char *)NULL;
	  return(FAIL);
	}
      else
	{
	  for (i = 0; i < rank; i++)
	    {
	      dims[i]=edge[i];
	    }
	 
	}
    }
 
  status = HE5_GDwrrdfield(gridID, fieldname, "w", start, stride, edge, data);
  if (status == FAIL)
    {
      sprintf(errbuf, "Cannot write data to the field \"%s\".",fieldname) ;
      H5Epush(__FILE__, "HE5_GDwritefield", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      errbuf = (char *)NULL;
      free(temp_fieldname);
      temp_fieldname = (char *)NULL;
      return(FAIL);
    }
  else
    {
      status = SUCCEED;
      free(errbuf);
      errbuf = (char *)NULL;
      free(temp_fieldname);
      temp_fieldname = (char *)NULL;
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreadfield                                                  |
|                                                                             |
|  DESCRIPTION: Reads data from a grid field.                                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char                fieldname                               |
|  start          hssize_t            start array                             |
|  stride         hsize_t             stride array                            |
|  edge           hsize_t             edge array                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                data buffer for read                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDreadfield(hid_t gridID, const char *fieldname, const hssize_t start[], const hsize_t stride[],  const hsize_t edge[], void *buffer)

{
  herr_t            status = FAIL;            /* routine return status variable */

  HE5_LOCK;
  CHECKPOINTER(fieldname);

  status = HE5_GDwrrdfield(gridID, fieldname, "r", start, stride, edge, buffer);

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwriteattr                                                  |
|                                                                             |
|  DESCRIPTION: Writes/updates attribute in a grid.                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char*               attribute name                          |
|  ntype          hid_t               Attribute data type ID                  |
|  count[]        hsize_t             Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDwriteattr(hid_t gridID, const char *attrname, hid_t ntype, hsize_t  count[],  void *datbuf)
{
  herr_t     status     = FAIL;/* routine return status variable */
  
  hid_t      fid        = FAIL;/* HDF-EOS file ID                */
  hid_t      gid        = FAIL;/* "HDFEOS" group ID              */
  
  long       idx        = FAIL;/* Grid index                     */
  hid_t      dtype;

  HE5_LOCK;
  CHECKNAME(attrname);
  CHECKPOINTER(count);
  CHECKPOINTER(datbuf);

  /* 
     if ntype is HE5 numbertype, rather than H5 numbertype, then convert
     it, otherwise use ntype itself
  */
  dtype = HE5_EHconvdatatype(ntype);
  if(dtype == FAIL)
    {
      dtype = ntype;
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDwriteattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get "Grid Attributes" group ID and call EHattr to perform I/O */
      /* ------------------------------------------------------------- */
      status = HE5_EHattr(HE5_GDXGrid[idx].gd_id, attrname, ntype, count,"w", datbuf);
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreadattr                                                   |
|                                                                             |
|  DESCRIPTION: Reads attribute from a grid.                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDreadattr(hid_t gridID, const char *attrname, void *datbuf)
{
  herr_t      status     = FAIL;/* routine return status variable */

  hid_t       fid        = FAIL;/* HDF-EOS file ID                */
  hid_t       ntype      = FAIL;/* Data type ID                   */
  hid_t       gid        = FAIL;/* "HDFEOS" group ID              */

  hsize_t     count[]    =  {0};/* array with elements number     */

  long        idx        = FAIL;/* Grid index                     */

  HE5_LOCK;
  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDreadattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get attribute group ID and call EHattr to perform I/O */
      /* ------------------------------------------------------ */
      status = HE5_EHattr(HE5_GDXGrid[idx].gd_id, attrname, ntype, count, "r", datbuf);
    }


 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqgrid                                                    |
|                                                                             |
|  DESCRIPTION: Returns number and names of grid structures in file           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nGrid          long                Number of grid structures in file       |
|                                                                             |
|  INPUTS:                                                                    |
|  filename       char                HDF-EOS filename                        |
|                                                                             |
|  OUTPUTS:                                                                   |
|  gridlist       char                List of grid names (comma-separated)    |
|  strbufsize     long                Length of gridlist                      |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqgrid(const char *filename, char *gridlist, long *strbufsize)
{
  long           nGrid  = FAIL;/* Number of grid structures in file */

  herr_t         status = FAIL;/* status variable                   */

  CHECKPOINTER(filename);

  /* Call "HE5_EHinquire" routine */
  /* ---------------------------- */
  nGrid = HE5_EHinquire(filename, "/HDFEOS/GRIDS", gridlist, strbufsize);

 COMPLETION:
  return (nGrid);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetfillvalue                                               |
|                                                                             |
|  DESCRIPTION: Sets fill value for the specified field.                      |
|               write attribute "_FillValue" to dataset(field)                |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|  ntype          hid_t   None        data type ID                            |
|  fillval        void                fill value                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Pset_fill_value                                               |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  10/5/99  A.Muslimov    Added dynamical memory allocation for errbuf, and   |
|                         nt arrays. Added error handlings after the function |
|                         calls.                                              |
|                                                                             |
|  12/3/99  A.Muslimov    Fixed a bug resulted in not writing a fill value    |
|                         into the dataset.                                   |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  Mar  04  S.Zhao        Modified for a character string dataset.            |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDsetfillvalue(hid_t gridID, const char *fieldname, hid_t numbertype_in, void *fillval)
{
  herr_t     status     = FAIL;/* routine return status variable */

  hid_t      fid        = FAIL;/* HDF-EOS file ID                */
  hid_t      gid        = FAIL;/* "HDFEOS" group ID              */
  
  long       idx        = FAIL;/* Grid index                     */

  char       *errbuf    = (char *)NULL;/*error message buffer    */
  hid_t       ntype;

  HE5_LOCK;
  CHECKPOINTER(fillval);


  /* Convert HDF-EOS5 datatype to HDF5 datatype */
  if (
      H5Tequal(numbertype_in, H5T_NATIVE_CHAR)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UCHAR)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_SHORT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_USHORT) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_INT)    == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_UINT)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LONG)   == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LLONG)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_ULLONG) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_FLOAT)  == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_DOUBLE) == SUCCEED ||
      H5Tequal(numbertype_in, H5T_NATIVE_LDOUBLE)== SUCCEED ||
      H5Tequal(numbertype_in, H5T_C_S1) == SUCCEED)
    {
      ntype = numbertype_in;
    }
  else
    {
      ntype = HE5_EHconvdatatype((int) numbertype_in);
    }

  if(ntype == FAIL)
    {
      sprintf(errbuf,"Cannot convert to HDF5 type data type ID for fillvalue.\n");
      H5Epush(__FILE__, "HE5_GDsetfillvalue", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetfillvalue", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDsetfillvalue", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDsetfillvalue", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return( status );
    }
	
  /* Get current dataset creation property ID, set dataset fill value */
  /* ---------------------------------------------------------------- */
  if( HE5_GDXGrid[idx].plist == FAIL)
    {
      HE5_GDXGrid[idx].plist = H5Pcreate(H5P_DATASET_CREATE);
      if ( HE5_GDXGrid[idx].plist == FAIL )
	{
	  sprintf(errbuf, "Cannot create the dataset property list.\n");
	  H5Epush(__FILE__, "HE5_GDsetfillvalue", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
		
	  return(FAIL);
	}

    }
	
  /* Set fill value */
  /* -------------- */
  if ((ntype != HE5T_CHARSTRING) && (ntype != H5T_NATIVE_CHAR) && (ntype != H5T_C_S1))
    {
      status = H5Pset_fill_value(HE5_GDXGrid[idx].plist, ntype, fillval);
      if ( status == FAIL )
	{
	  sprintf(errbuf, "Cannot set the fill value for a dataset creation property list.\n");
	  H5Epush(__FILE__, "HE5_GDsetfillvalue", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
		
	  return(status );
	}
    }
	
	
  free(errbuf);    
  errbuf = NULL;
    
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetfillvalue                                               |
|                                                                             |
|  DESCRIPTION: Retrieves fill value for a specified field.                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fillval        void                fill value                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dget_type                                                     |
|             H5Tclose                                                        |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/22/99  A.Muslimov    Changed the type of status variable from intn to    |
|                         int   . Added error handlings. Removed redundant    |
|                         'if else' statements. Initialized return status     |
|                         variable to -1.                                     |
|                                                                             |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
| Aug 22,11 Abe Taaheri   Add code to return error if fillvalue attribute     |
|                         not found.                                          |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDgetfillvalue(hid_t gridID, const char *fieldname, void *fillval)
{
  herr_t          status  = FAIL;/* routine return status variable */

  int             rank    = FAIL;/* Dummy rank variable            */
  int             i;		  	 /* loop index                     */
  int             found   = 0;	 /* found (1), not found (0) flag  */

  hid_t           *nt = (hid_t *)NULL;      /* number types        */
                                           
  hid_t           fid     = FAIL;/* HDF-EOS file ID                */
  hid_t           gid     = FAIL;/* "HDFEOS" group ID              */
  hid_t           fieldid = FAIL;/* dataset ID                     */    
  hid_t           typeID  = FAIL;/* datatype ID                    */

  long            idx     = FAIL;/* Grid index                     */

  hsize_t         dims[HE5_DTSETRANKMAX];/* Dimensions array       */
  hsize_t         count[] = { 1 };/* number of attribute elements  */

  char            *errbuf = (char *)NULL;/* error message buffer   */
  char            *attrnames = NULL;
  long             strbufsize;
  long             nattr = 0;

  HE5_LOCK;

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgetfillvalue", &fid,  &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }


  /* Get field info  */
  /* --------------  */
  nt = (hid_t *)calloc(1, sizeof(hid_t));
  if ( nt == (hid_t *)NULL )
    {
      sprintf(errbuf, "Cannot allocate memory for data type class ID.\n");
      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }

  /* Initialize dims[] array */
  /* ----------------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    dims[ i ] = 0;
  
  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, nt, NULL, NULL); 
  if( status == FAIL)
    {
      sprintf(errbuf, "Failed to get information about \"%s\" data field.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(nt);
	    
      return(FAIL);
    }
    
  /* Loop through all data datasets in grid */
  /* -------------------------------------- */
  for (i = 0; i < HE5_GDXGrid[ idx ].nDFLD; i++)
    {
      /* Get dataset name */
      if( strcmp(fieldname, HE5_GDXGrid[ idx ].ddataset[ i ].name) == 0 )
	{
	  found = 1; 
	  break;
	} 
    }
	
  /* Get dataset ID */
  /* -------------- */
  if( found == 1) 
    {
      fieldid = HE5_GDXGrid[ idx ].ddataset[ i ].ID; 
      typeID = H5Dget_type(fieldid);
      if ( typeID == FAIL )
	{
	  sprintf(errbuf, "Cannot get the dataset data type ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(nt);
			
	  return(FAIL);
	}
	
      /* if fillvalue attribute exist, get the value */

      nattr = HE5_GDinqlocattrs(gridID, fieldname, NULL, &strbufsize);
      if ( nattr < 0 )
	{
	  sprintf(errbuf, "Cannot retrieve fillvalue attribute. \n");
	  H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(nt);

	  return(FAIL);
	}
      
      attrnames = (char*)malloc(sizeof(char)*(strbufsize+1));
      if (attrnames == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for attrnames.\n") ;
	  H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(nt);

	  return(FAIL);
	}
      
      nattr = HE5_GDinqlocattrs(gridID, fieldname, attrnames, &strbufsize);
      if ( nattr < 0 )
	{
	  sprintf(errbuf, "Cannot retrieve fillvalue attribute. \n");
	  H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(nt);
	  if(attrnames != NULL)
	    {
	      free(attrnames);
	      attrnames = NULL;
	    }

	  return(FAIL);
	}
      
      if(strstr(attrnames, "_FillValue")!=NULL)
	{
	  /* Retrieve the fill value */
	  /* ----------------------- */
	  status = HE5_EHattr( fieldid, "_FillValue", typeID, count, "r", fillval);
	  if ( status == FAIL )
	    {
	      sprintf(errbuf, "Cannot retrieve the fill value.\n");
	      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_ATTR, H5E_READERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(nt);
	      if(attrnames != NULL)
		{
		  free(attrnames);
		  attrnames = NULL;
		}

	      return(FAIL);
	    }
	  
	  /* Release the data type ID */
	  /* ------------------------ */
	  status = H5Tclose(typeID);
	  if ( status == FAIL )
	    {
	      sprintf(errbuf, "Cannot release the data type ID.\n");
	      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_DATATYPE, H5E_CLOSEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(nt);	
	      if(attrnames != NULL)
		{
		  free(attrnames);
		  attrnames = NULL;
		}

	      return(FAIL);
	    }
	}
      else
	{
	  status = FAIL;
	  sprintf(errbuf, "Cannot retrieve fillvalue attribute. \n");
	  H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	}
    }
  else
    {
      status = FAIL;
      sprintf(errbuf, "Data field \"%s\" not found. \n", fieldname);
      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  if(attrnames != NULL)
    {
      free(attrnames);
      attrnames = NULL;
    }

  free(errbuf);
  errbuf = NULL;
  if (nt != NULL) free(nt);

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqdatatype                                                |
|                                                                             |
|  DESCRIPTION: Inquires about data fields in grid                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status          herr_t              return status (0) SUCCEED, (-1) FAIL   |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID          hid_t   None        HDF-EOS type grid  ID                  |
|  fieldname       char *                                                     |
|  attrname        char *                                                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dtype           H5T_class_t  None   HDF-EOS data type ID                   |
|  Class           H5T_class_t                                                |
|  Order           H5T_order_t                                                |
|  size            size_t                                                     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dopen                                                         |
|             H5Dget_type                                                     |
|             H5Tget_class                                                    |
|             H5Tget_order                                                    |
|             H5Tget_size                                                     |
|             H5Dclose                                                        |
|             H5Aopen_name                                                    |
|             H5Aget_type                                                     |
|             H5Aclose                                                        |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 99   D.Wynne       Original Programmer                                 |
|  Dec 99   A.Muslimov    Changed the status return data type from hid_t to   |
|                         int   .                                             |
|  Feb 00   A.Muslimov    Added error checkings.                              |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  Mar 00   A.Muslimov    Updated to include Group/Local attributes.          |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDinqdatatype(hid_t gridID, const char *fieldname, const char *attrname, int fieldgroup, hid_t *dtype, H5T_class_t *classID, H5T_order_t *Order, size_t *size)
{
 
  herr_t      status    = FAIL;	/* routine return status          */

  hid_t       datasetid = FAIL;	/* dataset ID                     */
  hid_t       fid       = FAIL;	/* HDF-EOS file ID                */
  hid_t       gid       = FAIL;	/* "HDFEOS" group ID              */
  hid_t       attr      = FAIL;	/* attribute dataset ID           */
  hid_t       fldgroup  = FAIL;	/* group ID                       */
  hid_t       fieldID   = FAIL;	/* Data field dataset ID          */
 
  long        idx       = FAIL;	/* Grid index                     */

  char        *errbuf   = (char *)NULL;/* Error message buffer    */



  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
   
 
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqdatatype", &fid, &gid, &idx);
  if(status == SUCCEED)
    {
      if(fieldgroup == HE5_HDFE_DATAGROUP)
	fldgroup = HE5_GDXGrid[idx].data_id;
      else if(fieldgroup == HE5_HDFE_ATTRGROUP)
	fldgroup = HE5_GDXGrid[idx].gd_id;
      else if(fieldgroup == HE5_HDFE_GRPATTRGROUP)
	fldgroup = HE5_GDXGrid[idx].data_id;
      else if(fieldgroup == HE5_HDFE_LOCATTRGROUP)
	fldgroup = HE5_GDXGrid[idx].data_id;
      else
	{
	  sprintf(errbuf, "Group \"%d\" unknown.\n", fieldgroup);
	  H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
			
	  return(FAIL);
	}

		
      /* Call HDF 5 routines */
      /* =================== */
      if(fieldgroup == HE5_HDFE_DATAGROUP)
	{
	  datasetid = H5Dopen(fldgroup, fieldname);
	  if (datasetid == FAIL)
	    {
	      sprintf(errbuf, "Cannot open the dataset for the \"%s\" field.\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATASET, H5E_NOTFOUND , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *dtype = H5Dget_type(datasetid);
	  if (*dtype == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the datatype for the \"%s\" field.\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATATYPE, H5E_NOTFOUND , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
		   
	  *classID  = H5Tget_class(*dtype);
	  if (*classID == H5T_NO_CLASS)
	    {
	      sprintf(errbuf, "Cannot get the data type class ID for the \"%s\" field.\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *Order    = H5Tget_order(*dtype);
	  if (*Order == H5T_ORDER_ERROR)
	    {
	      sprintf(errbuf, "Cannot get the data type order for the \"%s\" field.\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  if (*classID == H5T_STRING)
	    {
	      *size = H5Tget_size(*dtype);
	    }
	  else
	    {
	      *size     = H5Tget_size(*dtype);
	      if (*size == 0)
		{
		  sprintf(errbuf, "Cannot get the data type size for the \"%s\" field.\n", fieldname);
		  H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
				
		  return(FAIL);
		}
	    }
			
	  status = H5Dclose(datasetid);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Cannot release the dataset ID for the \"%s\" field.\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATASET, H5E_CLOSEERROR , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	}
      else if(fieldgroup == HE5_HDFE_ATTRGROUP || fieldgroup == HE5_HDFE_GRPATTRGROUP)
	{
	  attr      = H5Aopen_name(fldgroup, attrname);
	  if (attr == FAIL)
	    {
	      sprintf(errbuf, "Cannot open the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *dtype = H5Aget_type(attr);
	  if (*dtype == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the data type for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *classID  = H5Tget_class(*dtype);
	  if (*classID == H5T_NO_CLASS)
	    {
	      sprintf(errbuf, "Cannot get the data type class ID for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *Order    = H5Tget_order(*dtype);
	  if (*Order == H5T_ORDER_ERROR)
	    {
	      sprintf(errbuf, "Cannot get the data type order for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  if (*classID == H5T_STRING)
	    {
	      *size = H5Tget_size(*dtype);
	    }
	  else
	    {
	      *size     = H5Tget_size(*dtype);
	      if (*size == 0)
		{
		  sprintf(errbuf, "Cannot get the data type size for the \"%s\" attribute.\n", attrname);
		  H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
				
		  return(FAIL);
		}
	    }
			
	  status = H5Aclose(attr);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Cannot release the dataset ID for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATASET, H5E_CLOSEERROR , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    } 
	}

      else if(fieldgroup == HE5_HDFE_LOCATTRGROUP)
	{
			
	  fieldID = H5Dopen(fldgroup, fieldname);
	  if (fieldID == FAIL)
	    {
	      sprintf(errbuf,"Cannot open the \"%s\" field dataset.\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(FAIL);
	    }
			
	  attr      = H5Aopen_name(fieldID, attrname);
	  if (attr == FAIL)
	    {
	      sprintf(errbuf, "Cannot open the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__,  "HE5_GDinqdatatype", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
			   
	      return(FAIL);
	    }
			
	  *dtype = H5Aget_type(attr);
	  if (*dtype == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the data type for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *classID  = H5Tget_class(*dtype);
	  if (*classID == H5T_NO_CLASS)
	    {
	      sprintf(errbuf, "Cannot get the data type class ID for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  *Order    = H5Tget_order(*dtype);
	  if (*Order == H5T_ORDER_ERROR)
	    {
	      sprintf(errbuf, "Cannot get the data type order for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    }
			
	  if (*classID == H5T_STRING)
	    {
	      *size = H5Tget_size(*dtype);
	    }
	  else
	    {
	      *size     = H5Tget_size(*dtype);
	      if (*size == 0)
		{
		  sprintf(errbuf, "Cannot get the data type size for the \"%s\" attribute.\n", attrname);
		  H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_FUNC, H5E_CANTINIT , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
				
		  return(FAIL);
		}
	    }
			
	  status = H5Aclose(attr);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Cannot release the dataset ID for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATASET, H5E_CLOSEERROR , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
				
	      return(FAIL);
	    } 
			
	  status = H5Dclose(fieldID);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Cannot release the dataset ID for the \"%s\" attribute.\n", attrname);
	      H5Epush(__FILE__, "HE5_GDinqdatatype", __LINE__, H5E_DATASET, H5E_CLOSEERROR , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
				
	      return(FAIL);
	    }		
			
	}

    }
	
  free(errbuf);    
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDnentries                                                   |
|                                                                             |
|  DESCRIPTION: Returns number of entries and descriptive string buffer       |
|                size for a specified entity.                                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nEntries       long                Number of entries                       |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  entrycode      int     None        Entry code                              |
|                                     HDFE_NENTDIM  (0)                       |
|                                     HDFE_NENTDFLD (4)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                Length of comma-separated list          |
|                                     (Does not include null-terminator)      |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid.                                         |
|  9/28/99  A.Muslimov    Added proper error handlings after function calls.  |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDnentries(hid_t gridID, int entrycode, long *strbufsize)
{
  herr_t          status   = FAIL;/* routine return status variable  */

  int             metaflag = FAIL;/* Old (0), New (1) metadata flag) */
  int             nVal     = FAIL;/* Number of strings to search for */

  hid_t           fid      = FAIL;/* HDF-EOS file ID                 */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID               */

  long            i;		  /* Loop index                      */
  long            idx      = FAIL;/* Grid index                      */
  long            nEntries = 0;	  /* Number of entries               */

  char            *metabuf=(char *)NULL;     /* Ptr to structural metadata (SM) */
  char            *metaptrs[2] = {NULL,NULL};/* Ptrs to begin/end of SM section */
  char            *utlstr = (char *)NULL;       /* Utility string               */
  char            valName[2][32];               /* Strings to search for        */
  char            *errbuf = (char *)NULL;       /* buffer for error message     */

     
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char *)calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDnentries", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(FAIL);
    }

  /* Allocate memory for utility string */
  /* ---------------------------------- */
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(FAIL);
    }
    
  /* Zero out string buffer size */
  /* --------------------------- */
  *strbufsize = 0;

  /*
   * Get pointer to  relevant section within SM and Get names of
   * metadata strings to inquire about
   */
  switch (entrycode)
    {
    case HE5_HDFE_NENTDIM:
      {
	metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g", "Dimension", metaptrs);
	if(metabuf == NULL)
	  {
	    sprintf(errbuf, "Cannot allocate memory for metabuffer.\n");
	    H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    free(utlstr);
		    
	    return(FAIL);
	  }
	nVal = 1;
	strcpy(&valName[0][0], "DimensionName");
      }
      break;

    case HE5_HDFE_NENTDFLD:
      {
	metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g", "DataField", metaptrs);
	if(metabuf == NULL)
	  {
	    sprintf(errbuf, "Cannot allocate memory for metabuffer.\n");
	    H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    free(utlstr);

	    return(FAIL);
	  }
	nVal = 1;
	strcpy(&valName[0][0], "DataFieldName");
      }
      break;

    default:
      {
	sprintf(errbuf, "Unknown entry code.\n");
	H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	HE5_EHprint(errbuf, __FILE__, __LINE__);
      }
      break;
	  
    }


  /*
   * Check for presence of 'GROUP="' string If found then old metadata,
   * search on OBJECT string
   */
  metaflag = (strstr(metabuf, "GROUP=\"") == NULL) ? 1 : 0;
  if (metaflag == 0)
    {
      nVal = 1;
      strcpy(&valName[0][0], "\t\tOBJECT");
    }


  /* Begin loop through entries in metadata */
  /* -------------------------------------- */
  while (1)
    {
      /* Search for first string */
      strcpy(utlstr, &valName[0][0]);
      strcat(utlstr, "=");
      metaptrs[0] = strstr(metaptrs[0], utlstr);

      /* If found within relevant metadata section ... */
      if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	{
	  for (i = 0; i < nVal; i++)
	    {
	      /*
	       * Get all string values Don't count quotes
	       */
	      status = HE5_EHgetmetavalue(metaptrs, &valName[i][0], utlstr);
	      if ( status == FAIL )
		{
		  sprintf(errbuf, "Cannot get metadata string.\n");
		  H5Epush(__FILE__, "HE5_GDnentries", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(utlstr);
		  free(metabuf);
			
		  return(FAIL);
		}
	      *strbufsize += strlen(utlstr) - 2;
	    }
	  /* Increment number of entries */
	  nEntries++;

	  /* Go to end of OBJECT */
	  metaptrs[0] = strstr(metaptrs[0], "END_OBJECT");
	}
      else
	/* No more entries found */
	{
	  break;
	}
    }
  if (metabuf != NULL) free(metabuf);

  /* Count comma separators & slashes (if mappings) */
  /* ---------------------------------------------- */
  if (nEntries > 0)
    {
      *strbufsize += nEntries - 1;
      *strbufsize += (nVal - 1) * nEntries;
    }




  free(errbuf);
  free(utlstr);
    
  errbuf = NULL;
  utlstr = NULL;
    

  return (nEntries);
}


#define REMQUOTE					\
							\
  memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);	\
  utlstr[strlen(utlstr) - 2] = 0;


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqdims                                                    |
|                                                                             |
|  DESCRIPTION: Retrieve information about all dimensions defined in a grid.  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nDim           int                 Number of defined dimensions            |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimnames       char                Dimension names (comma-separated)       |
|  dims           hsize_t             Dimension values                        |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid.                                         |
|  9/28/99  A.Muslimov    Added proper error handlings after function calls.  |
|  10/18/99 A.Muslimov    Replace memcpy() by memmove() to avoid a problem    |
|                         when arguments 1 and 2 overlap in memory.           |
| 07/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDinqdims(hid_t gridID, char *dimnames, hsize_t dims[])
{
  int            nDim   =  0;  /* Number of dimensions (return)  */

  herr_t         status = FAIL;/* routine return status variable */
  
  hid_t          fid    = FAIL;/* HDF-EOS file ID                */
  hid_t          gid    = FAIL;/* "HDFEOS" group ID              */
  
  long           idx    = FAIL;/* Grid index                     */
  
  hsize_t        size   =  0;  /* Dimension size                 */
    
  char           *metabuf = (char *)NULL;      /* Ptr to structural metadata (SM) */
  char           *metaptrs[2] = {NULL,NULL};   /* Ptrs to begin/end of SM section */
  char           *utlstr = (char *)NULL;       /* Utility string                  */
  char           *errbuf = (char *)NULL;       /* Buffer for error message        */
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqdims", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  /* If dimension names or sizes are requested */
  /* ----------------------------------------- */
  if (dimnames != NULL || dims != NULL)
    {
      /* Get pointers to "Dimension" section within SM */
      /* --------------------------------------------- */
      metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname, "g","Dimension", metaptrs);
      if(metabuf == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for metabuffer.\n");
	  H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(utlstr);
		  
	  return(FAIL);
	}

      /* If dimension names are requested then "clear" name buffer */
      /* --------------------------------------------------------- */
      if (dimnames != NULL)
	{
	  dimnames[0] = 0;
	}

      while (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	{
	  strcpy(utlstr, "\t\tOBJECT=");
	  metaptrs[0] = strstr(metaptrs[0], utlstr);
	  if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	    {
	      /* Get Dimension Name */
	      /* ------------------ */
	      if (dimnames != NULL)
		{
		  /* Check 1st for old meta data then new */
		  /* ------------------------------------ */
		  status = HE5_EHgetmetavalue(metaptrs, "OBJECT", utlstr);
		  if (status == FAIL)
		    {
		      sprintf(errbuf,  "\"OBJECT\" string not found in metadata.");
		      H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(errbuf);
		      free(utlstr);
		      free(metabuf);
			    
		      return(FAIL);
			    
		    }

		  if (utlstr[0] != '"')
		    {
		      metaptrs[0] = strstr(metaptrs[0], "\t\t\t\tDimensionName=");
		      status = HE5_EHgetmetavalue(metaptrs, "DimensionName", utlstr);
		      if (status == FAIL)
			{
			  sprintf(errbuf,  "\"DimensionName\" string not found in metadata.");
			  H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
			  HE5_EHprint(errbuf, __FILE__, __LINE__);
			  free(errbuf);
			  free(utlstr);
			  free(metabuf);
								
			  return(FAIL);
			}
							
		    }

		  /* Strip off double quotes */
		  /* ----------------------- */
		  memmove(utlstr, utlstr + 1, strlen(utlstr) - 2);
		  utlstr[strlen(utlstr) - 2] = 0;
		  if (nDim > 0)
		    {
		      strcat(dimnames, ",");
		    }
		  strcat(dimnames, utlstr);
		}

	      /* Get Dimension Size */
	      /* ------------------ */
	      if (dims != NULL)
		{
		  status = HE5_EHgetmetavalue(metaptrs, "Size", utlstr);
		  if (status == FAIL)
		    {
		      sprintf(errbuf,  "\"Size\" string not found in metadata.");
		      H5Epush(__FILE__, "HE5_GDinqdims", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(errbuf);
		      free(utlstr);
		      free(metabuf);
							
		      return(FAIL);
		    }
		  size = (hsize_t)atol(utlstr);
		  dims[ nDim ] = size;
		}
	      nDim++;
	    }
	}
      if (metabuf != NULL) free(metabuf);		
    }
  
  free(utlstr);
  free(errbuf);
  
  utlstr = NULL;
  errbuf = NULL;
  
  return (nDim);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDattrinfo                                                   |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               Data type ID                            |
|  count          hsize_t             Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to int   .                                          |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Feb 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDattrinfo(hid_t gridID, const char *attrname, hid_t *ntype, hsize_t *count)
{
  herr_t        status = FAIL;/* routine return status variable */

  hid_t         fid    = FAIL;/* HDF-EOS file ID                */
  hid_t         gid    = FAIL;/* "HDFEOS" group ID              */

  long          idx    = FAIL;/* Grid index                     */

  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDattrinfo", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get attribute group ID and call EHattrinfo */
      /* ------------------------------------------ */
      status = HE5_EHattrinfo( HE5_GDXGrid[idx].gd_id, attrname, ntype, count);
    }

 COMPLETION:
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDattrinfo2                                                  |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               Data type ID                            |
|  count          hsize_t             Number of attribute elements            |
|  size           hsize_t *           buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to int   .                                          |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Feb 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDattrinfo2(hid_t gridID, const char *attrname, hid_t *ntype, hsize_t *count, hsize_t *size)
{
  herr_t        status = FAIL;/* routine return status variable */

  hid_t         fid    = FAIL;/* HDF-EOS file ID                */
  hid_t         gid    = FAIL;/* "HDFEOS" group ID              */

  long          idx    = FAIL;/* Grid index                     */

  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDattrinfo2", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get attribute group ID and call EHattrinfo */
      /* ------------------------------------------ */
      status = HE5_EHattrinfo2( HE5_GDXGrid[idx].gd_id, attrname, ntype, count, size);
    }

 COMPLETION:
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqattrs                                                   |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  attrnames      char                attribute name(s)                       |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    Changed the data type of status variable from intn  |
|                         to int   . Added error handling after the call to   |
|                         GDchkgdid().                                        |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqattrs(hid_t gridID, char *attrnames, long *strbufsize)
{
  herr_t          status   = FAIL;/* routine return status variable  */
  
  hid_t           fid      = FAIL;/* HDF-EOS file ID                 */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID               */
  
  long            nattr    =  0;  /* Number of attributes            */
  long            idx      = FAIL;/* Grid index                      */
  
  char            *grpname = (char *)NULL;/* Buffer for group name   */
  char            *errbuf  = (char *)NULL;/* error message buffer    */
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqattrs", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqattrs", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n" );
      H5Epush(__FILE__, "HE5_GDinqattrs", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(FAIL);
    }

  /* Allocate memory for the group name string */
  /* ----------------------------------------- */
  grpname = (char *) calloc( (strlen(HE5_GDXGrid[idx].gdname)+40), sizeof(char));
  if( grpname == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for the group name string.\n");
      H5Epush(__FILE__, "HE5_GDinqattrs", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(FAIL);
    }
	
  strcpy(grpname,"/HDFEOS/GRIDS/");
  strcat(grpname, HE5_GDXGrid[idx].gdname);
	
  nattr = HE5_EHattrcat(fid,  grpname, attrnames, strbufsize);
	
  if (grpname != NULL) free(grpname);
    

  free(errbuf);
  errbuf = NULL;
    
  return (nattr);
}



/*----------------------------------------------------------------------------r
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqfields                                                  |
|                                                                             |
|  DESCRIPTION: Retrieve information about all data fields defined in a grid. |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nFld           int                 Number of fields in grid                |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fieldlist      char*               Field names (comma-separated)           |
|  rank           int                 Array of ranks                          |
|  ntype          hid_t               Array of field number types             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dopen                                                         |
|             H5Dget_type                                                     |
|             H5Tget_class                                                    |
|             H5Dclose                                                        |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid. Added propere error handling after the  |
|                         function calls.                                     |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  Apr 00   A.Muslimvo    Changed type of 'slen', 'fldnmlen' from long to     |
|                              size_t.                                        |
|  May 00   A.Muslimov    Changed 'H5T_class_t" type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Jan 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|  Oct. 03  S.Zhao        Added the H5Tclose(datatype) call.                  |
|  Jan. 04  S.Zhao        Modified to enable a character string dataset.      |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDinqfields(hid_t gridID, char *fieldlist, int rank[], hid_t ntype[])
{
  int           nFld       =  0;  /* Number of fields (return)      */
  int           i;                /* loop index                     */ 

  herr_t        status     = FAIL;/* routine return status variable */
  herr_t        Dstatus    = FAIL;/* Status for H5Dclose            */

  long          ntflds     = 0;   /* Number of entries in field list*/
  long          idx        = FAIL;/* Grid index                     */

  hid_t         fid        = FAIL;/* HDF-EOS file ID                */
  hid_t         gid        = FAIL;/* "HDFEOS" group ID              */
  hid_t         datasetid  = FAIL;/* Dataset ID                     */
  hid_t         datatype   = FAIL;/* Datatype ID                    */
 
  size_t        slen[HE5_DTSETRANKMAX]; /* String length array      */
  size_t        fldnmlen[HE5_HDFE_NAMBUFSIZE];
 
  char          *tempfield = (char *)NULL;
  char          *fldnm[HE5_HDFE_NAMBUFSIZE];     
  char          *metabuf = (char *)NULL;/* Pointer to structural metadata (SM)     */
  char          *metaptrs[2];           /* Pointers to begin and end of SM section */
  char          *utlstr = (char *)NULL; /* Utility string                          */
  char          *ptr[HE5_DTSETRANKMAX]; /* String pointer array                    */
  char          *errbuf = (char *)NULL; /* error message buffer                    */
  H5T_class_t   classid = H5T_NO_CLASS; /* Data type class ID                      */
  htri_t        str_is_variable;        /* boolean: TRUE if string is variable 
					   lengeth FALSE if string is fixed length
					   -1 if error in H5Tis_variavle_str()     */
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

/*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqfields", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  utlstr  = (char *)calloc( HE5_HDFE_UTLBUFSIZE, sizeof(char) );
  if(utlstr == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for utility string.\n");
      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_FILE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
	

  /* If field names, ranks,  or number types desired ... */
  /* --------------------------------------------------- */
  if (fieldlist != NULL || rank != NULL || ntype != NULL)
    {
      /* Get pointers to "DataField" section within SM */
      /* --------------------------------------------- */
      metabuf = (char *)HE5_EHmetagroup(fid, HE5_GDXGrid[idx].gdname,"g","DataField", metaptrs);
      if(metabuf == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for metabuffer.\n");
	  H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(utlstr);
		
	  return(FAIL);
	}

      /* If field names are desired then "clear" name buffer */
      /* --------------------------------------------------- */
      if (fieldlist != NULL)
	fieldlist[0] = 0;
		
      /* Begin loop through mapping entries in metadata */
      /* ---------------------------------------------- */
      while (1)
	{
	  /* Search for OBJECT string */
	  /* ------------------------ */
	  metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");

			
	  /* If found within "Data" Field metadata section .. */
	  /* ------------------------------------------------ */
	  if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
	    {
	      /* Get Fieldnames (if desired) */
	      /* --------------------------- */
	      if (fieldlist != NULL)
		{
		  /* Check 1st for old meta data then new */
		  /* ------------------------------------ */
		  status = HE5_EHgetmetavalue(metaptrs, "OBJECT", utlstr);
		  if (status == FAIL)
		    {
		      sprintf(errbuf,  "\"OBJECT\" string not found in metadata.");
		      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(errbuf);
		      free(utlstr);
		      free(metabuf);
						
		      return(FAIL);
		    }
					
		  /*
		   * If OBJECT value begins with double quote then old
		   * metadata, field name is OBJECT value. Otherwise
		   * search for "DataFieldName" string
		   */
					
		  if (utlstr[0] != '"')
		    {
		      strcpy(utlstr, "\t\t\t\t");
		      strcat(utlstr, "DataFieldName");
		      strcat(utlstr, "=");
		      metaptrs[0] = strstr(metaptrs[0], utlstr);
		      status = HE5_EHgetmetavalue(metaptrs, "DataFieldName", utlstr);
		      if (status == FAIL)
			{
			  sprintf(errbuf,  "\"DataFieldName\" string not found in metadata.");
			  H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
			  HE5_EHprint(errbuf, __FILE__, __LINE__);
			  free(errbuf);
			  free(utlstr);
			  free(metabuf);

			  return(FAIL);
			}
						
		    }

		  /* Strip off double quotes */
		  /* ----------------------- */
		  REMQUOTE
					  
					  
		    /* Add to fieldlist */
		    /* ---------------- */
		    if (nFld > 0)
		      {
			strcat(fieldlist, ",");
		      }
		  strcat(fieldlist, utlstr);
					
		}
				
	      if (ntype != NULL)
		{
		  ntflds = HE5_EHparsestr(fieldlist, ',', fldnm, fldnmlen);
		  if(ntflds != FAIL)
		    {
		      for( i = 0; i < ntflds; i++)
			{
			  tempfield = (char *)calloc(fldnmlen[i] + 1, sizeof(char));
			  if (tempfield == NULL)
			    {
			      sprintf(errbuf,  "Cannot allocate memory.");
			      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
			      HE5_EHprint(errbuf, __FILE__, __LINE__);
			      if (errbuf  != NULL) free(errbuf);
			      if (utlstr  != NULL) free(utlstr);
			      if (metabuf != NULL) free(metabuf);
							  
			      return(FAIL);
			    }
			  memmove(tempfield,fldnm[i],fldnmlen[i]);
			  datasetid     = H5Dopen(HE5_GDXGrid[idx].data_id, tempfield);
			  if (datasetid == FAIL)
			    {
			      sprintf(errbuf,  "Cannot open the dataset.");
			      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
			      HE5_EHprint(errbuf, __FILE__, __LINE__);
			      if (errbuf  != NULL) free(errbuf);
			      if (utlstr  != NULL) free(utlstr);
			      if (metabuf != NULL) free(metabuf);
			      free(tempfield);

			      return(FAIL);
			    }

			  datatype      = H5Dget_type(datasetid);
			  if (datatype == FAIL)
			    {
			      sprintf(errbuf,  "Cannot get the data type.");
			      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
			      HE5_EHprint(errbuf, __FILE__, __LINE__);
			      if (errbuf  != NULL) free(errbuf);
			      if (utlstr  != NULL) free(utlstr);
			      if (metabuf != NULL) free(metabuf);
			      free(tempfield);

			      return(FAIL);
			    }

			  classid      = H5Tget_class(datatype);
			  if (classid == H5T_NO_CLASS)
			    {
			      sprintf(errbuf,  "Cannot get the data type class.");
			      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
			      HE5_EHprint(errbuf, __FILE__, __LINE__);
			      if (errbuf  != NULL) free(errbuf);
			      if (utlstr  != NULL) free(utlstr);
			      if (metabuf != NULL) free(metabuf);
			      free(tempfield);

			      return(FAIL);
			    }
 
			  if (classid == H5T_STRING)
			    {
			      /* HE5T_CHARSTRING has variable length for data fields */
			      str_is_variable = H5Tis_variable_str(datatype);
			      if(str_is_variable == TRUE)
				{
				  ntype[i] = HE5T_CHARSTRING;
				}
			      else if(str_is_variable == FALSE)
				{
				  ntype[i] = HE5T_NATIVE_CHAR;
				}
			      else
				{
				  status = FAIL;
				  sprintf(errbuf, "Failed to see if string field is varaible or fixed length.\n");
				  H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
				  HE5_EHprint(errbuf, __FILE__, __LINE__);
				  if (errbuf  != NULL) free(errbuf);
				  if (utlstr  != NULL) free(utlstr);
				  if (metabuf != NULL) free(metabuf);
				  free(tempfield);
				  return(status);
				}
			      /*ntype[i] = HE5T_CHARSTRING;*/
			    }
			  else
			    {
			      ntype[i] = HE5_EHdtype2numtype(datatype);
			      if (ntype[i] == FAIL)
				{
				  sprintf(errbuf,  "Cannot get the number type.\n");
				  H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
				  HE5_EHprint(errbuf, __FILE__, __LINE__);
				  if (errbuf  != NULL) free(errbuf);
				  if (utlstr  != NULL) free(utlstr);
				  if (metabuf != NULL) free(metabuf);
				  free(tempfield);
							  
				  return(FAIL);
				}
			    }

			  status = H5Tclose(datatype);
			  if ( status == FAIL )
			    {
			      sprintf(errbuf,  "Cannot close the datatype.");
			      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
			      HE5_EHprint(errbuf, __FILE__, __LINE__);
			      if (errbuf  != NULL) free(errbuf);
			      if (utlstr  != NULL) free(utlstr);
			      if (metabuf != NULL) free(metabuf);
			      free(tempfield);
 
			      return(FAIL);
			    }

			  Dstatus       = H5Dclose(datasetid);
			  if (Dstatus == FAIL)
			    {
			      sprintf(errbuf,  "Cannot close the dataset.");
			      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
			      HE5_EHprint(errbuf, __FILE__, __LINE__);
			      if (errbuf  != NULL) free(errbuf);
			      if (utlstr  != NULL) free(utlstr);
			      if (metabuf != NULL) free(metabuf);
			      free(tempfield);

			      return(FAIL);
			    }

			  free(tempfield);
			}
		    }
		}
			  
	      /*
	       * Get Rank (if desired) by counting # of dimensions in
	       * "DimList" string
	       */
	      if (rank != NULL)
		{
		  status = HE5_EHgetmetavalue(metaptrs, "DimList", utlstr);
		  if (status == FAIL)
		    {
		      sprintf(errbuf,  "\"DimList\" string not found in metadata.");
		      H5Epush(__FILE__, "HE5_GDinqfields", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      if (errbuf  != NULL) free(errbuf);
		      if (utlstr  != NULL) free(utlstr);
		      if (metabuf != NULL) free(metabuf);

		      return(FAIL);
		    }
					
		  rank[ nFld ] = (int)HE5_EHparsestr(utlstr, ',', ptr, slen);
		}
	      /* Increment number of fields */
	      nFld++;
	    }
	  else
	    /* No more fields found */
	    {
	      break;
	    }
	}
      if (metabuf != NULL) free(metabuf);
    }
	

  free(utlstr);
  free(errbuf);
    
	
  return (nFld);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdetach                                                     |
|                                                                             |
|  DESCRIPTION: Detaches from grid interface and performs file housekeeping.  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dclose                                                        |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  9/9/99   A.Muslimov    Checked for the statuses returned by H5Dclose() and |
|                         H5Gclose(). Cleaned up minor things.                |
|  Feb,2000 A.Muslimov    Fixed bug-prone release of IDs.                     |
|  Mar,2000 A.Muslimov    Added detaching from the "Data Fields" group.       |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDdetach(hid_t gridID)
{

  herr_t          status = FAIL;/* routine return status variable */    

  int             i, k;		    /* loop indices                   */
     
  long            idx    = FAIL;/* Grid index                     */
    
  hid_t           fid    = FAIL;/* HDF-EOS file ID                */
  hid_t           gid    = FAIL;/* "HDFEOS" group ID              */

  char            *errbuf = (char *)NULL;/*Error message buffer   */


  HE5_LOCK;

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdetach", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdetach", &fid, &gid, &idx);
  if( status == FAIL)
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdetach", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
     
      return(status);
    }


  /* "Detach" from previously attached datasets */
  /* ------------------------------------------ */
  if( HE5_GDXGrid[ idx ].nDFLD > 0 )
    {
      for (k = 0; k < HE5_GDXGrid[ idx ].nDFLD; k++)
	{
	  if ( HE5_GDXGrid[ idx ].ddataset[ k ].ID > 0 )
	    {
	      status = H5Dclose(HE5_GDXGrid[ idx ].ddataset[ k ].ID);
	      if( status == FAIL)
		{
		  sprintf(errbuf, "Cannot close the dataset.");
		  H5Epush(__FILE__, "HE5_GDdetach", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		   
		  return(status);
		}
	    }
	  if (HE5_GDXGrid[ idx ].ddataset[ k ].name != NULL) 
	    free(HE5_GDXGrid[ idx ].ddataset[ k ].name);
	}
      if ( HE5_GDXGrid[ idx ].ddataset != NULL )
	free(HE5_GDXGrid[ idx ].ddataset); 
    }

  /* Detach from "Data Fields" groups */
  /* -------------------------------- */

  if (  HE5_GDXGrid[ idx ].data_id > 0 )
    {
      status = H5Gclose(HE5_GDXGrid[ idx ].data_id);
      if( status == FAIL)
	{
	  sprintf(errbuf,"Cannot close the group.");
	  H5Epush(__FILE__, "HE5_GDdetach", __LINE__, H5E_OHDR, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  
	  return(status);
	}
    }


  /* Detach from Grid groups */
  /* ----------------------- */
  if (  HE5_GDXGrid[ idx ].gd_id > 0 )
    {
      status = H5Gclose(HE5_GDXGrid[ idx ].gd_id);
      if( status == FAIL)
	{
	  sprintf(errbuf,"Cannot close the group.");
	  H5Epush(__FILE__, "HE5_GDdetach", __LINE__, H5E_OHDR, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  
	  return(status);
	}
    }
	    

  /* Delete entries from External Arrays */
  /* ----------------------------------- */
  HE5_GDXGrid[  idx  ].active     =       0;
  HE5_GDXGrid[  idx  ].fid        =       0;
  HE5_GDXGrid[  idx  ].gd_id      =       0;
  HE5_GDXGrid[  idx  ].data_id    =       0;
  HE5_GDXGrid[  idx  ].obj_id     =       0;
  HE5_GDXGrid[  idx  ].ddataset   =    NULL;
  HE5_GDXGrid[  idx  ].nDFLD      =       0;


  /* Free Region Pointers */
  /* -------------------- */
  for (k = 0; k < HE5_NGRIDREGN; k++)
    {
      if (HE5_GDXRegion[ k ] != NULL && HE5_GDXRegion[ k ]->gridID == gridID)
	{
	  for (i = 0; i < HE5_DTSETRANKMAX; i++)
	    {
	      if (HE5_GDXRegion[ k ]->DimNamePtr[ i ] != NULL)
		{
		  if( HE5_GDXRegion[ k ]->DimNamePtr[ i ] != NULL )
		    {
		      free(HE5_GDXRegion[ k ]->DimNamePtr[ i ]);
		      HE5_GDXRegion[ k ]->DimNamePtr[ i ] = NULL;
		    }
		}
	    }

	  if ( HE5_GDXRegion[ k ] != NULL )
	    {
	      free(HE5_GDXRegion[ k ]);
	      HE5_GDXRegion[ k ] = NULL;
	    }
	}
    }
	
	
  free(errbuf);
  errbuf = (char *)NULL;

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDclose                                                      |
|                                                                             |
|  DESCRIPTION: Closes file.                                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  fid            hid_t               HDF-EOS type file ID                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDclose(hid_t fid)
{
  herr_t            status = FAIL;/* routine return status variable */

  /* Call HE5_EHclose to perform file close */
  /* -------------------------------------- */
  status = HE5_EHclose(fid);

  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetdefaults                                                |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  projparm       double              Projection parameters                   |
|  spherecode     int                 GCTP spheriod code                      |
|  upleftpt       double              upper left corner coordinates           |
|  lowrightpt     double              lower right corner coordinates          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  upleftpt       double              upper left corner coordinates           |
|  lowrightpt     double              lower right corner coordinates          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  9/28/99  A.Muslimov    Added proper error handlings after the function     |
|                         calls.                                              |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDgetdefaults(int projcode, int zonecode, double projparm[], int spherecode, double upleftpt[], double lowrightpt[])
{

  herr_t          status    = SUCCEED;/* routine return status variable */
   
#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*for_trans[100]) (double, double, double*, double*);
  int             errorcode = 0;
#else
  long            (*for_trans[100]) (double, double, double*, double*);
  long            errorcode = 0;
#endif

  double          lon   = 0.;
  double          lat   = 0.;
  double          plat  = 0.;
  double          x     = 0.;
  double          y     = 0.;
  double          plon  = 0.; 
  double          tlon  = 0.;
  double          llon  = 0.; 
  double          rlon  = 0.;
  double          pplon = 0.;
  double	  RLon = 0.;
  double 	  RLat = 0.;
  double 	  LLon = 0.;
  double 	  LLat = 0.;

  char            *errbuf;		/* buffer for error message       */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /* invoke GCTP initialization routine */
  /* ---------------------------------- */
  for_init(projcode, zonecode, projparm, spherecode, NULL, NULL,&errorcode, for_trans);

  /* Report error if any */
  /* ------------------- */
  if (errorcode != 0)
    {
      status = FAIL;
      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return (status);
    }

  /* Compute Default Boundary Points for EASE Grid          */
  /* Use Global coverage */
  /* ------------------------------------------------------ */
  if (projcode == HE5_GCTP_BCEA &&
      upleftpt[0] == 0 && upleftpt[1] == 0 &&
      lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      upleftpt[0] = HE5_EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LON, HE5_HDFE_DEG_DMS);
      upleftpt[1] = HE5_EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LAT, HE5_HDFE_DEG_DMS);
      lowrightpt[0] = HE5_EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LON, HE5_HDFE_DEG_DMS);
      lowrightpt[1] = HE5_EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LAT, HE5_HDFE_DEG_DMS);
    }

  /* Compute Default Boundary Points for CEA     */
  /* --------------------------------------------*/
  if (projcode ==HE5_GCTP_CEA &&
      upleftpt[0] == 0 && upleftpt[1] == 0 &&
      lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      LLon = HE5_EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LON, HE5_HDFE_DEG_RAD);
      LLat = HE5_EHconvAng(EASE_GRID_DEFAULT_UPLEFT_LAT, HE5_HDFE_DEG_RAD);
      RLon = HE5_EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LON, HE5_HDFE_DEG_RAD);
      RLat = HE5_EHconvAng(EASE_GRID_DEFAULT_LOWRGT_LAT, HE5_HDFE_DEG_RAD);

      errorcode = for_trans[projcode] (LLon, LLat, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return (status);
	}
      upleftpt[0] = x;
      upleftpt[1] = y;
 
      errorcode = for_trans[projcode] (RLon, RLat, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return (status);
        }
      lowrightpt[0] = x;
      lowrightpt[1] = y;

    }


  /* Compute Default Boundary Points for Polar Sterographic */
  /* ------------------------------------------------------ */
  if (projcode == HE5_GCTP_PS && upleftpt[0] == 0 && upleftpt[1] == 0 && lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      /*
       * Convert the longitude and latitude from the DMS to decimal degree
       * format.
       */
      plon = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
      plat = HE5_EHconvAng(projparm[5], HE5_HDFE_DMS_DEG);

      /*
       * Compute the longitudes at 90, 180 and 270 degrees from the central
       * longitude.
       */

      if (plon <= 0.0)
        {
	  tlon  = 180.0 + plon;
	  pplon = plon + 360.0;
        }
      else
        {
	  tlon  = plon - 180.0;
	  pplon = plon;
        }

      rlon = pplon + 90.0;
      if (rlon > 360.0)
	rlon = rlon - 360.;

      if (rlon > 180.0)
	rlon = rlon - 360.0;

      if (rlon <= 0.0)
	llon = 180.0 + rlon;
      else
	llon = rlon - 180.0;


      /* Convert all four longitudes from decimal degrees to radians */
      plon = HE5_EHconvAng(plon, HE5_HDFE_DEG_RAD);
      tlon = HE5_EHconvAng(tlon, HE5_HDFE_DEG_RAD);
      llon = HE5_EHconvAng(llon, HE5_HDFE_DEG_RAD);
      rlon = HE5_EHconvAng(rlon, HE5_HDFE_DEG_RAD);

      errorcode = for_trans[projcode] (llon, 0., &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      upleftpt[0] = x;

      errorcode = for_trans[projcode](rlon, 0.0, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      lowrightpt[0] = x;

      /*
       * Compute the upperleft and lowright y values based on the south or
       * north polar projection
       */

      if (plat < 0.0)
        {
	  errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  upleftpt[1] = y;

	  errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }
	  lowrightpt[1] = y;
        }
      else
        {
	  errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  upleftpt[1] = y;

	  errorcode = for_trans[projcode](plon, 0., &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  lowrightpt[1] = y;
        }
    }

  /* Compute Default Boundary Points for Goode Homolosine */
  /* ---------------------------------------------------- */
  if (projcode == HE5_GCTP_GOOD && upleftpt[0] == 0 && upleftpt[1] == 0 && lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      lon = HE5_EHconvAng(-180, HE5_HDFE_DEG_RAD);
      lat = 0.0;

      errorcode = for_trans[projcode] (lon, lat, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      upleftpt[0]   = -fabs(x);
      lowrightpt[0] = +fabs(x);

      lat = HE5_EHconvAng(90, HE5_HDFE_DEG_RAD);

      errorcode = for_trans[projcode] (lon, lat, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      upleftpt[1]   = +fabs(y);
      lowrightpt[1] = -fabs(y);
    }

  /* Compute Default Boundary Points for Lambert Azimuthal */
  /* ----------------------------------------------------- */
  if (projcode == HE5_GCTP_LAMAZ && upleftpt[0] == 0 && upleftpt[1] == 0 && lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      /*
       * Convert the longitude and latitude from the DMS to decimal degree
       * format.
       */
      plon = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
      plat = HE5_EHconvAng(projparm[5], HE5_HDFE_DMS_DEG);

      /*
       * Compute the longitudes at 90, 180 and 270 degrees from the central
       * longitude.
       */

      if (plon <= 0.0)
        {
	  tlon  = 180.0 + plon;
	  pplon = plon + 360.0;
        }
      else
        {
	  tlon  = plon - 180.0;
	  pplon = plon;
        }

      rlon = pplon + 90.0;
      if (rlon > 360.0)
	rlon = rlon - 360.;

      if (rlon > 180.0)
	rlon = rlon - 360.0;

      if (rlon <= 0.0)
	llon = 180.0 + rlon;
      else
	llon = rlon - 180.0;

      /* Convert all four longitudes from decimal degrees to radians */
      plon = HE5_EHconvAng(plon, HE5_HDFE_DEG_RAD);
      tlon = HE5_EHconvAng(tlon, HE5_HDFE_DEG_RAD);
      llon = HE5_EHconvAng(llon, HE5_HDFE_DEG_RAD);
      rlon = HE5_EHconvAng(rlon, HE5_HDFE_DEG_RAD);

      errorcode = for_trans[projcode] (llon, 0.0, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      upleftpt[0] = x;

      errorcode = for_trans[projcode] (rlon, 0.0, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      lowrightpt[0] = x;

      /*
       * Compute upperleft and lowerright values based on whether the
       * projection is south polar, north polar or equitorial
       */

      if (plat == -90.0)
        {
	  errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  upleftpt[1] = y;

	  errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  lowrightpt[1] = y;
        }
      else if (plat == 90.0)
        {
	  errorcode = for_trans[projcode] (tlon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  upleftpt[1] = y;

	  errorcode = for_trans[projcode] (plon, 0.0, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__,  "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  lowrightpt[1] = y;
        }
      else
        {
	  lat = HE5_EHconvAng(90, HE5_HDFE_DEG_RAD);
	  errorcode = for_trans[projcode] (plon, lat, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }
	  upleftpt[1] = y;

	  lat = HE5_EHconvAng(-90, HE5_HDFE_DEG_RAD);
	  errorcode = for_trans[projcode] (plon, lat, &x, &y);
	  if (errorcode != 0)
            {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		
	      return (status);
            }

	  lowrightpt[1] = y;
        }
    }

  /* Compute Default Boundary Points for Integerized Sinusoidal Grid */
  /* --------------------------------------------------------------- */
  if (projcode == HE5_GCTP_ISINUS && upleftpt[0] == 0 && upleftpt[1] == 0 && lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      /*
       * Convert the longitude and latitude from the DMS to decimal degree
       * format.
       */
      plon = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
      plat = HE5_EHconvAng(projparm[5], HE5_HDFE_DMS_DEG);
      /*
       * Compute the longitudes at 90, 180 and 270 degrees from the central
       * longitude.
       */

      if (plon <= 0.0)
        {
	  tlon = 180.0 + plon;
	  pplon = plon + 360.0;
        }
      else
        {
	  tlon = plon - 180.0;
	  pplon = plon;
        }

      rlon = pplon + 90.0;
      if (rlon > 360.0)
	rlon = rlon - 360.;

      if (rlon > 180.0)
	rlon = rlon - 360.0;

      if (rlon <= 0.0)
	llon = 180.0 + rlon;
      else
	llon = rlon - 180.0;

      /* Convert all four longitudes from decimal degrees to radians */
      plon = HE5_EHconvAng(plon, HE5_HDFE_DEG_RAD);
      tlon = HE5_EHconvAng(tlon, HE5_HDFE_DEG_RAD);
      llon = HE5_EHconvAng(llon, HE5_HDFE_DEG_RAD);
      rlon = HE5_EHconvAng(rlon, HE5_HDFE_DEG_RAD);

      errorcode = for_trans[projcode] (llon, 0.0, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      upleftpt[0] = x;

      errorcode = for_trans[projcode] (rlon, 0.0, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      lowrightpt[0] = x;

      lat = HE5_EHconvAng(90, HE5_HDFE_DEG_RAD);
      errorcode = for_trans[projcode] (plon, lat, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      upleftpt[1] = y;

      lat = HE5_EHconvAng(-90, HE5_HDFE_DEG_RAD);
      errorcode = for_trans[projcode] (plon, lat, &x, &y);
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li \n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDgetdefaults", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return (status);
        }

      lowrightpt[1] = y;
    }

  free(errbuf);
  errbuf = NULL;
    
  return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDll2ij                                                      |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  projparm       double              Projection parameters                   |
|  spherecode     int                 GCTP spheriod code                      |
|  xdimsize       long                xdimsize from GDcreate                  |
|  ydimsize       long                ydimsize from GDcreate                  |
|  upleftpt       double              upper left corner coordinates           |
|  lowrightpt     double              lower right corner coordinates          |
|  npnts          long                number of lon-lat points                |
|  longitude      double              longitude array (decimal degrees)       |
|  latitude       double              latitude array (decimal degrees)        |
|                                                                             |
|  OUTPUTS:                                                                   |
|  row            long                Row array                               |
|  col            long                Column array                            |
|  xval           double              X value array                           |
|  yval           double              Y value array                           |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|                         Added proper error handlings.                       |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  2/02/08  Abe Taaheri   Created Fortran Wrapper, and made it an API         |
|  Jun 11   Abe Taaher    Modified for State Plane Files inclusion            |
|                                                                             |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDll2ij(int projcode, int zonecode, double projparm[],
	    int spherecode, long xdimsize, long ydimsize,
	    double upleftpt[], double lowrightpt[],
	    long  npnts, double longitude[], double latitude[],
	    long row[], long col[], double xval[], double yval[])
{
  
  herr_t          status = SUCCEED;         /* routine return status variable       */
  
  long            i;                     /* Loop index                           */

#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*for_trans[100]) (double, double, double *, double *);
  int              errorcode = 0;         /* GCTP error code   */  
#else
  long            (*for_trans[100]) (double, double, double *, double *);
  long             errorcode = 0;         /* GCTP error code   */  
#endif

  double          xVal    = 0.;          /* Scaled x distance                    */
  double          yVal    = 0.;          /* Scaled y distance                    */
  double          xMtr    = 0.;          /* X value in meters from GCTP          */
  double          yMtr    = 0.;          /* Y value in meters from GCTP          */
  double          lonrad0 = 0.;          /* Longitude in radians of upleft point */
  double          latrad0 = 0.;          /* Latitude in radians of upleft point  */
  double          lonrad  = 0.;          /* Longitude in radians of point        */
  double          latrad  = 0.;          /* Latitude in radians of point         */
  double          scaleX  = 0.;          /* X scale factor                       */
  double          scaleY  = 0.;          /* Y scale factor                       */
  double          HE5_EHconvAng(double, int);/* Angle conversion routine         */
  double	  xMtr0, xMtr1, yMtr0, yMtr1;
  
  char            *errbuf;               /* Buffer for error message             */
  char            *eastFile = NULL;
  char            *northFile = NULL;

  CHECKPOINTER(upleftpt);
  CHECKPOINTER(lowrightpt);
  CHECKPOINTER(longitude);
  CHECKPOINTER(latitude);
 

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDll2ij", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  
  /* If projection not GEO call GCTP initialization routine */
  /* ------------------------------------------------------ */
  if (projcode != HE5_GCTP_GEO)
    {

      eastFile = (char *) malloc(300*sizeof(char));
      northFile = (char *) malloc(300*sizeof(char));

      HE5_GDgetEastAndNorthFiles(eastFile,northFile); 

      for_init(projcode, zonecode, projparm, spherecode, eastFile, northFile,  
	       &errorcode, for_trans);
	  
      free (eastFile);
      free (northFile);
      eastFile = NULL;
      northFile = NULL;

      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDll2ij", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);

	  return (status);
	}
    }
  
  if (status == SUCCEED)
    {
      /* GEO projection */
      /* -------------- */
      if (projcode == HE5_GCTP_GEO)
	{
	  /* Convert upleft and lowright X coords from DMS to radians */
	  /* -------------------------------------------------------- */
	  lonrad0 = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_RAD);
	  lonrad  = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_RAD);
		  
	  /* Compute x scale factor */
	  /* ---------------------- */
	  scaleX = (lonrad - lonrad0) / xdimsize;
		  
		  
	  /* Convert upleft and lowright Y coords from DMS to radians */
	  /* -------------------------------------------------------- */
	  latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_RAD);
	  latrad  = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_RAD);

		  
	  /* Compute y scale factor */
	  /* ---------------------- */
	  scaleY = (latrad - latrad0) / ydimsize;
	}
      /* BCEA projection */
      /* -------------- */
      else if ( projcode == HE5_GCTP_BCEA)
	{
	  /* Convert upleft and lowright X coords from DMS to radians */
	  /* ----------------------------------------------------------*/
    
	  lonrad0 = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_RAD);
	  lonrad = HE5_EHconvAng(lowrightpt[0],HE5_HDFE_DMS_RAD);
  
	  /* Convert upleft and lowright Y coords from DMS to radians */
	  /* ----------------------------------------------------------*/
	  latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_RAD);
	  latrad = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_RAD);
  
	  /* Convert from lon/lat to meters(or whatever unit is, i.e unit
	     of r_major and r_minor) using GCTP */
	  /* ----------------------------------------- */
	  errorcode = for_trans[projcode] (lonrad0, latrad0, &xMtr0, &yMtr0);

	  /* Report error if any */
	  /* ------------------- */
	  if (errorcode != 0)
	    {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDll2ij", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return (status);
	    }
  
	  /* Convert from lon/lat to meters(or whatever unit is, i.e unit
	     of r_major and r_minor) using GCTP */
	  /* ----------------------------------------- */
	  errorcode = for_trans[projcode] (lonrad, latrad, &xMtr1, &yMtr1);
              
	  /* Report error if any */
	  /* ------------------- */
	  if (errorcode != 0)
	    { status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDll2ij", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      return (status);  
	    }
  
	  /* Compute x scale factor */
	  /* ---------------------- */
	  scaleX = (xMtr1 - xMtr0) / xdimsize;
 
	  /* Compute y scale factor */
	  /* ---------------------- */
	  scaleY = (yMtr1 - yMtr0) / ydimsize;
	}

      else
        {
	  /* Non-GEO, Non-BCEA  projections */
	  /* ------------------ */
		  
	  /* Compute x & y scale factors */
	  /* --------------------------- */
	  scaleX = (lowrightpt[0] - upleftpt[0]) / xdimsize;
	  scaleY = (lowrightpt[1] - upleftpt[1]) / ydimsize;
        }
	  
	  
	  
      /* Loop through all points */
      /* ----------------------- */
      for (i = 0; i < npnts; i++)
        {
	  /* Convert lon & lat from decimal degrees to radians */
	  /* ------------------------------------------------- */
	  lonrad = HE5_EHconvAng(longitude[i], HE5_HDFE_DEG_RAD);
	  latrad = HE5_EHconvAng(latitude[i], HE5_HDFE_DEG_RAD);

	  /* GEO projection */
	  /* -------------- */
	  if (projcode == HE5_GCTP_GEO)
	    {
	      /* Compute scaled distance to point from origin */
	      /* -------------------------------------------- */
	      xVal = (lonrad - lonrad0) / scaleX;
	      yVal = (latrad - latrad0) / scaleY;
	    }
	  else
	    {
	      /* Convert from lon/lat to meters using GCTP */
	      /* ----------------------------------------- */
	      errorcode = for_trans[projcode](lonrad, latrad, &xMtr, &yMtr);
			  

	      /* Report error if any */
	      /* ------------------- */
	      if (errorcode != 0)
		{
		  status = FAIL;
		  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
		  H5Epush(__FILE__, "HE5_GDll2ij", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		}
	      else {
		/* if projection is BCEA normalize x and y by cell size and
		   measure it from the uperleft corner of the grid */
  
		/* Compute scaled distance to point from origin */
		/* -------------------------------------------- */
		if(  projcode == HE5_GCTP_BCEA)
		  {
		    xVal = (xMtr - xMtr0) / scaleX;
		    yVal = (yMtr - yMtr0) / scaleY;
		  }
		else
		  {
		    xVal = (xMtr - upleftpt[0]) / scaleX;
		    yVal = (yMtr - upleftpt[1]) / scaleY;
		  }
	      }
	    }		  
                        			  
		  

	  /* Compute row and col from scaled distance */
	  /* ---------------------------------------- */
	  col[i] = (long)xVal;
	  row[i] = (long)yVal;
		  
		  
	  /* Store scaled distances if requested */
	  /* ----------------------------------- */
	  if (xval != NULL)
	    {
	      xval[i] = xVal;
	    }
		  
	  if (yval != NULL)
	    {
	      yval[i] = yVal;
	    }
	}
    }
  
  if (errbuf != NULL) free(errbuf);
  
 COMPLETION:
  return(status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDij2ll                                                      |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  projparm       double              Projection parameters                   |
|  spherecode     int                 GCTP spheriod code                      |
|  xdimsize       long                xdimsize from GDcreate                  |
|  ydimsize       long                ydimsize from GDcreate                  |
|  upleftpt       double              upper left corner coordinates           |
|  lowrightpt     double              lower right corner coordinates          |
|  pixcen         int                 pixel center code                       |
|  npnts          long                number of lon-lat points                |
|  row            long                Row array                               |
|  col            long                Column array                            |
|  pixcen         int                 Code from GDpixreginfo                  |
|  pixcnr         int                 Code from GDorigininfo                  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  longitude      double              longitude array (decimal degrees)       |
|  latitude       double              latitude array  (decimal degrees)       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|                         Added proper error handling after the function calls|
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  2/02/08  Abe Taaheri   Created Fortran Wrapper, and made it an API         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDij2ll(int projcode, int zonecode, double projparm[],
	    int spherecode, long xdimsize, long ydimsize,
	    double upleftpt[], double lowrightpt[],
	    long npnts, long row[], long col[],
	    double longitude[], double latitude[], int pixcen, int pixcnr)
{

  herr_t          status    = FAIL;/* routine return status variable      */

  long            i;			  /* Loop index                           */

#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*inv_trans[100]) (double, double, double*, double*);	
  int             errorcode = 0;  /* GCTP error code                      */
#else
  long            (*inv_trans[100]) (double, double, double*, double*);	
  long            errorcode = 0;  /* GCTP error code                      */
#endif
 
#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*for_trans[100]) (double, double, double*, double*);
#else
  long            (*for_trans[100]) (double, double, double*, double*);
#endif

  double          arg1, arg2;
  double          pixadjX  = 0.;  /* Pixel adjustment (x)                 */
  double          pixadjY  = 0.;  /* Pixel adjustment (y)                 */
  double          lonrad0  = 0.;  /* Longitude in radians of upleft point */
  double          latrad0  = 0.;  /* Latitude in radians of upleft point  */
  double          scaleX   = 0.;  /* X scale factor                       */
  double          scaleY   = 0.;  /* Y scale factor                       */
  double          lonrad   = 0.;  /* Longitude in radians of point        */
  double          latrad   = 0.;  /* Latitude in radians of point         */
  double          HE5_EHconvAng(double, int);/* Angle conversion routine  */
  double	  xMtr0, yMtr0, xMtr1, yMtr1;

  char            *errbuf;		  /* buffer for error message     */
  char            *eastFile = NULL;
  char            *northFile = NULL;

  CHECKPOINTER(upleftpt);
  CHECKPOINTER(lowrightpt);
  CHECKPOINTER(row);
  CHECKPOINTER(col);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  

  /* Compute adjustment of position within pixel */
  /* ------------------------------------------- */
  if (pixcen == HE5_HDFE_CENTER)
    {
      /* Pixel defined at center */
      /* ----------------------- */
      pixadjX = 0.5;
      pixadjY = 0.5;
    }
  else
    {
      switch (pixcnr)
        {
		  
        case HE5_HDFE_GD_UL:
	  {
	    /* Pixel defined at upper left corner */
	    /* ---------------------------------- */
	    pixadjX = 0.0;
	    pixadjY = 0.0;
	    break;
	  }

        case HE5_HDFE_GD_UR:
	  {
	    /* Pixel defined at upper right corner */
	    /* ----------------------------------- */
	    pixadjX = 1.0;
	    pixadjY = 0.0;
	    break;
	  }

        case HE5_HDFE_GD_LL:
	  {
	    /* Pixel defined at lower left corner */
	    /* ---------------------------------- */
	    pixadjX = 0.0;
	    pixadjY = 1.0;
	    break;
	  }

        case HE5_HDFE_GD_LR:
	  {
	    /* Pixel defined at lower right corner */
	    /* ----------------------------------- */
	    pixadjX = 1.0;
	    pixadjY = 1.0;
	    break;
	  }

	default:
	  {
	    sprintf(errbuf, "Unknown pixel corner.\n");
	    H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    return(FAIL);
	  }
        }
    }



  /* If projection not GEO or BCEA call GCTP initialization routine */
  /* ------------------------------------------------------ */
  if (projcode != HE5_GCTP_GEO && projcode != HE5_GCTP_BCEA)
    {
      eastFile = (char *) malloc(300*sizeof(char));
      northFile = (char *) malloc(300*sizeof(char));

      HE5_GDgetEastAndNorthFiles(eastFile,northFile); 

      scaleX = (lowrightpt[0] - upleftpt[0]) / xdimsize;
      scaleY = (lowrightpt[1] - upleftpt[1]) / ydimsize;

      inv_init(projcode, zonecode, projparm, spherecode, eastFile, northFile, 
	       &errorcode, inv_trans);

      free (eastFile);
      free (northFile);
      eastFile = NULL;
      northFile = NULL;


      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(status);
        }
      else
        {
	  /* For each point ... */
	  /* ------------------ */
	  for (i = 0; i < npnts; i++)
            {
	      /* Convert from meters to lon/lat (radians) using GCTP */
	      /* --------------------------------------------------- */
	      /*errorcode = inv_trans[projcode] ((col[i] + pixadjX) * scaleX + upleftpt[0], (row[i] + pixadjY) * scaleY + upleftpt[1], &lonrad, &latrad);*/

	      /* modified previous line to the following for the linux64 with -fPIC in cmpilation. 
		 Whithout the change col[] and row[] values are ridiclous numbers, resulting a strange 
		 number (very big) for arg1 and arg2. But with (int) typecast they become normal integers,
		 resulting in a acceptable values for arg1 and arg2. The problem was discovered during the
		 lat/lon geolocating of an hdfeos5 file with 64-bit hadview plug-in, developped for linux64.
	      */
	      arg1 = (((int)col[i] + pixadjX) * scaleX + upleftpt[0]);
	      arg2 = (((int)row[i] + pixadjY) * scaleY + upleftpt[1]);
	      errorcode = inv_trans[projcode] (arg1, arg2, &lonrad, &latrad);

	      /* Report error if any */
	      /* ------------------- */
	      if (errorcode != 0)
		{
		  status = FAIL;
		  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
		  H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  return(status);
		}
	      else
		{
		  /* Convert from radians to decimal degrees */
		  /* --------------------------------------- */
		  longitude[i] = HE5_EHconvAng(lonrad, HE5_HDFE_RAD_DEG);
		  latitude[i]  = HE5_EHconvAng(latrad, HE5_HDFE_RAD_DEG);
		}
	    }
	}
    }
  else if (projcode == HE5_GCTP_BCEA)
    {
      /* BCEA projection */
      /* -------------- */
 
      /* Note: upleftpt and lowrightpt are in packed degrees, so they
	 must be converted to meters for this projection */

      /* Initialize forward transformation */
      /* --------------------------------- */
      for_init(projcode, zonecode, projparm, spherecode, NULL, NULL,&errorcode, for_trans);

      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return (-1);
	}

      /* Convert upleft and lowright X coords from DMS to radians */
      /* -------------------------------------------------------- */
      lonrad0 =HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_RAD);
      lonrad = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_RAD);

      /* Convert upleft and lowright Y coords from DMS to radians */
      /* -------------------------------------------------------- */
      latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_RAD);
      latrad = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_RAD);

      /* Convert form lon/lat to meters(or whatever unit is, i.e unit
	 of r_major and r_minor) using GCTP */
      /* ----------------------------------------- */
      errorcode = for_trans[projcode] (lonrad0, latrad0, &xMtr0, &yMtr0);

      /* Report error if any */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return (status);
	}

      /* Convert from lon/lat to meters or whatever unit is, i.e unit
	 of r_major and r_minor) using GCTP */
      /* ----------------------------------------- */
      errorcode = for_trans[projcode] (lonrad, latrad, &xMtr1, &yMtr1);

      /* Report error if any */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return (status);
	}

      /* Compute x scale factor */
      /* ---------------------- */
      scaleX = (xMtr1 - xMtr0) / xdimsize;

      /* Compute y scale factor */
      /* ---------------------- */
      scaleY = (yMtr1 - yMtr0) / ydimsize;

      /* Initialize inverse transformation */
      /* --------------------------------- */
      inv_init(projcode, zonecode, projparm, spherecode, NULL, NULL, &errorcode, inv_trans);
      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return (-1);
	}
      /* For each point ... */
      /* ------------------ */
      for (i = 0; i < npnts; i++)
	{
	  /* Convert from meters (or any units that r_major and
	     r_minor has) to lon/lat (radians) using GCTP */
	  /* --------------------------------------------------- */
	  errorcode = inv_trans[projcode] (
					   (col[i] + pixadjX) * scaleX + xMtr0,
					   (row[i] + pixadjY) * scaleY + yMtr0,
					   &lonrad, &latrad);

	  /* Report error if any */
	  /* ------------------- */
	  if (errorcode != 0)
	    {
              /* status = -1;
		 sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
		 H5Epush(__FILE__, "HE5_GDij2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
		 HE5_EHprint(errbuf, __FILE__, __LINE__);
                 return (status); */
	      longitude[i] = 1.0e51; /* PGSd_GCT_IN_ERROR */
	      latitude[i] = 1.0e51; /* PGSd_GCT_IN_ERROR */
	    }

	  /* Convert from radians to decimal degrees */
	  /* --------------------------------------- */
	  longitude[i] = HE5_EHconvAng(lonrad, HE5_HDFE_RAD_DEG);
	  latitude[i] = HE5_EHconvAng(latrad, HE5_HDFE_RAD_DEG);
	}
    }

  else if (projcode == HE5_GCTP_GEO)
    {
      /* GEO projection */
      /* -------------- */

      /*
       * Note: lonrad, lonrad0, latrad, latrad0 are actually in degrees for
       * the GEO projection case.
       */


      /* Convert upleft and lowright X coords from DMS to degrees */
      /* -------------------------------------------------------- */
      lonrad0 = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_DEG);
      lonrad  = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_DEG);

      /* Compute x scale factor */
      /* ---------------------- */
      scaleX = (lonrad - lonrad0) / xdimsize;

      /* Convert upleft and lowright Y coords from DMS to degrees */
      /* -------------------------------------------------------- */
      latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_DEG);
      latrad  = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_DEG);

      /* Compute y scale factor */
      /* ---------------------- */
      scaleY = (latrad - latrad0) / ydimsize;

      /* For each point ... */
      /* ------------------ */
      for (i = 0; i < npnts; i++)
        {
	  /* Convert to lon/lat (decimal degrees) */
	  /* ------------------------------------ */
	  longitude[i] = (col[i] + pixadjX) * scaleX + lonrad0;
	  latitude[i]  = (row[i] + pixadjY) * scaleY + latrad0;
        }
    }

  if (errbuf != NULL) free(errbuf);
  
 COMPLETION:
  return (status);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: GDrs2ll                                                          |
|                                                                             |
|  DESCRIPTION:  Converts EASE grid's (r,s) coordinates to longitude and      |
|                latitude (in decimal degrees).                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         intn                return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 GCTP projection code                    |
|  projparm       double              Projection parameters                   |
|  xdimsize       long                xdimsize from GDcreate                  |
|  ydimsize       long                ydimsize from GDcreate                  |
|  pixcen         int                 pixel center code                       |
|  npnts          long                number of lon-lat points                |
|  s              long                s coordinate                            |
|  r              long                r coordinate                            |
|  pixcen         int                 Code from GDpixreginfo                  |
|  pixcnr         int                 Code from GDorigininfo                  |
|  upleft         double              upper left corner coordinates (DMS)     |
|  lowright       double              lower right corner coordinates (DMS)    |
|                                                                             |
|  OUTPUTS:                                                                   |
|  longitude      double              longitude array (decimal degrees)       |
|  latitude       double              latitude array  (decimal degrees)       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer    Description                                        |
|  ======   ============   =================================================  |
|  Dec 04   Adura Adekunjo Added function to  hdfeos5                         |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDrs2ll(int projcode, double projparm[],
	    long xdimsize, long ydimsize,
	    double upleft[], double lowright[],
	    int npnts, double r[], double s[],
	    double longitude[], double latitude[], int pixcen, int pixcnr)
{
  herr_t          status    = SUCCEED;/* routine return status variable      */
  long            i;          /* Loop index */

#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*inv_trans[100]) (double, double, double*, double*);
  int           errorcode = 0;      /* GCTP error code */
#else
  long            (*inv_trans[100]) (double, double, double*, double*);
  long           errorcode = 0;      /* GCTP error code */
#endif

  double          pixadjX;    /* Pixel adjustment (x) */
  double          pixadjY;    /* Pixel adjustment (y) */
  double          lonrad;     /* Longitude in radians of point */
  double          latrad;     /* Latitude in radians of point */
  double          HE5_EHconvAng(double, int);/* Angle conversion routine */
  double          xMtr;       /* X value in meters from GCTP */
  double          yMtr;       /* Y value in meters from GCTP */
  double          epsilon;
  double          beta;
  double          qp_cea;
  double          kz_cea;
  double          eccen, eccen_sq;
  double          phi1, sinphi1, cosphi1;
  double          scaleX, scaleY;

  int             zonecode=0;

  int             spherecode=0;
  double          lon[2],lat[2];
  double          xcor[2], ycor[2];
  int             nlatlon;

  char            *errbuf;                /* buffer for error message             */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /* If projection is BCEA define scale, r0 and s0 */
  if (projcode == HE5_GCTP_BCEA)
    {
      eccen_sq = 1.0 - SQUARE(projparm[1]/projparm[0]);
      eccen = sqrt(eccen_sq);
      if(eccen < 0.00001)
	{
	  qp_cea = 2.0;
	}
      else
	{
	  qp_cea =
	    (1.0 - eccen_sq)*((1.0/(1.0 - eccen_sq))-(1.0/(2.0*eccen))*
			      log((1.0 - eccen)/(1.0 + eccen)));
	}
      phi1 = HE5_EHconvAng(projparm[5],HE5_HDFE_DMS_RAD);
      cosphi1 = cos(phi1);
      sinphi1 = sin(phi1);
      kz_cea = cosphi1/(sqrt(1.0 - (eccen_sq*sinphi1*sinphi1)));
    }
    else /* fail for all other projections */
      {
	    sprintf(errbuf, "Error: HE5_GDrs2ll can be called only for HE5_GCTP_BCEA projection.");
	    H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    return(FAIL);
      }


  /* Compute adjustment of position within pixel */
  /* ------------------------------------------- */
  if (pixcen == HE5_HDFE_CENTER)
    {
      /* Pixel defined at center */
      /* ----------------------- */
      pixadjX = 0.5;
      pixadjY = 0.5;
    }
  else
    {
      switch (pixcnr)
        {
        case HE5_HDFE_GD_UL:
	  {
	    /* Pixel defined at upper left corner */
	    /* ---------------------------------- */
	    pixadjX = 0.0;
	    pixadjY = 0.0;
	    break;
	  }

        case HE5_HDFE_GD_UR:
	  {
	    /* Pixel defined at upper right corner */
	    /* ----------------------------------- */
	    pixadjX = 1.0;
	    pixadjY = 0.0;
	    break;
	  }

        case HE5_HDFE_GD_LL:
	  {
	    /* Pixel defined at lower left corner */
	    /* ---------------------------------- */
	    pixadjX = 0.0;
	    pixadjY = 1.0;
	    break;
	  }
	case HE5_HDFE_GD_LR:
	  {
	    /* Pixel defined at lower right corner */
	    /* ----------------------------------- */
	    pixadjX = 1.0;
	    pixadjY = 1.0;
	    break;
	  }
	default:
	  {
	    sprintf(errbuf, "Unknown pixel corner.\n");
	    H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	    HE5_EHprint(errbuf, __FILE__, __LINE__);
	    free(errbuf);
	    return(FAIL);
	  }
	}
    }

  /* If projection is BCEA call GCTP initialization routine */
  /* ------------------------------------------------------ */
  if (projcode == HE5_GCTP_BCEA)
    {
       
      inv_init(projcode, 0, projparm, 0, NULL, NULL, &errorcode, inv_trans);

      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
        {
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(status); 
        }
      else
        {
	  /* For each point ... */
	  /* ------------------ */
          for (i = 0; i < npnts; i++)
            {
              /* Convert from EASE grid's (r,s) to lon/lat (radians)
                 using GCTP */
              /* --------------------------------------------------- */
              nlatlon = 2;
              lon[0] = upleft[0];
              lon[1] = lowright[0];
              lat[0] = upleft[1];
              lat[1] = lowright[1];
              status = HE5_GDll2mm_cea(projcode,zonecode,spherecode,projparm, xdimsize, ydimsize,
				       upleft, lowright, nlatlon, lon, lat, xcor, ycor, &scaleX, &scaleY);
              if (status == FAIL)
		{
		  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
		  H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  return(status);
		}
            
	      xMtr = (r[i]/ scaleX + pixadjX - 0.5)* scaleX;
	      yMtr = - (s[i]/fabs(scaleY) + pixadjY - 0.5)* fabs(scaleY);


              /* allow .5 cell tolerance in arcsin function
                 (used in bceainv function) so that grid
                 coordinates which are less than .5 cells
                 above 90.00N or below 90.00S are given lat of 90.00
              */

              epsilon = 1 + 0.5 * (fabs(scaleY)/projparm[0]);
              beta = 2.0 * (yMtr - projparm[7]) * kz_cea/(projparm[0] * qp_cea);

	      if( fabs (beta) > epsilon)
                {
                  status = FAIL;
                  sprintf(errbuf, "GCTP Error:  %s %s %s\n", "grid coordinates",
                          "are more than .5 cells", "above 90.00N or below 90.00S. ");  
                  H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  return(status);
                }
	      else if( beta <= -1)
                {
                  errorcode = inv_trans[projcode] (xMtr, 0.0,
                                                   &lonrad, &latrad);
                  latrad = - M_PI1/2;
                }
              else if( beta >= 1)
                {
                  errorcode = inv_trans[projcode] (xMtr, 0.0,
                                                   &lonrad, &latrad);
                  latrad = M_PI1/2;
                }
              else
                {
                  errorcode = inv_trans[projcode] (xMtr, yMtr,
                                                   &lonrad, &latrad);
                }
          
	      /* Report error if any */
	      /* ------------------- */
	      if (errorcode != 0)
		{
		  status = FAIL;
		  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
		  H5Epush(__FILE__, "HE5_GDrs2ll", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  return (status);
		}
           
	      /* Convert from radians to decimal degrees */
	      /* --------------------------------------- */
	      longitude[i] = HE5_EHconvAng(lonrad, HE5_HDFE_RAD_DEG);
	      latitude[i] =  HE5_EHconvAng(latrad, HE5_HDFE_RAD_DEG);
	    }
        }
    }
  if (errbuf != NULL) free(errbuf);
 
 COMPLETION:
  return (status);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_lamazDxDtheta                                                |
|                                                                             |
|  DESCRIPTION: Partial derivative along longitude line for Lambert Azimuthal |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|                 double              Dx/D(theta) for LAMAZ projection        |
|                                                                             |
|  INPUTS:                                                                    |
|  parms          double              Parameters defining partial derivative  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
double 
HE5_lamazDxDtheta(double  parms[])
{
  double  ans      = 0.;
  double  snTheta  = 0.;
  double  sn2Theta = 0.;
  double  snTheta1 = 0.;
  double  csTheta1 = 0.;
  double  csLamda  = 0.;
  
  herr_t  status   = FAIL;

  CHECKPOINTER(parms);

  snTheta  = sin(HE5_EHconvAng(parms[0], HE5_HDFE_DEG_RAD));
  sn2Theta = sin(2. * HE5_EHconvAng(parms[0], HE5_HDFE_DEG_RAD));
  snTheta1 = sin(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  csTheta1 = cos(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  csLamda  = cos(HE5_EHconvAng(parms[2], HE5_HDFE_DEG_RAD) - HE5_EHconvAng(parms[3], HE5_HDFE_DEG_RAD));

  ans = 4. * snTheta + (csTheta1 * csLamda * sn2Theta) + (2. * snTheta1 * (1. + (snTheta * snTheta)));
  
 COMPLETION:
  return(ans); 
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_lamazDxDlamda                                                |
|                                                                             |
|  DESCRIPTION: Partial derivative along latitude line for Lambert Azimuthal  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|                 double              Dx/D(lamda) for LAMAZ projection        |
|                                                                             |
|  INPUTS:                                                                    |
|  parms          double              Parameters defining partial derivative  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
double 
HE5_lamazDxDlamda(double parms[])
{
  double   ans      = 0.;
  double   snTheta  = 0.;
  double   csTheta  = 0.;
  double   snTheta1 = 0.;
  double   csTheta1 = 0.;
  double   csLamda  = 0.;
  double   cs       = 0.; 
  double   sn       = 0.;

  herr_t   status   = FAIL;

  CHECKPOINTER(parms);

  snTheta  = sin(HE5_EHconvAng(parms[2], HE5_HDFE_DEG_RAD));
  csTheta  = cos(HE5_EHconvAng(parms[2], HE5_HDFE_DEG_RAD));
  snTheta1 = sin(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  csTheta1 = cos(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  csLamda  = cos(HE5_EHconvAng(parms[0], HE5_HDFE_DEG_RAD) - HE5_EHconvAng(parms[3], HE5_HDFE_DEG_RAD));
  
  cs = csTheta * csTheta1;
  sn = snTheta * snTheta1;

  ans = cs + (2. * (1. + sn) + (cs * csLamda)) * csLamda;

 COMPLETION:
  return(ans);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_lamazDyDtheta                                                |
|                                                                             |
|  DESCRIPTION: Partial derivative along longitude line for Lambert Azimuthal |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|                 double              Dy/D(theta) for LAMAZ projection        |
|                                                                             |
|  INPUTS:                                                                    |
|  parms          double              Parameters defining partial derivative  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
double 
HE5_lamazDyDtheta(double parms[])
{
  double  ans      = 0.;
  double  snTheta  = 0.;
  double  csTheta  = 0.;
  double  snTheta1 = 0.;
  double  csTheta1 = 0.;
  double  csLamda  = 0.;
  double  sn2      = 0.;
  double  cs2      = 0.;
  double  sndiff   = 0.;

  herr_t  status   = FAIL; 
 
  CHECKPOINTER(parms);

  snTheta  = sin(HE5_EHconvAng(parms[0], HE5_HDFE_DEG_RAD));
  csTheta  = cos(HE5_EHconvAng(parms[0], HE5_HDFE_DEG_RAD));
  snTheta1 = sin(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  csTheta1 = cos(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  csLamda  = cos(HE5_EHconvAng(parms[2], HE5_HDFE_DEG_RAD) - HE5_EHconvAng(parms[3], HE5_HDFE_DEG_RAD));
  
  sn2    = snTheta1 * snTheta;
  cs2    = csTheta1 * csTheta;
  sndiff = snTheta1 - snTheta;

  ans = cs2 * (sn2 * (1. + (csLamda * csLamda)) + 2.) + csLamda * (2. * (1. + sn2 * sn2) - (sndiff * sndiff));

 COMPLETION:
  return(ans);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_homDyDtheta                                                  |
|                                                                             |
|  DESCRIPTION: Partial derivative along longitude line for Oblique Mercator  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|                 double              Dx/D(theta) for HOM projection          |
|                                                                             |
|  INPUTS:                                                                    |
|  parms          double              Parameters defining partial derivative  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
double 
HE5_homDyDtheta(double parms[])
{
  double  ans      = 0.;
  double  tnTheta  = 0.;
  double  tnTheta1 = 0.;
  double  snLamda  = 0.;

  herr_t  status   = FAIL;

  CHECKPOINTER(parms);

  tnTheta  = tan(HE5_EHconvAng(parms[0], HE5_HDFE_DEG_RAD));
  tnTheta1 = tan(HE5_EHconvAng(parms[1], HE5_HDFE_DEG_RAD));
  snLamda  = cos(HE5_EHconvAng(parms[2], HE5_HDFE_DEG_RAD) - HE5_EHconvAng(parms[3], HE5_HDFE_DEG_RAD));

  ans = tnTheta * snLamda + tnTheta1;

 COMPLETION:
  return(ans);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDtangentpnts                                                |
|                                                                             |
|  DESCRIPTION: Finds tangent points along lon/lat lines                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 Projection code                         |
|  projparm       double              Projection parameters                   |
|  cornerlon      double   dec deg    Longitude of opposite corners of box    |
|  cornerlat      double   dec deg    Latitude of opposite corners of box     |
|  longitude      double   dec deg    Longitude of points to check            |
|  latitude       double   dec deg    Latitude of points to check             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  npnts          long                Number of points to check in subset     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  3/16/00  A.Muslimov    Added Abe Taaheri's update (MERCATOR and ALBERS     |
|                         projections) from HDF-EOSv2.                        |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  May  04  S.Zhao        Added a case for GEO projections.                   |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static herr_t   
HE5_GDtangentpnts(int projcode, double projparm[], double cornerlon[], double cornerlat[], double longitude[], double latitude[], long *npnts)
{

  herr_t          status       = FAIL;/* return status variable      */  
  
  int             i;                  /* Loop index                  */
  
  double          lonrad         = 0.;/* Longitude (radians)         */
  double          latrad         = 0.;/* Latitude (radians)          */
  double          cs[4]={0.,0.,0.,0.};/* Cosine array                */
  double          sn[4]={0.,0.,0.,0.};/* Sine array                  */
  double          csTest         = 0.;/* Cosine test value           */
  double          snTest         = 0.;/* Sine test value             */
  double          crs01          = 0.;/* Cross product               */
  double          crsTest[2]= {0.,0.};/* Cross product array         */
  double          longPol        = 0.;/* Longitude beneath pole      */
  double          minLat         = 0.;/* Minimum latitude            */
  double          bisectParm[4]={0.,0.,0.,0.};/* Bisection parms     */
  double          tanLat         = 0.;/* Tangent latitude            */
  double          tanLon         = 0.;/* Tangent lontitude           */
  double          dotPrd         = 0.;/* Dot product                 */
  double          centMerd       = 0.;/* Central Meridian            */
  double          orgLat         = 0.;/* Latitude of origin          */
  double          dpi            = 0.;/* Double precision pi         */
  double          HE5_lamazDxDtheta(double *);/* Lambert Azimuthal Dx/Dtheta */
  double          HE5_lamazDxDlamda(double *);/* Lambert Azimuthal Dx/Dlamda */
  double          HE5_lamazDyDtheta(double *);/* Lambert Azimuthal Dy/Dtheta */
  double          HE5_homDyDtheta(double *);  /* Oblique Mercator  Dy/Dtheta */
  
  char            *errbuf;            /* Buffer for error message    */
 
  CHECKPOINTER(projparm);
  CHECKPOINTER(cornerlon);
  CHECKPOINTER(cornerlat);
  CHECKPOINTER(longitude);
  CHECKPOINTER(latitude);
 
  /* Allocate memory for error message buffer */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDtangentpnts", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /* Conpute pi (double precsion) */
  /* ---------------------------- */
  dpi = atan(1.) * 4.;
  
  switch (projcode)
    {

    case HE5_GCTP_GEO:
      {
	/* No need for tangent points, since GEO projection is rectangular */
      }
      break;

    case HE5_GCTP_MERCAT:
      {
	/* No need for tangent points, since MERCAT projection is rectangular */
      }
      break;
    case HE5_GCTP_BCEA:
      {
	/* No need for tangent points, since BCEA projection
	   is rectangular */
      }
      break;
    case HE5_GCTP_CEA:
      {
	/* No need for tangent points, since CEA projection
	   is rectangular */
      }
      break;
    case HE5_GCTP_PS:
      {
	/* Add "xy axis" points for Polar Stereographic if necessary */
	/* --------------------------------------------------------- */


	/* Get minimum of corner latitudes */
	/* ------------------------------- */
	minLat = (fabs(cornerlat[0]) <= fabs(cornerlat[1])) ? cornerlat[0] : cornerlat[1];


	/* Compute sine and cosine of corner longitudes */
	/* -------------------------------------------- */
	for (i = 0; i < 2; i++)
	  {
	    lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
	    cs[i]  = cos(lonrad);
	    sn[i]  = sin(lonrad);
	  }


	/* Compute cross product */
	/* --------------------- */
	crs01 = cs[0] * sn[1] - cs[1] * sn[0];


	/* Convert longitude beneath pole from DMS to DEG */
	/* ---------------------------------------------- */
	longPol = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_RAD);



	for (i = 0; i < 4; i++)
	  {
	    csTest = cos(longPol);
	    snTest = sin(longPol);

	    crsTest[0] = cs[0] * snTest - csTest * sn[0];
	    crsTest[1] = cs[1] * snTest - csTest * sn[1];

	    if ((crs01 > 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
		(crs01 < 0 && crsTest[0] < 0 && crsTest[1] < 0) ||
		(crs01 < 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
		(crs01 < 0 && crsTest[0] > 0 && crsTest[1] > 0))
	      {
		longitude[*npnts] = HE5_EHconvAng(longPol, HE5_HDFE_RAD_DEG);
		latitude[*npnts] = minLat;
		(*npnts)++;
	      }
	    longPol += 0.5 * dpi;
	  }
      }
      break;


    case HE5_GCTP_LAMAZ:
      {
	if ((long)projparm[5] == +90000000 || (long)projparm[5] == -90000000)
	  {
	    /* Add "xy axis" points for Polar Lambert Azimuthal */
	    /* ------------------------------------------------ */
	    minLat = (fabs(cornerlat[0]) <= fabs(cornerlat[1]))
	      ? cornerlat[0] : cornerlat[1];

	    for (i = 0; i < 2; i++)
	      {
		lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
		cs[i]  = cos(lonrad);
		sn[i]  = sin(lonrad);
	      }
	    crs01 = cs[0] * sn[1] - cs[1] * sn[0];

	    longPol = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_RAD);
	    for (i = 0; i < 4; i++)
	      {
		csTest = cos(longPol);
		snTest = sin(longPol);

		crsTest[0] = cs[0] * snTest - csTest * sn[0];
		crsTest[1] = cs[1] * snTest - csTest * sn[1];

		if ((crs01 > 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
		    (crs01 < 0 && crsTest[0] < 0 && crsTest[1] < 0) ||
		    (crs01 < 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
		    (crs01 < 0 && crsTest[0] > 0 && crsTest[1] > 0))
		  {
		    longitude[*npnts] = HE5_EHconvAng(longPol, HE5_HDFE_RAD_DEG);
		    latitude[*npnts] = minLat;
		    (*npnts)++;
		  }
		longPol += 0.5 * dpi;
	      }
	  }
	else if ((long)projparm[5] == 0)
	  {
	    /* Add "Equator" points for Equatorial Lambert Azimuthal */
	    /* ----------------------------------------------------- */
	    if (cornerlat[0] * cornerlat[1] < 0)
	      {
		longitude[4] = cornerlon[0];
		latitude[4] = 0;

		longitude[5] = cornerlon[1];
		latitude[5] = 0;

		*npnts = 6;
	      }
	  }
	else
	  {
	    /* Add tangent points for Oblique Lambert Azimuthal */
	    /* ------------------------------------------------ */
	    bisectParm[0] = HE5_EHconvAng(projparm[5], HE5_HDFE_DMS_DEG);
	    bisectParm[2] = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);

	    /* Tangent to y-axis along longitude */
	    /* --------------------------------- */
	    for (i = 0; i < 2; i++)
	      {
		bisectParm[1] = cornerlon[i];

		if (HE5_EHbisect(HE5_lamazDxDtheta, bisectParm, 3, cornerlat[0], cornerlat[1], 0.0001, &tanLat) == 0)
		  {
		    longitude[*npnts] = cornerlon[i];
		    latitude[*npnts] = tanLat;
		    (*npnts)++;
		  }
	      }

	    /* Tangent to y-axis along latitude */
	    /* -------------------------------- */
	    for (i = 0; i < 2; i++)
	      {
		bisectParm[1] = cornerlat[i];

		if (HE5_EHbisect(HE5_lamazDxDlamda, bisectParm, 3, cornerlon[0], cornerlon[1], 0.0001, &tanLon) == 0)
		  {
		    longitude[*npnts] = tanLon;
		    latitude[*npnts] = cornerlat[i];
		    (*npnts)++;
		  }
	      }


	    /* Tangent to x-axis along longitude */
	    /* --------------------------------- */
	    for (i = 0; i < 2; i++)
	      {
		bisectParm[1] = cornerlon[i];

		if (HE5_EHbisect(HE5_lamazDyDtheta, bisectParm, 3, cornerlat[0], cornerlat[1],  0.0001, &tanLat) == 0)
		  {
		    longitude[*npnts] = cornerlon[i];
		    latitude[*npnts] = tanLat;
		    (*npnts)++;
		  }
	      }

	    /* Tangent to x-axis along latitude */
	    /* -------------------------------- */
	    for (i = 0; i < 2; i++)
	      {
		lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
		cs[i]  = cos(lonrad);
		sn[i]  = sin(lonrad);
	      }
	    crs01 = cs[0] * sn[1] - cs[1] * sn[0];

	    longPol = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_RAD);
	    for (i = 0; i < 2; i++)
	      {
		csTest = cos(longPol);
		snTest = sin(longPol);

		crsTest[0] = cs[0] * snTest - csTest * sn[0];
		crsTest[1] = cs[1] * snTest - csTest * sn[1];

		if ((crs01 > 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
		    (crs01 < 0 && crsTest[0] < 0 && crsTest[1] < 0) ||
		    (crs01 < 0 && crsTest[0] > 0 && crsTest[1] < 0) ||
		    (crs01 < 0 && crsTest[0] > 0 && crsTest[1] > 0))
		  {
		    longitude[*npnts] = HE5_EHconvAng(longPol, HE5_HDFE_RAD_DEG);
		    latitude[*npnts]  = cornerlat[0];
		    (*npnts)++;
		    longitude[*npnts] = HE5_EHconvAng(longPol, HE5_HDFE_RAD_DEG);
		    latitude[*npnts]  = cornerlat[1];
		    (*npnts)++;
		  }
		longPol += dpi;
	      }
	  }
      }
      break;


    case HE5_GCTP_GOOD:
      {
	/* Add "Equator" points for Goode Homolosine if necessary */
	/* ------------------------------------------------------ */
	if (cornerlat[0] * cornerlat[1] < 0)
	  {
	    longitude[4] = cornerlon[0];
	    latitude[4] = 0;

	    longitude[5] = cornerlon[1];
	    latitude[5] = 0;

	    *npnts = 6;
	  }
      }
      break;



    case HE5_GCTP_LAMCC:
      {
	/* Compute sine and cosine of corner longitudes */
	/* -------------------------------------------- */
	for (i = 0; i < 2; i++)
	  {
	    lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
	    cs[i] = cos(lonrad);
	    sn[i] = sin(lonrad);
	  }


	/* Compute dot product */
	/* ------------------- */
	dotPrd = cs[0] * cs[1] + sn[0] * sn[1];


	/* Convert central meridian (DMS to DEG) & compute sin & cos */
	/* --------------------------------------------------------- */
	centMerd = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
	lonrad   = HE5_EHconvAng(centMerd, HE5_HDFE_DEG_RAD);
	cs[1]    = cos(lonrad);
	sn[1]    = sin(lonrad);


	/* If box brackets central meridian ... */
	/* ------------------------------------ */
	if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
	  {
	    latitude[4]  = cornerlat[0];
	    longitude[4] = centMerd;

	    latitude[5]  = cornerlat[1];
	    longitude[5] = centMerd;

	    *npnts = 6;
	  }
      }
      break;


    case HE5_GCTP_ALBERS:
      {
	/* Compute sine and cosine of corner longitudes */
	/* -------------------------------------------- */
	for (i = 0; i < 2; i++)
	  {
	    lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
	    cs[i]  = cos(lonrad);
	    sn[i]  = sin(lonrad);
	  }


	/* Compute dot product */
	/* ------------------- */
	dotPrd = cs[0] * cs[1] + sn[0] * sn[1];


	/* Convert central meridian (DMS to DEG) & compute sin & cos */
	/* --------------------------------------------------------- */
	centMerd = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
	lonrad   = HE5_EHconvAng(centMerd, HE5_HDFE_DEG_RAD);
	cs[1]    = cos(lonrad);
	sn[1]    = sin(lonrad);


	/* If box brackets central meridian ... */
	/* ------------------------------------ */
	if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
	  {
	    latitude[4]  = cornerlat[0];
	    longitude[4] = centMerd;

	    latitude[5]  = cornerlat[1];
	    longitude[5] = centMerd;

	    *npnts = 6;
	  }
      }
      break;


    case HE5_GCTP_POLYC:
      {
	/* Compute sine and cosine of corner longitudes */
	/* -------------------------------------------- */
	for (i = 0; i < 2; i++)
	  {
	    lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
	    cs[i]  = cos(lonrad);
	    sn[i]  = sin(lonrad);
	  }


	/* Compute dot product */
	/* ------------------- */
	dotPrd = cs[0] * cs[1] + sn[0] * sn[1];


	/* Convert central meridian (DMS to DEG) & compute sin & cos */
	/* --------------------------------------------------------- */
	centMerd = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
	lonrad   = HE5_EHconvAng(centMerd, HE5_HDFE_DEG_RAD);
	cs[1] = cos(lonrad);
	sn[1] = sin(lonrad);


	/* If box brackets central meridian ... */
	/* ------------------------------------ */
	if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
	  {
	    latitude[4]  = cornerlat[0];
	    longitude[4] = centMerd;

	    latitude[5]  = cornerlat[1];
	    longitude[5] = centMerd;
	    *npnts       = 6;
	  }
      }
      break;


    case HE5_GCTP_TM:
      {
	/* Compute sine and cosine of corner longitudes */
	/* -------------------------------------------- */
	for (i = 0; i < 2; i++)
	  {
	    lonrad = HE5_EHconvAng(cornerlon[i], HE5_HDFE_DEG_RAD);
	    cs[i]  = cos(lonrad);
	    sn[i]  = sin(lonrad);
	  }


	/* Compute dot product */
	/* ------------------- */
	dotPrd = cs[0] * cs[1] + sn[0] * sn[1];


	for (i = -1; i <= 1; i++)
	  {
	    centMerd = HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_DEG);
	    lonrad   = HE5_EHconvAng(centMerd + 90 * i, HE5_HDFE_DEG_RAD);
	    csTest   = cos(lonrad);
	    snTest   = sin(lonrad);


	    /* If box brackets meridian ... */
	    /* ---------------------------- */
	    if (csTest * cs[1] + snTest * sn[1] > dotPrd)
	      {
		latitude[*npnts]  = cornerlat[0];
		longitude[*npnts] = centMerd;
		(*npnts)++;

		latitude[*npnts]  = cornerlat[1];
		longitude[*npnts] = centMerd;
		(*npnts)++;
	      }
	  }



	/* Compute sine and cosine of corner latitudes */
	/* ------------------------------------------- */
	for (i = 0; i < 2; i++)
	  {
	    latrad = HE5_EHconvAng(cornerlat[i], HE5_HDFE_DEG_RAD);
	    cs[i]  = cos(latrad);
	    sn[i]  = sin(latrad);
	  }

	/* Compute dot product */
	/* ------------------- */
	dotPrd = cs[0] * cs[1] + sn[0] * sn[1];


	/* Convert origin latitude (DMS to DEG) & compute sin & cos */
	/* -------------------------------------------------------- */
	orgLat = HE5_EHconvAng(projparm[5], HE5_HDFE_DMS_DEG);
	latrad = HE5_EHconvAng(orgLat, HE5_HDFE_DEG_RAD);
	cs[1]  = cos(latrad);
	sn[1]  = sin(latrad);


	/* If box brackets origin latitude ... */
	/* ----------------------------------- */
	if (cs[0] * cs[1] + sn[0] * sn[1] > dotPrd)
	  {
	    latitude[*npnts]  = orgLat;
	    longitude[*npnts] = cornerlon[0];
	    (*npnts)++;

	    latitude[*npnts] = orgLat;
	    longitude[*npnts] = cornerlon[1];
	    (*npnts)++;
	  }
      }
      break;


    case HE5_GCTP_HOM:
      {
	/* Tangent to y-axis along longitude */
	/* --------------------------------- */
	if (projparm[12] == 0)
	  {
	    cs[0] = cos(HE5_EHconvAng(projparm[8],  HE5_HDFE_DMS_RAD));
	    sn[0] = sin(HE5_EHconvAng(projparm[8],  HE5_HDFE_DMS_RAD));
	    cs[1] = cos(HE5_EHconvAng(projparm[9],  HE5_HDFE_DMS_RAD));
	    sn[1] = sin(HE5_EHconvAng(projparm[9],  HE5_HDFE_DMS_RAD));
	    cs[2] = cos(HE5_EHconvAng(projparm[10], HE5_HDFE_DMS_RAD));
	    sn[2] = sin(HE5_EHconvAng(projparm[10], HE5_HDFE_DMS_RAD));
	    cs[3] = cos(HE5_EHconvAng(projparm[11], HE5_HDFE_DMS_RAD));
	    sn[3] = sin(HE5_EHconvAng(projparm[11], HE5_HDFE_DMS_RAD));

	    bisectParm[2] = atan2(
				  (cs[1] * sn[3] * cs[0] - sn[1] * cs[3] * cs[2]),
				  (sn[1] * cs[3] * sn[2] - cs[1] * sn[3] * sn[0]));
	    bisectParm[0] = atan(
				 (sin(bisectParm[3]) * sn[0] - cos(bisectParm[3]) * cs[0]) /
				 (sn[1] / cs[1]));
	    bisectParm[2] = bisectParm[3] + 0.5 * dpi;
	  }
	else
	  {
	    cs[0] = cos(HE5_EHconvAng(projparm[3], HE5_HDFE_DMS_RAD));
	    sn[0] = sin(HE5_EHconvAng(projparm[3], HE5_HDFE_DMS_RAD));
	    cs[1] = cos(HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_RAD));
	    sn[1] = sin(HE5_EHconvAng(projparm[4], HE5_HDFE_DMS_RAD));

	    bisectParm[0] = asin(cs[1] * sn[0]);
	    bisectParm[2] = atan2(-cs[0], (-sn[1] * sn[0])) + 0.5 * dpi;
	  }

	for (i = 0; i < 2; i++)
	  {
	    bisectParm[1] = cornerlon[i];

	    if (HE5_EHbisect(HE5_homDyDtheta, bisectParm, 3, cornerlat[0], cornerlat[1],  0.0001, &tanLat) == 0)
	      {
		longitude[*npnts] = cornerlon[i];
		latitude[*npnts] = tanLat;
		(*npnts)++;
	      }
	  }

      }
      break;

    default:
      {
	if(projcode != HE5_GCTP_UTM)
	  {
	    status = FAIL;
	    H5Epush(__FILE__, "HE5_GDtangentpnts", __LINE__, H5E_ARGS, H5E_BADVALUE, "Unknown projection code.");
	    HE5_EHprint("Error: Unknown projection code, occured", __FILE__, __LINE__);
	  }
      }
      break;
	  
    }
  

  free(errbuf);

 COMPLETION:  
  return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefboxregion                                               |
|                                                                             |
|  DESCRIPTION: Defines region for subsetting in a grid.                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       hid_t   None        Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  cornerlon      double   dec deg    Longitude of opposite corners of box    |
|  cornerlat      double   dec deg    Latitude of opposite corners of box     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/22/99  A.Muslimov    Changed the type of return value from intn to hid_t.|
|                         Added error handling after the function calls.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
hid_t
HE5_GDdefboxregion(hid_t gridID, double cornerlon[], double cornerlat[])
{

  hid_t           regionID = FAIL;/* Region ID (return value)                */
  hid_t           fid      = FAIL;/* HDF-EOS file ID                         */
  hid_t           gid      = FAIL;/* "HDFEOS" group ID                       */
  hid_t           i;		  /* Loop index                              */

  herr_t          status   = FAIL;/* routine return status variable          */

  int             j;		  /* Loop index                              */
  int             projcode = FAIL;/* Projection code                         */
  int             zonecode = FAIL;/* Zone code                               */
  int             spherecode=FAIL;/* Sphere code                             */

  long            idx      = FAIL;/* Grid index                              */
  long            xdimsize = 0;	  /* XDim size                               */
  long            ydimsize = 0;	  /* YDim size                               */
  long            row[32];	  /* Row array                               */
  long            col[32];	  /* Column array                            */
  long            minCol    = 0;  /* Minimun column value                    */
  long            minRow    = 0;  /* Minimun row value                       */
  long            maxCol    = 0;  /* Maximun column value                    */
  long            maxRow    = 0;  /* Maximun row value                       */
  long            npnts     = 4;  /* No. of boundary (edge & tangent) pnts   */

  double          longitude[32];  /* Longitude array                         */
  double          latitude[32];	  /* Latitude array                          */
  double          upleftpt[2]={0.,0.};	/* Upper left pt coordinates         */
  double          lowrightpt[2]={0.,0.};/* Lower right pt coordinates        */
  double          projparm[16];	  /* Projection parameters                   */
  double          xscale    = 0.0;/* X scale                                 */
  double          yscale    = 0.0;/* Y scale                                 */
  double          lonrad0   = 0.0;/* Longitude of upper left point (radians) */
  double          latrad0   = 0.0;/* Latitude of upper left point (radians)  */
  double          lonrad2   = 0.0;/* Longitude of point (radians)            */
  double          latrad2   = 0.0;/* Latitude of point (radians)             */
  double	  lon[2], lat[2];
  double	  xcor[2], ycor[2];
  double	  upleftpt_m[2];
  double          xmtr[2], ymtr[2];
  int             nlatlon;

  /* Used for SOM projection  */
  long            blockindexstart = -1;
  long            blockindexstop = -1;
  double          offset[180];

  char            *errbuf=(char *)NULL;    /* Buffer for error message */
 
  HE5_LOCK;
  CHECKPOINTER(cornerlat);
  CHECKPOINTER(cornerlon);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdefboxregion", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
	
  /* Get grid info */
  /* ------------- */
  status = HE5_GDgridinfo(gridID, &xdimsize, &ydimsize, upleftpt, lowrightpt);
  if (status == FAIL)
    {
      regionID = FAIL;
      sprintf(errbuf,  "Failed to get grid information.\n" );
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return (regionID);
    }
  
  /* Make sure that xdimsize or ydimsize != 0 */
  /* ---------------------------------------- */
  if ( xdimsize == 0 || ydimsize == 0)
    {
      regionID = FAIL;
      sprintf(errbuf,  "Zero values of \"xdimsize\" and \"ydimsize\".\n" );
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return (regionID);
    }

  /* Initialize projparm[] array */
  /* --------------------------- */
  for (j = 0; j < 16; j++)
    projparm[ j ] = 0.;

  /* Get proj info */
  /* ------------- */
  status = HE5_GDprojinfo(gridID, &projcode, &zonecode, &spherecode, projparm);
  /* If no projection code defined then bail */
  /* --------------------------------------- */
  if (projcode == FAIL)
    {
      regionID = FAIL;
      sprintf(errbuf,"No projection code is defined.\n" ); 
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return (regionID);
    }
	

  /* Get default values for upleft and lowright if necessary */
  /* ------------------------------------------------------- */
  if (upleftpt[0] == 0 && upleftpt[1] == 0 && lowrightpt[0] == 0 && lowrightpt[1] == 0)
    {
      status = HE5_GDgetdefaults(projcode, zonecode, projparm, spherecode, upleftpt, lowrightpt);
      if (status == FAIL)
	{
	  regionID = FAIL;
	  sprintf(errbuf,"Failed to get default values for uplft and lowrght points.\n" );
	  H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
			
	  return (regionID);
	}
    }


  /* Fill-up longitude and latitude arrays */
  /* ------------------------------------- */
  longitude[0] = cornerlon[0];
  latitude[0]  = cornerlat[0];
	
  longitude[1] = cornerlon[0];
  latitude[1]  = cornerlat[1];
	
  longitude[2] = cornerlon[1];
  latitude[2]  = cornerlat[0];

  longitude[3] = cornerlon[1];
  latitude[3]  = cornerlat[1];


  /* Find additional tangent points from GDtangentpnts */
  /* ------------------------------------------------- */
  status = HE5_GDtangentpnts(projcode, projparm, cornerlon, cornerlat, longitude, latitude, &npnts);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Failed to find additional tangent points.\n" );
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(FAIL);
    }
	
	
  /* Initialize row[]/col[] arrays */
  /* ----------------------------- */
  for (j = 0; j < 32; j++)
    {
      row[j] = 0;
      col[j] = 0;
    }


  /* Convert from lon/lat to row/col */
  /* ------------------------------- */
  status = HE5_GDll2ij(projcode, zonecode, projparm, spherecode,xdimsize, ydimsize, upleftpt, lowrightpt,npnts, longitude, latitude, row, col, NULL, NULL);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot convert from lon/lat to row/col.\n" );
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(FAIL);
    }
	

  /* Find min/max values for row & col */
  /* --------------------------------- */
  minCol = col[0];
  minRow = row[0];
  maxCol = col[0];
  maxRow = row[0];

  for (i = 1; i < npnts; i++)
    {
      if (col[i] < minCol)
	{
	  minCol = col[i];
	}

      if (col[i] > maxCol)
	{
	  maxCol = col[i];
	}
		
      if (row[i] < minRow)
	{
	  minRow = row[i];
	}
		
      if (row[i] > maxRow)
	{
	  maxRow = row[i];
	}
    }
	

  /* "Clamp" if outside Grid */
  /* ----------------------- */
  minCol = (minCol < 0) ? 0 : minCol;
  minRow = (minRow < 0) ? 0 : minRow;
	
  maxCol = (maxCol >= xdimsize) ? xdimsize - 1 : maxCol;
  maxRow = (maxRow >= ydimsize) ? ydimsize - 1 : maxRow;

	
  /* Check whether subset region is outside grid region */
  /* -------------------------------------------------- */
  if (minCol >= xdimsize || minRow >= ydimsize || maxCol < 0 || maxRow < 0 )
    {
      regionID = FAIL;
      sprintf(errbuf, "Subset Region outside of Grid Region.");
      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(regionID);
    }
  else
    {
      /* Store grid region info */
      /* ---------------------- */
      for (i = 0; i < HE5_NGRIDREGN; i++)
	{
	  /* Find first empty grid region */
	  /* ---------------------------- */
	  if (HE5_GDXRegion[i] == 0)
	    {
	      /* Allocate space for grid region entry */
	      /* ------------------------------------ */
	      HE5_GDXRegion[i] = (struct HE5_gridRegion *)calloc(1, sizeof(struct HE5_gridRegion));
	      if(HE5_GDXRegion[i] == NULL)
		{
		  regionID = FAIL;
		  sprintf(errbuf, "Cannot allocate memory.\n");
		  H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
					
		  return(regionID);
		}
				
				
	      /* Store file and grid ID */
	      /* ---------------------- */
	      HE5_GDXRegion[i]->fid    = fid;
	      HE5_GDXRegion[i]->gridID = gridID;
				
				
	      /* Initialize vertical subset entries to FAIL */
	      /* ------------------------------------------ */
	      for (j = 0; j < HE5_DTSETRANKMAX; j++)
		{
		  HE5_GDXRegion[ i ]->StartVertical[j] = FAIL;
		  HE5_GDXRegion[ i ]->StopVertical[j]  = FAIL;
		}
				

	      /* Store start & count along x & y */
	      /* ------------------------------- */
	      HE5_GDXRegion[ i ]->xStart = minCol;
	      HE5_GDXRegion[ i ]->xCount = maxCol - minCol + 1;
	      HE5_GDXRegion[ i ]->yStart = minRow;
	      HE5_GDXRegion[ i ]->yCount = maxRow - minRow + 1;
				
	      /* Store upleft and lowright points of subset region */
	      /* ------------------------------------------------- */
	      if (projcode == HE5_GCTP_GEO)
		{
		  /* GEO projection */
		  /* -------------- */

		  /* Convert upleft & lowright lon from DMS to radians */
		  /* ------------------------------------------------- */
		  lonrad0 = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_RAD);
		  lonrad2 = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_RAD);
					
		  /* Compute X scale */
		  /* --------------- */
		  xscale = (lonrad2 - lonrad0) / xdimsize;
					
		  /* Convert upleft & lowright lat from DMS to radians */
		  /* ------------------------------------------------- */
		  latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_RAD);
		  latrad2 = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_RAD);
					
		  /* Compute Y scale */
		  /* --------------- */
		  yscale = (latrad2 - latrad0) / ydimsize;
					

		  /* MinCol -> radians -> DMS -> upleftpt[0] */
		  /* --------------------------------------- */
		  HE5_GDXRegion[i]->upleftpt[0] = HE5_EHconvAng(lonrad0 + xscale * minCol, HE5_HDFE_RAD_DMS);
					
		  /* MinRow -> radians -> DMS -> upleftpt[1] */
		  /* --------------------------------------- */
		  HE5_GDXRegion[i]->upleftpt[1] = HE5_EHconvAng(latrad0 + yscale * minRow, HE5_HDFE_RAD_DMS);

					
		  /* MinCol + 1 -> radians -> DMS -> lowrightpt[0] */
		  /* --------------------------------------------- */
		  HE5_GDXRegion[i]->lowrightpt[0] = HE5_EHconvAng(lonrad0 + xscale * (maxCol + 1), HE5_HDFE_RAD_DMS);
				  
					
		  /* MinRow + 1 -> radians -> DMS -> lowrightpt[1] */
		  /* --------------------------------------------- */
		  HE5_GDXRegion[i]->lowrightpt[1] = HE5_EHconvAng(latrad0 + yscale * (maxRow + 1), HE5_HDFE_RAD_DMS);
		}
	      else if (projcode == HE5_GCTP_BCEA)
		{
		  /* BCEA projection */
		  /* -------------- */
		  nlatlon = 2;
		  lon[0] = upleftpt[0];
		  lon[1] = lowrightpt[0];
		  lat[0] = upleftpt[1];
		  lat[1] = lowrightpt[1];
		  status =
		    HE5_GDll2mm_cea(projcode,zonecode,spherecode,projparm,
				    xdimsize, ydimsize,upleftpt, lowrightpt,nlatlon,
				    lon, lat, xcor, ycor, &xscale, &yscale);
		  upleftpt_m[0] = xcor[0];
		  upleftpt_m[1] = ycor[0];
		  if (status == FAIL)
		    {
		      sprintf(errbuf, "Error converting .");
		      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(errbuf);
		      return(FAIL);
		    }
  
		  /* MinCol -> meters -> upleftpt[0] */
		  /* ------------------------------- */
		  xmtr[0] = upleftpt_m[0] + xscale * minCol;
  
		  /* MinRow -> meters -> upleftpt[1] */
		  /* ------------------------------- */
		  ymtr[0] = upleftpt_m[1] + yscale * minRow;

		  /* MinCol + 1 -> meters -> lowrightpt[0] */
		  /* ------------------------------------- */
		  xmtr[1] = upleftpt_m[0] + xscale * (maxCol + 1);
  
		  /* MinRow + 1 -> meters -> lowrightpt[1] */
		  /* ------------------------------------- */
		  ymtr[1] = upleftpt_m[1] + yscale * (maxRow + 1);
 
		  /* Convert upleft & lowright lon from DMS to radians */
		  /* ------------------------------------------------- */
		  npnts = 2;
		  status = HE5_GDmm2ll_cea(projcode, zonecode, spherecode,
					   projparm, xdimsize, ydimsize,
					   upleftpt, lowrightpt, npnts,
					   xmtr,  ymtr,
					   longitude, latitude);
		  if (status == -1)
		    {
		      sprintf(errbuf, "Subsetting failed "); 
		      H5Epush(__FILE__, "HE5_GDdefboxregion", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(errbuf);
		      return (status);
		    }
		  HE5_GDXRegion[i]->upleftpt[0] = longitude[0];
  
		  HE5_GDXRegion[i]->upleftpt[1] = latitude[0];
 
		  HE5_GDXRegion[i]->lowrightpt[0] = longitude[1];

		  HE5_GDXRegion[i]->lowrightpt[1] = latitude[1];
		}
	      else if (projcode == HE5_GCTP_SOM)
		{
		  /* Store start & count along x & y */
		  /* ------------------------------- */
		  HE5_GDXRegion[i]->xStart = 0;
		  HE5_GDXRegion[i]->xCount = xdimsize;
		  HE5_GDXRegion[i]->yStart = 0;
		  HE5_GDXRegion[i]->yCount = ydimsize;
 
		  HE5_GDXRegion[i]->somStart = blockindexstart;
		  HE5_GDXRegion[i]->somCount = blockindexstop - blockindexstart + 1;
  
		  /* Store upleft and lowright points of subset region */
		  /* ------------------------------------------------- */
		  if (blockindexstart == 0)
		    {
		      HE5_GDXRegion[i]->upleftpt[0] = upleftpt[0];
		      HE5_GDXRegion[i]->upleftpt[1] = upleftpt[1];
		      HE5_GDXRegion[i]->lowrightpt[0] = lowrightpt[0];
		      HE5_GDXRegion[i]->lowrightpt[1] = lowrightpt[1];
		    }
		  else
		    {
		      HE5_GDXRegion[i]->upleftpt[0] =
			(lowrightpt[0] - upleftpt[0])*
			(offset[blockindexstart-1]/xdimsize) + upleftpt[0];
		      HE5_GDXRegion[i]->upleftpt[1] =
			(lowrightpt[1] - upleftpt[1])*
			(blockindexstart+1-1) + upleftpt[1];

		      HE5_GDXRegion[i]->lowrightpt[0] =
			(lowrightpt[0] - upleftpt[0])*
			(offset[blockindexstart-1]/xdimsize) + lowrightpt[0];

		      HE5_GDXRegion[i]->lowrightpt[1] =
			(lowrightpt[1] - upleftpt[1])*
			(blockindexstart+1-1) + lowrightpt[1];
  
		    }
		}

	      else
		{
		  /* Non-GEO, Non-BCEA  projections */
		  /* ------------------------------ */

		  /* Compute X & Y scale */
		  /* ------------------- */
		  xscale = (lowrightpt[0] - upleftpt[0]) / xdimsize;
		  yscale = (lowrightpt[1] - upleftpt[1]) / ydimsize;
					
					
		  /* MinCol -> meters -> upleftpt[0] */
		  /* ------------------------------- */
		  HE5_GDXRegion[i]->upleftpt[0] = upleftpt[0] + xscale * minCol;

		  /* MinRow -> meters -> upleftpt[1] */
		  /* ------------------------------- */
		  HE5_GDXRegion[i]->upleftpt[1] = upleftpt[1] + yscale * minRow;
					
		  /* MinCol + 1 -> meters -> lowrightpt[0] */
		  /* ------------------------------------- */
		  HE5_GDXRegion[i]->lowrightpt[0] = upleftpt[0] + xscale * (maxCol + 1);
					
		  /* MinRow + 1 -> meters -> lowrightpt[1] */
		  /* ------------------------------------- */
		  HE5_GDXRegion[i]->lowrightpt[1] = upleftpt[1] + yscale * (maxRow + 1);
		}
				
	      /* Store region ID */
	      /* --------------- */
	      regionID = i;
	      break;
	    }
	}
    }
	
	
  free(errbuf);
  errbuf = NULL;
   
 COMPLETION:
  HE5_UNLOCK;
  return (regionID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDregioninfo                                                 |
|                                                                             |
|  DESCRIPTION: Retrieves size of region in bytes.                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  regionID       hid_t               Region ID                               |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               field number types                      |
|  rank           int                 field rank                              |
|  dims           hsize_t             dimensions of field region              |
|  size           long                size in bytes of field region           |
|  upleftpt       double              Upper left corner coord for region      |
|  lowrightpt     double              Lower right corner coord for region     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  9/23/99  A.Muslimov    Changed the type  of gridID, regionID from int32_t  |
|                         to hid_t.Removed redundant if(status == 0){} blocks.|
|                         Added error handling after the function calls.      |
|                         Cleaned up minor things.                            |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Jan 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|  June 04  S.Zhao        Enabled to subset on a one-dimensional field.       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDregioninfo(hid_t gridID, hid_t regionID, const char *fieldname, hid_t *ntype, int *rank, hsize_t dims[], long  *size, double upleftpt[], double lowrightpt[])
{

  herr_t          status = FAIL;/* routine return status variable */ 
 
  int             j;            /* Loop index                     */

  hid_t           fid    = FAIL;/* HDF-EOS file ID                */
  hid_t           gid    = FAIL;/* "HDFEOS" group ID              */
  
  long            idx    = FAIL;/* Grid index                     */
  long            index  = FAIL;/* Dimension index                */
  
  char            dimlist[HE5_HDFE_DIMBUFSIZE];/* Dimension list  */
  char            *errMesg = "Vertical Dimension Not Found: \"%s\".\n";
  char            *errM1 = "Both \"XDim\" and \"YDim\" must be present ";
  char            *errM2 = "in the dimension list for \"%s\".\n";
  char            *errbuf= (char *)NULL;      /* Error buffer     */
  
  CHECKPOINTER(fieldname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDregioninfo", &fid, &gid, &idx);
  if(status == FAIL)
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      free(errbuf);
     
      return(status);
    }
  
  
  /* Check for valid region ID */
  /* ------------------------- */
  if (regionID < 0 || regionID >= HE5_NGRIDREGN)
    {
      status = FAIL;
      sprintf(errbuf, "Invalid Region ID: %d.\n", regionID);
      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);
    }
  
  
  
  /* Check for active region ID */
  /* -------------------------- */
  if (HE5_GDXRegion[regionID] == 0)
    {
      status = FAIL;
      sprintf(errbuf, "Inactive Region ID: %d.\n", regionID);
      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(status);
    }
  
  
  
  
  /* Check that region defined for this file */
  /* --------------------------------------- */
  if (HE5_GDXRegion[regionID]->fid != fid)
    {
      status = FAIL;
      sprintf(errbuf, "Region is not defined for this file.\n");
      H5Epush(__FILE__, "HE5_GDregioninfo",  __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(status);
    }
  
  
  
  /* Check that region defined for this grid */
  /* --------------------------------------- */
  if (HE5_GDXRegion[regionID]->gridID != gridID)
    {
      status = FAIL;
      sprintf(errbuf, "Region is not defined for this Grid.\n");
      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);
    }
  
  
  
  /* Check for valid fieldname */
  /* ------------------------- */
  status = HE5_GDfieldinfo(gridID, fieldname, rank, dims, ntype, dimlist, NULL);
  if (status == FAIL)
    {
      /* Fieldname not found in grid */
      /* --------------------------- */
      sprintf(errbuf, "Fieldname \"%s\" not found.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDregioninfo",    __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(status);
    }
  else if (*rank > 1)
    {
      /* "XDim" and/or "YDim" not found */
      /* ------------------------------ */
      if ( HE5_EHstrwithin("XDim", dimlist, ',') == FAIL || HE5_EHstrwithin("YDim", dimlist, ',') == FAIL)
	{
	  status = FAIL;
	  sprintf(errbuf, "%s%s%s", errM1, errM2, fieldname);
	  H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	    
	  return(status);
	}
    }
  
  
  
  /* If no problems ... */
  /* ------------------ */
  
  if (*rank > 1)
    {
      /* Load XDim dimension from region entry */
      /* ------------------------------------- */
      if (HE5_GDXRegion[regionID]->xCount != 0)
	{
	  dims[ HE5_EHstrwithin("XDim", dimlist, ',') ] = (hsize_t)HE5_GDXRegion[regionID]->xCount;
	}
      /* Load YDim dimension from region entry */
      /* ------------------------------------- */
      if (HE5_GDXRegion[regionID]->yCount != 0)
	{
	  dims[ HE5_EHstrwithin("YDim", dimlist, ',') ] = (hsize_t)HE5_GDXRegion[regionID]->yCount;
	}
    }

  
  /* Vertical Subset */
  /* --------------- */
  for (j = 0; j < HE5_DTSETRANKMAX; j++)
    {
      /* If active vertical subset ... */
      /* ----------------------------- */
      if (HE5_GDXRegion[regionID]->StartVertical[j] != FAIL)
	{
	  /* Find vertical dimension within dimlist */
	  /* -------------------------------------- */
	  index = HE5_EHstrwithin(HE5_GDXRegion[regionID]->DimNamePtr[j], dimlist, ',');

	  /* If dimension found ... */
	  /* ---------------------- */
	  if (index != FAIL)
	    {
	      /* Compute dimension size */
	      /* ---------------------- */
	      dims[ index ] = HE5_GDXRegion[regionID]->StopVertical[j] - HE5_GDXRegion[regionID]->StartVertical[j] + 1;
	    }
	  else
	    {
	      /* Vertical dimension not found */
	      /* ---------------------------- */
	      status = FAIL;
	      *size  = FAIL;
	      sprintf( errbuf, errMesg, HE5_GDXRegion[regionID]->DimNamePtr[j]);
	      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
		    
	      return(status);
	    }
	}
    }
  
  
  
  /* Compute number of total elements */
  /* -------------------------------- */
  *size = (long)dims[ 0 ];
  
  for (j = 1; j < *rank; j++)
    *size *= (long)dims[j];
  
  /* Multiply by size in bytes of numbertype */
  /* --------------------------------------- */
  *size *= (long)HE5_GDfielddatasize(gridID,fieldname);
  if(*size == 0)
    {
      status = FAIL;
      sprintf(errbuf, "Cannot get the data size of the data field.\n");
      H5Epush(__FILE__, "HE5_GDregioninfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      free(errbuf);
	     
      return(status);
    }
  
  
  /* Return upper left and lower right subset values */
  /* ----------------------------------------------- */
  upleftpt[0]   = HE5_GDXRegion[regionID]->upleftpt[0];
  upleftpt[1]   = HE5_GDXRegion[regionID]->upleftpt[1];
  lowrightpt[0] = HE5_GDXRegion[regionID]->lowrightpt[0];
  lowrightpt[1] = HE5_GDXRegion[regionID]->lowrightpt[1];
  
  
  free(errbuf);
  errbuf = NULL;
 
 COMPLETION:
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetfieldID                                                 |
|                                                                             |
|  DESCRIPTION: Return a data field ID                                        |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    Added error handling after the call to GDchkgdid(). |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static herr_t   
HE5_GDgetfieldID(hid_t gridID, const char *fieldname, hid_t *fieldID)
{
  
  herr_t         status     = FAIL;/* routine return status variable */

  int            i;                /* Loop index                     */
  
  hid_t          fid        = FAIL;/* HDF-EOS file ID                */
  hid_t          gid        = FAIL;/* "HDFEOS" group ID              */
  
  long           idx        = FAIL;/* Grid index                     */
  
  /*  char           *errbuf=(char *)NULL;*//* error message buffer        */
					    char           errbuf[HE5_HDFE_ERRBUFSIZE];
  
  CHECKPOINTER(fieldname);
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  /*
    errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
    if(errbuf == NULL)
    {
    H5Epush(__FILE__, "HE5_GDgetfieldID", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
    HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
    return(FAIL);
    }
  */
  

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgetfieldID", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDgetfieldID", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      /*free(errbuf);*/
		
      return(FAIL);
    }
  
  /* Loop through all data datasets in grid and get dataset name */
  /* ----------------------------------------------------------- */
  for (i = 0; i < HE5_GDXGrid[idx].nDFLD; i++)
    {
      if( strcmp(fieldname, HE5_GDXGrid[idx].ddataset[i].name) == 0 ) break;
    }
  
  /* Get field-related dataset  ID */
  /* ============================= */ 
  *fieldID = HE5_GDXGrid[idx].ddataset[i].ID;
  
  /*free(errbuf);*/
  
 COMPLETION:
  return(status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDfielddatasize                                              |
|                                                                             |
|  DESCRIPTION: Return size in bytes of a data field                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  size           size_t              data type size in bytes                 |
|                                                                             |
|  INPUTS:                                                                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dget_type                                                     |
|             H5Tget_size                                                     |
|             H5Tclose                                                        |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Added proper error handlings after the function     |
|                         calls.                                              |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static size_t 
HE5_GDfielddatasize(hid_t gridID, const char *fieldname)
{
  size_t         size      =  0;  /* return value, data type size in bytes */
  
  herr_t         status    = FAIL;/* routine return status variable */

  int            i;				  /* Loop index */

  hid_t          fid       = FAIL;/* HDF-EOS file ID */
  hid_t          gid       = FAIL;/* "HDFEOS" group ID */
  hid_t          dtype     = FAIL;/* datatype ID */
  hid_t          datasetid = FAIL;/* field dataset ID */

  long           idx       = FAIL;/* Grid index */

  char           *errbuf=(char *)NULL;/* error message buffer */

  CHECKPOINTER(fieldname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      size = 0;
      H5Epush(__FILE__, "HE5_GDfielddatasize", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(size);
    }
	

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDfielddatasize", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      size = 0;
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDfielddatasize", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(size);
    }
	
  /* Loop through all data datasets in grid */
  /* -------------------------------------- */
  for (i = 0; i < HE5_GDXGrid[idx].nDFLD; i++)
    {
      /* Get dataset name */
      /* ---------------- */
      if( strcmp(fieldname, HE5_GDXGrid[idx].ddataset[i].name) == 0 )
	break;
    }

  /* Get dataset ID */
  /* -------------- */
  datasetid = HE5_GDXGrid[idx].ddataset[i].ID;
  dtype     = H5Dget_type(datasetid);
  if ( dtype == FAIL )
    {
      size = 0;
      sprintf(errbuf, "Cannot get data type ID.\n");
      H5Epush(__FILE__, "HE5_GDfielddatasize", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(size);
    }

  /* Get data type size (bytes) */
  /* -------------------------- */   
  size = H5Tget_size(dtype);
  if ( size == 0 )
    {
      sprintf(errbuf, "Cannot retrieve data size.\n");
      H5Epush(__FILE__, "HE5_GDfielddatasize", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(size);
    }

  /* Release the data type ID */
  /* ------------------------ */
  status = H5Tclose(dtype);
  if ( status == FAIL )
    {
      size = 0;
      sprintf(errbuf, "Cannot release datatype ID.\n");
      H5Epush(__FILE__, "HE5_GDfielddatasize", __LINE__, H5E_DATATYPE, H5E_CLOSEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }


  free(errbuf);
  errbuf = NULL;
    
 
 COMPLETION:
  return(size);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDextractregion                                              |
|                                                                             |
|  DESCRIPTION: Retrieves data from specified region.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  regionID       hid_t               Region ID                               |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                Data buffer containing subsetted region |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/23/99  A.Muslimov    Changed the data type of gridID and regionID from   |
|                         int32_t to hid_t. Added proper error handling after |
|                         the function calls. Removed redundant               |
|                         if(status==0){} brackets.                           |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  June 04  S.Zhao        Enabled to subset on a one-dimensional field.       |
|  July 04  S.Zhao        Set a default origin if HE5_GDorigininfo fails.     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDextractregion(hid_t gridID, hid_t regionID, const char *fieldname, void *buffer)
{
  herr_t          status   = FAIL;               /* routine return status variable */

  int             i, j;			         /* Loop indices                   */
  int             rank     = FAIL;               /* Field rank                     */
  int             origincode=FAIL;               /* Pixel origin code              */

  hid_t           *ntype   = (hid_t *)NULL;      /* number types                   */

  hid_t           fid      = FAIL;               /* HDF-EOS file ID                */
  hid_t           gid      = FAIL;               /* "HDFEOS" group ID              */

  long            idx      = FAIL;               /* Grid index                     */
  long            index    = FAIL;               /* Dimension index                */

  hssize_t        start[HE5_DTSETRANKMAX];       /* Start array for data to read   */
  hsize_t         edge[HE5_DTSETRANKMAX];        /* Edge array for data to read    */
  hsize_t         dims[HE5_DTSETRANKMAX];        /* Dimensions                     */

  char            dimlist[HE5_HDFE_DIMBUFSIZE];	 /* Dimension list                 */
  char            *errMesg = "Vertical Dimension Not Found: \"%s\".\n";
  char            *errM1   = "Both \"XDim\" and \"YDim\" must be present ";
  char            *errM2   = "in the dimension list for \"%s\".\n";
  char            *errbuf  = (char *)NULL; /* error message buffer */

  HE5_LOCK;
  CHECKPOINTER(fieldname);  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDextractregion", &fid, &gid, &idx);
  if (status == FAIL)
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      
      return(status);
    }


  /* Check for valid region ID */
  /* ------------------------- */    
  if (regionID < 0 || regionID >= HE5_NGRIDREGN)
    {
      status = FAIL;
      sprintf(errbuf, "Invalid Region id: %d.\n", regionID);
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);	    
    }


  /* Check for active region ID */
  /* -------------------------- */
  if (HE5_GDXRegion[regionID] == 0)
    {
      status = FAIL;
      sprintf(errbuf, "Inactive Region ID: %d.\n", regionID);
      H5Epush(__FILE__,  "HE5_GDextractregion", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);
    }



  /* Check that region defined for this file */
  /* --------------------------------------- */
  if (HE5_GDXRegion[regionID]->fid != fid)
    {
      status = FAIL;
      sprintf(errbuf, "Region is not defined for this file.\n");
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);
	    
    }


  /* Check that region defined for this grid */
  /* --------------------------------------- */
  if (HE5_GDXRegion[regionID]->gridID != gridID)
    {
      status = FAIL;
      sprintf(errbuf, "Region is not defined for this Grid.\n");
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);
    }



  /* Initialize dims[] array */
  /* ----------------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    dims[ i ] = 0;


  /* Check for valid fieldname */
  /* ------------------------- */
  ntype = (hid_t *)calloc(1, sizeof(hid_t));

  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, dimlist, NULL);
  if (status == FAIL)
    {
      /* Fieldname not found in grid */
      /* --------------------------- */
      sprintf(errbuf, "Fieldname \"%s\" not found.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(ntype);
	    
      return(status);
    }
  else if (rank > 1)
    {
      /* "XDim" and/or "YDim" not found */
      /* ------------------------------ */
      if ( HE5_EHstrwithin("XDim", dimlist, ',') == FAIL || HE5_EHstrwithin("YDim", dimlist, ',') == FAIL)
	{
	  status = FAIL;
	  sprintf(errbuf, "%s%s%s", errM1, errM2, fieldname);
	  H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(ntype);

	  return(status);
	}
    }


  /* Get origin order info */
  /* --------------------- */
  status = HE5_GDorigininfo(gridID, &origincode);
  if (status == FAIL)
    {
      /* Set a default origin code */
      /* ------------------------- */
      origincode = HE5_HDFE_GD_UL;
    }


  /* Initialize start & edge arrays */
  /* ------------------------------ */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    {
      start[ i ] = 0;
      edge[ i ]  = dims[ i ];
    }

  if (rank > 1)
    {
      /* Set start & edge arrays for XDim */
      /* -------------------------------- */
      index = HE5_EHstrwithin("XDim", dimlist, ',');
      if (HE5_GDXRegion[regionID]->xCount != 0)
	{
	  edge[index]  = (hsize_t)HE5_GDXRegion[regionID]->xCount;
	  start[index] = (hssize_t)HE5_GDXRegion[regionID]->xStart;
	}

      /* Adjust X-dim start if origin on right edge */
      /* ------------------------------------------ */
      if ((origincode & 1) == 1)
	{
	  start[index] = dims[index] - (start[index] + edge[index]);
	}

      /* Set start & edge arrays for YDim */
      /* -------------------------------- */
      index = HE5_EHstrwithin("YDim", dimlist, ',');
      if (HE5_GDXRegion[regionID]->yCount != 0)
	{
	  start[index] = (hssize_t)HE5_GDXRegion[regionID]->yStart;
	  edge[index]  = (hsize_t)HE5_GDXRegion[regionID]->yCount;
	}

      /* Adjust Y-dim start if origin on lower edge */
      /* ------------------------------------------ */
      if ((origincode & 2) == 2)
	{
	  start[index] = dims[index] - (start[index] + edge[index]);
	}

    }


  /* Vertical Subset */
  /* --------------- */
  for (j = 0; j < HE5_DTSETRANKMAX; j++)
    {
      /* If active vertical subset ... */
      /* ----------------------------- */
      if (HE5_GDXRegion[regionID]->StartVertical[j] != FAIL)
	{

	  /* Find vertical dimension within dimlist */
	  /* -------------------------------------- */
	  index = HE5_EHstrwithin(HE5_GDXRegion[regionID]->DimNamePtr[j], dimlist, ',');

	  /* If dimension found ... */
	  /* ---------------------- */
	  if (index != FAIL)
	    {
	      /* Compute start and edge for vertical dimension */
	      /* --------------------------------------------- */
	      start[index] = (hssize_t)HE5_GDXRegion[regionID]->StartVertical[j];
	      edge[index]  = (hsize_t)(HE5_GDXRegion[regionID]->StopVertical[j] - HE5_GDXRegion[regionID]->StartVertical[j] + 1);
	    }
	  else
	    {
	      /* Vertical dimension not found */
	      /* ---------------------------- */
	      status = FAIL;
	      sprintf(errbuf, errMesg, HE5_GDXRegion[regionID]->DimNamePtr[j]);
	      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(ntype);

	      return(status);
		    
	    }
	}
	    
    }
	

  /* Read into data buffer */
  /* --------------------- */
  status = HE5_GDreadfield(gridID, fieldname, start, NULL, edge, buffer);
  if (status == FAIL)
    {
      sprintf(errbuf, "Cannot read data for the \"%s\" data field into data buffer.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDextractregion", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }


  free(errbuf);
  errbuf = NULL;
  free(ntype);
 
 COMPLETION:
  HE5_UNLOCK;
  return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdupregion                                                  |
|                                                                             |
|  DESCRIPTION: Duplicates a region                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  newRegionID    hid_t               New region ID                           |
|                                                                             |
|  INPUTS:                                                                    |
|  oldRegionID    hid_t               Old region ID                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 98   Abe Taaheri   changed *GDXRegion[i] = *GDXRegion[oldregionID];    |
|                         to copy elements of structure one by one to avoid   |
|                         copying pointer for DimNamePtr to another place that|
|                         causes "Freeing Unallocated Memory" in purify when  |
|                         using GDdetach                                      |
|  9/23/99  A.Muslimov    Changed the data type for newregionID(return value) |
|                         and oldregionID from int32_t to hid_t.              |
|  4/19/00 A.Muslimov     Changed type of 'slendupregion' from long to size_t.|
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
hid_t 
HE5_GDdupregion(hid_t oldRegionID)
{

  hid_t           newRegionID = FAIL;/* New region ID (return value)    */
  hid_t           i, j;              /* Loop indices                    */
  
  size_t          slendupregion  = 0;/* length of dimension name string */

  /* Find first empty (inactive) region */
  /* ---------------------------------- */
  for (i = 0; i < HE5_NGRIDREGN; i++)
    {
      if (HE5_GDXRegion[i] == 0)
        {
	  /* Allocate space for new grid region entry */
	  /* ---------------------------------------- */
	  HE5_GDXRegion[i] = (struct HE5_gridRegion *)calloc(1, sizeof(struct HE5_gridRegion));
	  if(HE5_GDXRegion[i] == NULL)
            {
	      H5Epush(__FILE__, "HE5_GDdupregion", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory");
	      HE5_EHprint("Error: Cannot allocate memory, occured", __FILE__, __LINE__);
	      return(FAIL);
            }
		  
		  
	  /* Copy old region structure data to new region */
	  /* -------------------------------------------- */
	  HE5_GDXRegion[i]->fid           = HE5_GDXRegion[oldRegionID]->fid;
	  HE5_GDXRegion[i]->gridID        = HE5_GDXRegion[oldRegionID]->gridID;
	  HE5_GDXRegion[i]->xStart        = HE5_GDXRegion[oldRegionID]->xStart;
	  HE5_GDXRegion[i]->xCount        = HE5_GDXRegion[oldRegionID]->xCount;
	  HE5_GDXRegion[i]->yStart        = HE5_GDXRegion[oldRegionID]->yStart;
	  HE5_GDXRegion[i]->yCount        = HE5_GDXRegion[oldRegionID]->yCount;
	  HE5_GDXRegion[i]->upleftpt[0]   = HE5_GDXRegion[oldRegionID]->upleftpt[0];
	  HE5_GDXRegion[i]->upleftpt[1]   = HE5_GDXRegion[oldRegionID]->upleftpt[1];
	  HE5_GDXRegion[i]->lowrightpt[0] = HE5_GDXRegion[oldRegionID]->lowrightpt[0];
	  HE5_GDXRegion[i]->lowrightpt[1] = HE5_GDXRegion[oldRegionID]->lowrightpt[1];
	  for (j = 0; j < HE5_DTSETRANKMAX; j++)
            {
	      HE5_GDXRegion[i]->StartVertical[j] = HE5_GDXRegion[oldRegionID]->StartVertical[j];
	      HE5_GDXRegion[i]->StopVertical[j]  = HE5_GDXRegion[oldRegionID]->StopVertical[j];
            }
		  
	  for (j = 0; j < HE5_DTSETRANKMAX; j++)
            {
	      if(HE5_GDXRegion[oldRegionID]->DimNamePtr[j] != NULL)
                {
		  slendupregion = strlen(HE5_GDXRegion[oldRegionID]->DimNamePtr[j]);
		  HE5_GDXRegion[i]->DimNamePtr[j] = (char *) calloc( (slendupregion + 1), sizeof(char) );
		  strcpy(HE5_GDXRegion[i]->DimNamePtr[j],HE5_GDXRegion[oldRegionID]->DimNamePtr[j]);
                }
            }
		  
	  /* Define new region ID */
	  /* -------------------- */
	  newRegionID = i;
		  
	  break;
        }
    }
  return (newRegionID);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefvrtregion                                               |
|                                                                             |
|  DESCRIPTION: Finds elements of a monotonic field within a vertical subset  |
|               region.                                                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  regionID       hid_t   None        Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  regionID       hid_t               Region ID                               |
|  vertObj        char                Vertical object to subset               |
|  range          double              Vertical subsetting range               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/23/99  A.Muslimov    Changed the data types of return value, gridID, and |
|                         RegionID from int32_t to hid_t. Added error handling|
|                         after the function calls.                           |
|  10/18/99 A.Muslimov    Replace memcpy() by memmove() to avoid a problem    |
|                         when arguments 1 and 2 overlap in memory.           |
|  11/10/99 A.Muslimov    In the call to GDreadfield() 3d and 5th arguments   |
|                         were passed as "NULL"s, which resulted in a core    |
|                         dump. To fix this bug, replaced them by start and   |
|                         edge, respectively.                                 |
|  04/19/00 A.Muslimov    Changed type of 'slen' from long to size_t.         |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|  Mar  04  S.Zhao        Modified for supported field type.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
#define HE5_SETGRIDREG							\
									\
  status = HE5_GDgridinfo(gridID, &xdimsize, &ydimsize, upleftpt, lowrightpt); \
  for (k = 0; k < HE5_NGRIDREGN; k++)					\
    {									\
      if (HE5_GDXRegion[k] == 0)					\
	{								\
	  HE5_GDXRegion[k] = (struct HE5_gridRegion *)calloc(1, sizeof(struct HE5_gridRegion)); \
	  HE5_GDXRegion[k]->fid           = fid;			\
	  HE5_GDXRegion[k]->gridID        = gridID;			\
	  HE5_GDXRegion[k]->xStart        = 0;				\
	  HE5_GDXRegion[k]->xCount        = xdimsize;			\
	  HE5_GDXRegion[k]->yStart        = 0;				\
	  HE5_GDXRegion[k]->yCount        = ydimsize;			\
	  HE5_GDXRegion[k]->upleftpt[0]   = upleftpt[0];		\
	  HE5_GDXRegion[k]->upleftpt[1]   = upleftpt[1];		\
	  HE5_GDXRegion[k]->lowrightpt[0] = lowrightpt[0];		\
	  HE5_GDXRegion[k]->lowrightpt[1] = lowrightpt[1];		\
	  regionID = k;							\
	  for (j = 0; j < HE5_DTSETRANKMAX; j++)			\
	    {								\
	      HE5_GDXRegion[k]->StartVertical[j] = FAIL;		\
	      HE5_GDXRegion[k]->StopVertical[j]  = FAIL;		\
	    }								\
	  break;							\
	}								\
    }


#define HE5_FILLVERTREG							\
  for (j = 0; j < HE5_DTSETRANKMAX; j++)				\
    {									\
      if (HE5_GDXRegion[regionID]->StartVertical[j] == FAIL)		\
	{								\
	  HE5_GDXRegion[regionID]->StartVertical[j] = i;		\
	  HE5_GDXRegion[regionID]->DimNamePtr[j] = (char *) calloc( (slen + 1),sizeof(char) ); \
	  memmove(HE5_GDXRegion[regionID]->DimNamePtr[j], dimlist, slen + 1); \
	  break;							\
	}								\
    }

hid_t 
HE5_GDdefvrtregion(hid_t gridID, hid_t regionID, char *vertObj, double range[])
{

  herr_t          status = FAIL;                /* Return status variable */

  int             tmp    = 999;                 /* Temporary flag         */
  int             rank   = FAIL;                /* Dataset rank           */ 
  int             vertINT= 0;
  int             j;                            /* Loop index             */

  hid_t           *nt    = (hid_t *)NULL;       /* number types           */
    
  unsigned char   found  = 0;                   /* "Found" flag           */

  hid_t           k;			        /* loop index             */ 
  hid_t           fid    = FAIL;                /* HDF-EOS file ID        */
  hid_t           gid    = FAIL;                /* "HDFEOS" group ID      */
  hid_t           dtype  = FAIL;                /* Datatype  ID           */
  hid_t           fieldID= FAIL;                /* Data field dataset ID  */

  size_t          slen   = 0;                   /* String length value    */
  size_t          size   = 0;                   /* Field datasize (bytes) */

  long            i;			        /* loop index             */
  long            idx      = FAIL;              /* Grid index             */
  long            xdimsize =  0;                /* Size of "XDim"         */
  long            ydimsize =  0;                /* Size of "YDim"         */

  short           vertSHORT= 0;                 /* Temp "short" variable  */

  float           vertFLT  = 0.;                /* Temp "float" variable  */

  double          vertDBL  = 0.;                /* Temp "double" variable */
  double          upleftpt[2]={0.,0.};	        /* Upper left point       */
  double          lowrightpt[2]={0.,0.};        /* Lower right point      */

  hsize_t         dims[HE5_DTSETRANKMAX];       /* Dimension sizes array  */
  hssize_t        start[HE5_DTSETRANKMAX];      /* Start array            */
  hsize_t         edge[HE5_DTSETRANKMAX];       /* Edge array             */

  char            *vertArr = (char *)NULL;      /* Temp "char" variable   */ 
  char            dimlist[HE5_HDFE_DIMBUFSIZE]; /* Dimension list         */
  char	          *errbuf  = (char *)NULL;	    /* Error message buffer   */

  HE5_LOCK;
  CHECKPOINTER(vertObj);
  CHECKPOINTER(range);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /* Initialize arrays */
  /* ----------------- */
  for (j = 0; j < HE5_DTSETRANKMAX; j++)
    {
      dims[ j ]  = 0;
      start[ j ] = 0;
      edge[ j ]  = 0;
    }
    
   
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDdefvrtregion", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      regionID = FAIL;
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return( regionID );
    }
 
  memmove(dimlist, vertObj, 4);
  dimlist[4] = 0;

  if (strcmp(dimlist, "DIM:") == 0)
    {
      slen = strlen(vertObj) - 4;
      if (regionID == FAIL)
	{
	  HE5_SETGRIDREG;
	}
      for (j = 0; j < HE5_DTSETRANKMAX; j++)
	{
	  if (HE5_GDXRegion[regionID]->StartVertical[j] == FAIL)
	    {
	      HE5_GDXRegion[regionID]->StartVertical[j] = (long)range[0];
	      HE5_GDXRegion[regionID]->StopVertical[j]  = (long)range[1];
	      HE5_GDXRegion[regionID]->DimNamePtr[j]    = (char *) calloc( (slen + 1),sizeof(char) );

	      if(HE5_GDXRegion[regionID]->DimNamePtr[j] == NULL)
		{
		  sprintf(errbuf,"Cannot allocate memory\n") ;
		  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf) ;
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
			
		  return(FAIL);
		}
	      memmove(HE5_GDXRegion[regionID]->DimNamePtr[j],vertObj + 4, slen + 1);
	      break;
	    }
	}
    }
  else
    {
      nt = (hid_t *)calloc(1, sizeof(hid_t));
      if (nt == (hid_t *)NULL )
	{
	  regionID = FAIL;
	  sprintf(errbuf, "Cannot allocate memory for data type class ID.\n");
	  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
		
	  return(regionID);
	}

      status = HE5_GDfieldinfo(gridID, vertObj, &rank, dims, nt, dimlist,NULL);
      if (status == FAIL)
	{
	  regionID = FAIL;
	  sprintf(errbuf, "Vertical Field: \"%s\" not found.\n", vertObj);
	  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(nt);
		
	  return(regionID);
	}
      else
	{
	  if (rank != 1)
	    {
	      regionID = FAIL;
	      sprintf(errbuf, "Vertical Field: \"%s\" must be 1-dim.\n", vertObj);
	      H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(nt);
		    
	      return(regionID);
	    }
	  else
	    {
	      slen = strlen(dimlist);
	      size = HE5_GDfielddatasize(gridID, vertObj);
	      vertArr = (char *)calloc(dims[0], size);
	      if(vertArr == NULL)
		{
		  regionID = FAIL;
		  sprintf(errbuf,"Cannot allocate memory\n");
		  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
		  free(errbuf);
		  free(nt);
					  
		  return(regionID);
		}

	      /* ------------------------------------------------  */
	      /* Generate start[] and edge[] arrays to pass to the */
	      /*      GDreadfield(). The NULL values are not       */
	      /*       allowed for the 3d and 5th argument         */
	      /*           of this function. (A.M)                 */
	      /* ------------------------------------------------  */
	      for( k = 0; k < rank; k++ )
		{
		  start[k] = 0;
		  edge[k]  = dims[k];
		}
					
	      status = HE5_GDreadfield(gridID, vertObj, start, NULL, edge, vertArr);
	      if(status == FAIL)
		{
		  regionID = FAIL;
		  sprintf(errbuf, "Cannot read out data from the data field.\n");
		  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  free(errbuf);
		  free(vertArr);
		  free(nt);
						
		  return(regionID);
		}

	      /* Get field ID and field data type */
	      /* ------------------------------- */
	      status = HE5_GDgetfieldID(gridID, vertObj, &fieldID);
	      if(status == FAIL)
		{
		  regionID = FAIL;
		  sprintf(errbuf, "Cannot get the data field ID.\n");
		  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  free(errbuf);
		  free(vertArr);
		  free(nt);
						
		  return(regionID);
		}

	      dtype = H5Dget_type(fieldID);
	      if(dtype == FAIL)
		{
		  regionID = FAIL;
		  sprintf(errbuf, "Cannot get the data type of the data field.\n");
		  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  free(errbuf);
		  free(vertArr);
		  free(nt);
						
		  return(regionID);
		}
					

	      if ( H5Tequal( dtype, H5T_NATIVE_SHORT) ||
		   H5Tequal( dtype, H5T_STD_I16BE) ||
		   H5Tequal( dtype, H5T_STD_I16LE) )
		tmp = 1;
	      else if ( H5Tequal(dtype, H5T_NATIVE_INT) ||
			H5Tequal(dtype, H5T_STD_I32BE) ||
			H5Tequal(dtype, H5T_STD_I32LE) )
		tmp = 2;
	      else if ( H5Tequal( dtype, H5T_NATIVE_FLOAT) ||
			H5Tequal( dtype, H5T_IEEE_F32BE) ||
			H5Tequal( dtype, H5T_IEEE_F32LE) )
		tmp = 3;
	      else if ( H5Tequal(dtype, H5T_NATIVE_DOUBLE) ||
			H5Tequal(dtype, H5T_IEEE_F64BE) ||
			H5Tequal(dtype, H5T_IEEE_F64LE) )
		tmp = 4;
					
	      status = H5Tclose(dtype);
	      if(status == FAIL)
		{
		  regionID = FAIL;
		  sprintf(errbuf, "Cannot release the data type ID.\n");
		  H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  free(errbuf);
		  free(vertArr);
		  free(nt);
						
		  return(regionID);
		}
					
 
	      switch (tmp )
		{
		case  1:

		  for (i = 0; i < dims[0]; i++)
		    {
		      memmove(&vertINT, vertArr + i * size, size);
						  
		      if (vertINT >= range[0] && vertINT <= range[1])
			{
			  found = 1;
			  if (regionID == FAIL)
			    {
			      HE5_SETGRIDREG;
			    }
			  HE5_FILLVERTREG;
								
			  break;
			}
		    }
						
		  if (found == 1)
		    {
		      for (i = dims[0] - 1; i >= 0; i--)
			{
			  memmove(&vertINT, vertArr + i * size, size);
								
			  if (vertINT >= range[0] && vertINT <= range[1])
			    {
			      HE5_GDXRegion[regionID]->StopVertical[j] = i;
			      break;
			    }
			}
		    }
		  else
		    {
		      regionID = FAIL;
		      sprintf(errbuf,"Data field not found.\n");
		      H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      free(errbuf);
		      free(vertArr);
		      free(nt);
							
		      return(regionID);
		    }
		  break;
						
						
		case 2:
						
		  for (i = 0; i < dims[0]; i++)
		    {
		      memmove(&vertSHORT, vertArr + i * size, size);
						  
		      if (vertSHORT >= range[0] && vertSHORT <= range[1])
			{
			  found = 1;
			  if (regionID == FAIL)
			    {
			      HE5_SETGRIDREG;
			    }
			  HE5_FILLVERTREG;
							  
			  break;
			}
		    }
						
		  if (found == 1)
		    {
		      for (i = dims[0] - 1; i >= 0; i--)
			{
			  memmove(&vertSHORT, vertArr + i * size, size);

			  if (vertSHORT >= range[0] && vertSHORT <= range[1])
			    {
			      HE5_GDXRegion[regionID]->StopVertical[j] = i;
			      break;
			    }
			}
		    }
		  else
		    {
		      status = FAIL;
		    }
		  break;

						
		case 3:
						
		  for (i = 0; i < dims[0]; i++)
		    {
		      memmove(&vertFLT, vertArr + i * size, size);
							
		      if (vertFLT >= range[0] && vertFLT <= range[1])
			{
			  found = 1;
			  if (regionID == FAIL)
			    {
			      HE5_SETGRIDREG;
			    }
			  HE5_FILLVERTREG;
								
			  break;
			}
		    }
						
		  if (found == 1)
		    {
		      for (i = dims[0] - 1; i >= 0; i--)
			{
			  memmove(&vertFLT, vertArr + i * size, size);
							  
			  if (vertFLT >= range[0] && vertFLT <= range[1])
			    {
			      HE5_GDXRegion[regionID]->StopVertical[j] = i;
			      break;
			    }
			}
		    }
		  else
		    {
		      regionID = FAIL;
		      sprintf(errbuf, "Data field not found.\n");
		      H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      free(errbuf);
		      free(vertArr);
		      free(nt);
						  
		      return(regionID);

		    }
		  break;
						

		case 4:
						
		  for (i = 0; i < dims[0]; i++)
		    {
		      memmove(&vertDBL, vertArr + i * size, size);
							
		      if (vertDBL >= range[0] && vertDBL <= range[1])
			{
			  found = 1;
			  if (regionID == FAIL)
			    {
			      HE5_SETGRIDREG;
			    }
			  HE5_FILLVERTREG;
								
			  break;
			}
		    }
						
		  if (found == 1)
		    {
		      for (i = dims[0] - 1; i >= 0; i--)
			{
			  memmove(&vertDBL, vertArr + i * size, size);
							  
			  if (vertDBL >= range[0] &&  vertDBL <= range[1])
			    {
			      HE5_GDXRegion[regionID]->StopVertical[j] = i;
			      break;
			    }
			}
		    }
		  else
		    {
		      regionID = FAIL;
		      sprintf(errbuf, "Data field not found.\n");
		      H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		      free(errbuf);
		      free(vertArr);
		      free(nt);
							
		      return(regionID);
		    }
		  break;
				

		default:
		  {
		    regionID = FAIL;
		    sprintf(errbuf, "Unknown Data type.\n");
		    H5Epush(__FILE__, "HE5_GDdefvrtregion", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
		    free(errbuf);
		    free(vertArr);
		    free(nt);
		  }
		  break;

		}
	      if (vertArr != NULL) free(vertArr);
	    }
	}
    }
	
	
  free(errbuf);
  errbuf = NULL;
  if (nt != NULL) free(nt);

 COMPLETION:
  HE5_UNLOCK;
  return (regionID);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeftimeperiod                                              |
|                                                                             |
|  DESCRIPTION: Finds elements of the "Time" field within a given time        |
|               period.                                                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  periodID       hid_t               Period ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  periodID       hid_t               Period ID                               |
|  starttime      double  TAI sec     Start of time period                    |
|  stoptime       double  TAI sec     Stop of time period                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/23/99  A.Muslimov    Changed the data type of periodID, gridID from      |
|                         int32_t| to hid_t.                                  |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
hid_t
HE5_GDdeftimeperiod(hid_t gridID, hid_t periodID, double starttime, double stoptime)
{
  double         timerange[2]={0.,0.};/* Range of periods */

  timerange[0] = starttime;
  timerange[1] = stoptime;

  periodID = HE5_GDdefvrtregion(gridID, periodID, "Time", timerange);

  return (periodID);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetpixels                                                  |
|                                                                             |
|  DESCRIPTION: Finds row and columns for specified lon/lat values            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  nLonLat        long                Number of lonlat values                 |
|  lonVal         double   dec deg    Longitude values                        |
|  latVal         double   dec deg    Latitude values                         |
|                                                                             |
|  OUTPUTS:                                                                   |
|  pixRow         long                Pixel rows                              |
|  pixCol         long                Pixel columns                           |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|                                                                             |
|    Date     Programmer   Description                                        |
|  ======   ============  =================================================   |
|  9/23/99  A.Muslimov    Added proper error handling after function calls.   |
|                         Removed redundant if(status==0){} brackets.         |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDgetpixels(hid_t gridID, long nLonLat, double lonVal[], double latVal[], long pixRow[], long pixCol[])
{
  herr_t          status     = FAIL;/* routine return status variable */

  int             projcode   = FAIL;/* GCTP projection code           */
  int             zonecode   = FAIL;/* Zone code                      */
  int             spherecode = FAIL;/* Sphere code                    */
  int             origincode = FAIL;/* Origin code                    */
  int             pixregcode = FAIL;/* Pixel registration code        */

  hid_t           fid        = FAIL;/* HDF-EOS file ID                */
  hid_t           gid        = FAIL;/* "HDFEOS" group ID              */

  long            i;		    /* Loop index                     */
  long            idx        = FAIL;/* Grid index                     */
  long            xdimsize   =  0;/* Size of "XDim"                   */
  long            ydimsize   =  0;/* Size of "YDim"                   */

  double          upleftpt[2]={0.,0.};  /* Upper left point           */
  double          lowrightpt[2]={0.,0.};/* Lower right point          */
  double          projparm[16];        /* Projection parameters       */
  double          *xVal=(double *)NULL;/* Ptr to x location values    */
  double          *yVal=(double *)NULL;/* Ptr to y location values    */

  char            *errbuf;	    /* buffer for error message           */

  CHECKPOINTER(lonVal);
  CHECKPOINTER(latVal);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

   
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgetpixels", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n" );	
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(status);
    }

	
  /* Get grid info */
  /* ------------- */
  status = HE5_GDgridinfo(gridID, &xdimsize, &ydimsize, upleftpt, lowrightpt);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Cannot get information about Grid.\n");
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	  
      return(status);
    }

  /* Initialize projparm[] array */
  /* --------------------------- */
  for (i = 0; i < 16; i++)
    projparm[i] = 0.;
	

  /* Get projection info */
  /* ------------------- */
  status = HE5_GDprojinfo(gridID, &projcode, &zonecode, &spherecode, projparm);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot get projection information.\n");   
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(status);
    }
	
  /* Get explicit upleftpt & lowrightpt if defaults are used */
  /* ------------------------------------------------------- */
  status = HE5_GDgetdefaults(projcode, zonecode, projparm, spherecode, upleftpt, lowrightpt);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot get explicit upleftpt and lowrghtpt values.\n");
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(status);
    }
	
  /* Get pixel registration and origin info */
  /* -------------------------------------- */
  status = HE5_GDorigininfo(gridID, &origincode);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Cannot get pixel registration information.\n");
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(status);
    }
	
  status = HE5_GDpixreginfo(gridID, &pixregcode);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Cannot get pixel origin information.\n");    
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(status);
    }

	
  /* Allocate space for x & y locations */
  /* ---------------------------------- */	
  xVal = (double *) calloc(nLonLat, sizeof(double));
  if(xVal == NULL)
    {
      status = FAIL;
      sprintf(errbuf, "Cannot allocate memory");
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	    
      return(status);
    }

  yVal = (double *) calloc(nLonLat, sizeof(double));
  if(yVal == NULL)
    {
      status = FAIL;
      sprintf(errbuf,"Cannot allocate memory");
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(xVal);
	    
      return(status);
    }
	
	
  /* Get pixRow, pixCol, xVal, & yVal */
  /* -------------------------------- */
  status = HE5_GDll2ij(projcode, zonecode, projparm, spherecode, xdimsize, ydimsize, upleftpt, lowrightpt, nLonLat, lonVal, latVal, pixRow, pixCol, xVal, yVal);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot get pixRow, pixCol, xVal, and yVal.\n");
      H5Epush(__FILE__, "HE5_GDgetpixels", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(xVal);
      free(yVal);
	
      return(status);
    }

	
  /* Loop through all lon/lat values */
  /* ------------------------------- */
  for (i = 0; i < nLonLat; i++)
    {
      /* Adjust columns & rows for "corner" registered grids */
      /* --------------------------------------------------- */
      if (pixregcode == HE5_HDFE_CORNER)
	{
	  if (origincode == HE5_HDFE_GD_UL)
	    {
	      if (xVal[i] - pixCol[i] > 0.5)
		{
		  ++pixCol[i];
		}
				
	      if (yVal[i] - pixRow[i] > 0.5)
		{
		  ++pixRow[i];
		}
	    }
	  else if (origincode == HE5_HDFE_GD_UR)
	    {
	      if (xVal[i] - pixCol[i] <= 0.5)
		{
		  --pixCol[i];
		}
				  
	      if (yVal[i] - pixRow[i] > 0.5)
		{
		  ++pixRow[i];
		}
	    }
	  else if (origincode == HE5_HDFE_GD_LL)
	    {
	      if (xVal[i] - pixCol[i] > 0.5)
		{
		  ++pixCol[i];
		}
				
	      if (yVal[i] - pixRow[i] <= 0.5)
		{
		  --pixRow[i];
		}
	    }
	  else if (origincode == HE5_HDFE_GD_LR)
	    {
	      if (xVal[i] - pixCol[i] <= 0.5)
		{
		  --pixCol[i];
		}
	      if (yVal[i] - pixRow[i] <= 0.5)
		{
		  --pixRow[i];
		}
	    }
	}
		

      /* If outidxe grid boundaries then set to FAIL */
      /* ------------------------------------------- */
      if (pixCol[i] < 0 || pixCol[i] >= xdimsize || pixRow[i] < 0 || pixRow[i] >= ydimsize)
	{
	  pixCol[i] = FAIL;
	  pixRow[i] = FAIL;
	}
    }

  if (xVal != NULL) free(xVal);
  if (yVal != NULL) free(yVal);
  free(errbuf);
  errbuf = NULL;

   
 COMPLETION:
  return (status);
}





/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetpixvalues                                               |
|                                                                             |
|  DESCRIPTION: Retrieves data from specified pixels.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  size*nPixels   long      bytes     Size of data buffer                     |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  nPixels        long                Number of pixels                        |
|  pixRow         long                Pixel row numbers                       |
|  pixCol         long                Pixel column numbers                    |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                Data buffer                             |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|              H5Screate_simple                                               |
|              H5Dget_space                                                   |
|              H5Dget_type                                                    |
|              H5Sselect_elements                                             |
|              H5Dread                                                        |
|              H5Tclose                                                       |
|              H5Sclose                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 98   Abe Taaheri   revised to reduce overhead for rechecking           |
|                         for gridid, fieldname, etc in GDreadfield.          |
|  June 98  AT            fixed bug with 2-dim field merged in 3-dim field    |
|                         (for offset and count)                              |
|  9/23/99  A.Muslimov    Added proper error handling after function calls.   |
|                         Removed redundant if(status==0){} brackets. Dynami- |
|                         cally allocated memory for dimlist, ntype, and      |
|                         errbuf strings.                                     |
|  12/7/99  A.Muslimov    Modified a block that reads out the pixel values    |
|                         from the dataset. This fixes a bug resulted in      |
|                         a failure of getting the pixel values.              |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  7/17/00  A.Muslimov    Added EHdtype2mtype() before the call to H5Dread(). |  
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDgetpixvalues(hid_t gridID, long nPixels, long pixRow[], long pixCol[], const char *fieldname, void *buffer)
{

  herr_t            status     = FAIL;           /* routine return status variable */

  int               j;                           /* Loop indices                   */
  int               rank       = FAIL;           /* Field rank                     */
  int               mrank      =  1;             /* Rank of dataspace in memory    */
  int               origincode = FAIL;           /* Origin code                    */

  hid_t             *ntype = (hid_t *)NULL;      /* number types                   */
  
  hid_t             fid    = FAIL;               /* HDF-EOS file ID                */
  hid_t             gid    = FAIL;               /* "HDFEOS" group ID              */
  hid_t             dataID = FAIL;               /* dataset ID                     */           
  hid_t             dtype  = FAIL;               /* data type ID                   */
  hid_t             mtype  = FAIL;               /* memory data type ID            */
  hid_t             fspace = FAIL;               /* file data space ID             */
  hid_t             mspace = FAIL;               /* memory data space ID           */   
  
  long              i;                           /* loop index                     */
  long              idx    = FAIL;               /* Grid index                     */
  long              xdim   = FAIL;               /* Location of "XDim" within field list */
  long              ydim   = FAIL;               /* Location of "YDim" within field list */
  
  hssize_t          *coord;                      /* Array of pixel coordinates           */
  
  hsize_t           dims[HE5_DTSETRANKMAX];      /* Field dimensions                     */
  hsize_t           mdims[1] = {0};              /* Dimension of dataspace in memory     */
  
  size_t            npoints = 0;                 /* Number of points/pixels to read      */
  size_t            size    = 0;                 /* Size of data buffer (bytes)          */

  char              *dimlist=(char *)NULL;       /* Dimension list string                */
  char              *errbuf = (char *)NULL;      /* buffer for error message             */	
  
  CHECKPOINTER(fieldname);
  CHECKPOINTER(pixRow);
  CHECKPOINTER(pixCol);

  
  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
    
  
  /* Initialize dims[] array */
  /* ----------------------- */
  for ( j = 0; j < HE5_DTSETRANKMAX; j++)
    dims[j] = 0;
  
  dimlist = (char *)calloc( HE5_HDFE_DIMBUFSIZE, sizeof(char ));
  if ( dimlist == NULL )
    {
      sprintf(errbuf,"Cannot allocate memory for dimension list string.\n");
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return(FAIL);
    }
  
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgetpixvalues", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
		
      return(FAIL);
    }
  
  
  /* Get field list */
  /* -------------- */
  ntype = (hid_t *)calloc(1, sizeof(hid_t));
  if ( ntype == (hid_t *)NULL )
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);

      return(FAIL);
    }

  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, dimlist, NULL);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Fieldname \"%s\" not found.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);

      return(FAIL);
    }
  
  
  /* Check for "XDim" & "YDim" in dimension list */
  /* ------------------------------------------- */
  xdim = HE5_EHstrwithin("XDim", dimlist, ',');
  if (xdim == FAIL)
    {
      sprintf( errbuf,"\"XDim\" not present in dimlist for field \"%s\".\n",fieldname);
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);
		
      return(FAIL);
    }
  
  ydim = HE5_EHstrwithin("YDim", dimlist, ',');	
  if (ydim == FAIL)
    {
      sprintf( errbuf,"\"YDim\" not present in dimlist for field \"%s\".\n",fieldname);
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);
		
      return(FAIL);
    }
  
  
  /* Get origin order info */
  /* --------------------- */
  status = HE5_GDorigininfo(gridID, &origincode);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Cannot get origin order information.\n");
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);

      return(FAIL);
    }
  
  /* Compute size of data buffer for each pixel */
  /* ------------------------------------------ */
  size = (size_t)dims[ 0 ];	
  for (j = 1; j < rank; j++)
    size *= dims[ j ];
  
  /* Calculate size of a whole data buffer */
  /* ------------------------------------- */
  size *= HE5_GDfielddatasize(gridID,fieldname);
  if (size == 0)
    {
      sprintf(errbuf,"Cannot get the field data size.\n");
      H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);
		
      return(FAIL);
    }
  
  
  
  /* If data values are requested ... */
  /* -------------------------------- */
  if (buffer != NULL)
    {
      status = HE5_GDgetfieldID( gridID, fieldname, &dataID);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot get data field ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
	  return(FAIL);
	}
		
		
      mdims[0] = (hsize_t)nPixels;
      npoints  = (size_t)nPixels;
	
      /* Create a data space in memory */
      /* ----------------------------- */ 		
      mspace = H5Screate_simple(mrank, (const hsize_t *)mdims, NULL);
      if ( mspace == FAIL )
	{
	  sprintf(errbuf,"Cannot create the data space.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATASPACE, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
	  return(FAIL);
	}
		
      /* Allocate memory for pixel coordinates array */
      /* ------------------------------------------- */
      coord = (hssize_t *)calloc((unsigned)(rank * nPixels), sizeof(hssize_t)); 
      if ( coord == (hssize_t *)NULL )
	{
	  sprintf(errbuf,"Cannot allocate memory for pixel coordinates array.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
	  return(FAIL);
	}
		
      /* Loop through all pixels */
      /* ----------------------- */
      for (i = 0; i < nPixels; i++)
	{
			
	  /* If pixel row & column OK ... */
	  /* ---------------------------- */
	  if (pixCol[i] != FAIL && pixRow[i] != FAIL)
	    {
	      /* Fill out the array of pixel coordinates */
	      /* --------------------------------------- */
	      coord[2 * i]     = (hssize_t)pixRow[i];
	      coord[2 * i + 1] = (hssize_t)pixCol[i];
	    }
	}
		
      fspace = H5Dget_space(dataID);
      if ( fspace == FAIL)
	{
	  sprintf(errbuf,"Cannot get the file data space ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);
			  
	  return(FAIL);
	}
		
		
      dtype = H5Dget_type(dataID);
      if ( dtype == FAIL )
	{
	  sprintf(errbuf,"Cannot get the datatype ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATATYPE, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);

	  return(FAIL);
	}

		
      /* Select the points/pixels to read */
      /* -------------------------------- */  
      status = H5Sselect_elements(fspace, H5S_SELECT_SET, npoints, (const hsize_t *)coord);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot select the pixels to read.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);

	  return(FAIL);
	}		

      /* Get the memory data type ID */
      /* --------------------------- */
      mtype = HE5_EHdtype2mtype(dtype);
      if ( mtype == FAIL )
	{
	  sprintf(errbuf,"Cannot get the memory data type.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);
			
	  return(FAIL);
	}

      /* Read the selected points into the buffer */
      /* ---------------------------------------  */
      status = H5Dread(dataID, mtype, mspace, fspace, H5P_DEFAULT, buffer);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot read out the data from the dataset.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);
			
	  return(FAIL);
	}
		
		
      status = H5Tclose(dtype);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot release the datatype ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATATYPE, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);
			
	  return(FAIL);
	}
		
      status = H5Sclose(mspace);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot release the memory data space ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);
			
	  return(FAIL);
	}
		
      status = H5Sclose(fspace);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot release the file data space ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetpixvalues", __LINE__, H5E_DATASPACE, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
	  free(coord);
			
			
	  return(FAIL);
	}
		
      free(coord);
		
		
    }
  
  
  /* If successful return size of returned data in bytes */
  /* --------------------------------------------------- */
  if (dimlist != NULL) free(dimlist);
  
  free(errbuf);
  free(ntype);

 COMPLETION:
  return( (long)(size * nPixels) );
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinterpolate                                                |
|                                                                             |
|  DESCRIPTION: Performs bilinear interpolate on a set of xy values           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nRetn*nValues*  long                Size of data buffer (bytes)            |
|  sizeof(double)                                                             |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  nValues        long                Number of lon/lat points to interpolate |
|  xyValues       double              XY values of points to interpolate      |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  interpVal      double              Interpolated Data Values                |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dget_type                                                     |
|             H5Tequal                                                        |
|             H5Tclose                                                        |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 98   Abe Taaheri   changed the return value so that the Return Value   |
|                         is size in bytes for the data buffer which is       |
|                         float64.                                            |
|  8/24/99  A.Muslimov    Changed the return type from intn to int   .        |
|  9/23/99  A.Muslimov    Added proper error handling after function calls.   |
|                         Removed redundant if(status==0){} brackets.         |
|  10/18/99 A.Muslimov    Replace memcpy() by memmove() to avoid a problem    |
|                         when arguments 1 and 2 overlap in memory.           |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Mar  04  S.Zhao        Modified for supported field type.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinterpolate(hid_t gridID, long nValues, double lonVal[], double latVal[], const char *fieldname, double interpVal[])
{
  long              nRetn       =  0;  /* Number of data values returned */
  long              i, j;              /* loop indices                   */
  long              idx         = FAIL;/* Grid index                     */
  long              xdimsize    =  0;  /* XDim size                      */
  long              ydimsize    =  0;  /* YDim size                      */
  long              numsize     =  0;  /* Size in bytes of number type   */
  long              xdim        = FAIL;/* Location of "XDim" in a list   */
  long              ydim        = FAIL;/* Location of "YDim" in a list   */
  long              dum         =  0;  /* Dummy variable                 */
  long              size        =  0;  /* Size of buffer in bytes        */
  long              pixCol[4];  /* Pixel columns for 4 nearest neighbors */
  long              pixRow[4];  /* Pixel rows for 4 nearest neighbors    */
  long              tDen        =  0;/*Interpolation denominator value 1 */
  long              uDen        =  0;/*Interpolation denominator value 2 */
  
  herr_t            status = FAIL;   /* routine return status variable   */

  int               k;               /* Loop indices                     */
  int               rank = FAIL;     /* Field rank                       */
  int               iINT[4]={0,0,0,0};/* Working buffer (int)            */
  int               tmp    = 999;    /* temp variable (for type code)    */
  int               projcode    = FAIL;/* Projection code                */
  int               zonecode    = FAIL;/* Zone code                      */
  int               spherecode  = FAIL;/* Sphere code                    */
  int               pixregcode  = FAIL;/* Pixel registration code        */
  int               origincode  = FAIL;/* Origin code                    */

  hid_t             *ntype = (hid_t *)NULL;      /*  number types        */

  hid_t             fid         = FAIL;/* HDF-EOS file ID                */
  hid_t             gid         = FAIL;/* "HDFEOS" group ID              */
  hid_t             dataID      = FAIL;/* data field dataset ID          */
  hid_t             dtype       = FAIL;/* data field datatype ID         */
  
  hsize_t           dims[HE5_DTSETRANKMAX];/* Field dimensions           */
  
  double            upleftpt[2]={0.,0.};  /* Upper left pt coordinates   */
  double            lowrightpt[2]={0.,0.};/* Lower right pt coordinates  */
  double            projparm[16];      /* Projection parameters          */
  double            xVal        = FAIL;/* "Exact" x location of interpolated point */
  double            yVal        = FAIL;/* "Exact" y location of interpolated point */
  double            tNum        =  0.; /* Interpolation numerator value 1          */
  double            uNum        =  0.; /* Interpolation numerator value 2          */
  double            fdbl[4]={0.,0.,0.,0.};/* Working buffer (double)               */
  
  short             ishort[4]={0,0,0,0};/* Working buffer (short)                  */
  
  float             flt[4]={0.,0.,0.,0.};/* Working buffer (float)                 */
  
  char              *pixVal  = NULL;    /* Nearest neighbor values                 */
  char              *dimlist = NULL;    /* Dimension list string                   */
  char              *errbuf  = NULL;    /* Error message buffer                    */
    
  CHECKPOINTER(fieldname);
  CHECKPOINTER(lonVal);
  CHECKPOINTER(latVal);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinterpolate", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }
  
  
  dimlist = (char *)calloc( HE5_HDFE_DIMBUFSIZE, sizeof(char ));
  if ( dimlist == NULL )
    {
      sprintf(errbuf,"Cannot allocate memory for dimension list string.\n");
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  
  
  /* Get field information */
  /* --------------------- */        
  ntype = (hid_t *)calloc(1, sizeof(hid_t));
  if ( ntype == (hid_t *)NULL )
    {
      sprintf(errbuf,"Cannot allocate memory for data type class ID.\n");
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
	    
      return(FAIL);
    }
      
  /* Initialize dims[] array */
  /* ----------------------- */
  for (k = 0; k < HE5_DTSETRANKMAX; k++)
    dims[ k ] = 0;

  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, dimlist,NULL);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Cannot get information about \"%s\" data field.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);
	    
      return(FAIL);
    }
  
  
  /* Check for "XDim" & "YDim" in dimension list */
  /* ------------------------------------------- */
  xdim = HE5_EHstrwithin("XDim", dimlist, ',');  
  if (xdim == FAIL)
    {
      sprintf( errbuf, "\"XDim\" not present in dimlist for field: \"%s\".\n", fieldname);
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);
				
      return(FAIL);
				
    }

  ydim = HE5_EHstrwithin("YDim", dimlist, ',');
  if (ydim == FAIL)
    {
      sprintf( errbuf,"\"YDim\" not present in dimlist for field: \"%s\".\n", fieldname);
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_BTREE, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);
		
		
      return(FAIL);
    }
  
  /* If no problems ... */
  /* ------------------ */
  
  /* Compute size of data buffer for each interpolated value */
  /* ------------------------------------------------------- */
  dims[xdim] = 1;
  dims[ydim] = 1;
  size       = (long)dims[0];
  
  for (k = 1; k < rank; k++)
    size *= (long)dims[ k ];
  
  numsize = (long)HE5_GDfielddatasize(gridID, fieldname);
  if ( numsize == 0 )
    {
      sprintf(errbuf,"Cannot get the size of data type.\n");
      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(ntype);

      return(FAIL);
    }
  
  size *= numsize;
  
  nRetn = size / numsize;
  
  /* If interpolated values are requested ... */
  /* ---------------------------------------- */
  if (interpVal != NULL)
    {
      /* Get grid info */
      /* ------------- */
      status = HE5_GDgridinfo(gridID, &xdimsize, &ydimsize,upleftpt, lowrightpt);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot get information about Grid.\n");
	  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
		  
	  return(FAIL);
	}

      /* Initialize projparm[] array */
      /* --------------------------- */
      for (k = 0; k < 16; k++)
	projparm[ k ] = 0.;
		
      /* Get projection info */
      /* ------------------- */
      status = HE5_GDprojinfo(gridID, &projcode, &zonecode,&spherecode, projparm);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot get projection information.\n");
	  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
	  return(FAIL);
	}
		
      /* Get explicit upleftpt & lowrightpt if defaults are used */
      /* ------------------------------------------------------- */
      status = HE5_GDgetdefaults(projcode, zonecode, projparm, spherecode, upleftpt, lowrightpt);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot get upleftpt and lowrightpt defaults.\n");
	  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
			
	  return(FAIL);
	}
		
      /* Get pixel registration and origin info */
      /* -------------------------------------- */
      status = HE5_GDpixreginfo(gridID, &pixregcode);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot get pixel registration information.\n");
	  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
	  return(FAIL);
	}
		
      status = HE5_GDorigininfo(gridID, &origincode);
      if ( status == FAIL )
	{
	  sprintf(errbuf,"Cannot get pixel origin information.\n");
	  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(ntype);
			
	  return(FAIL);
	}
		
		
      /* Loop through all interpolated points */
      /* ------------------------------------ */
      for (i = 0; i < nValues; i++)
	{
	  /* Get row & column of point pixel */
	  /* ------------------------------- */
	  status = HE5_GDll2ij(projcode, zonecode, projparm, spherecode,xdimsize, ydimsize, upleftpt, lowrightpt, 1, &lonVal[i], &latVal[i], pixRow, pixCol, &xVal, &yVal);
	  if ( status == FAIL )
	    {
	      sprintf(errbuf,"Cannot get row and column of point pixel.\n");
	      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(dimlist);
	      free(pixVal);
	      free(ntype);
				
	      return(FAIL);
	    }
			
			
	  /* Get diff of interp. point from pixel location */
	  /* --------------------------------------------- */
	  if (pixregcode == HE5_HDFE_CENTER)
	    {
	      tNum = xVal - (pixCol[0] + 0.5);
	      uNum = yVal - (pixRow[0] + 0.5);
	    }
	  else if (origincode == HE5_HDFE_GD_UL)
	    {
	      tNum = xVal - pixCol[0];
	      uNum = yVal - pixRow[0];
	    }
	  else if (origincode == HE5_HDFE_GD_UR)
	    {
	      tNum = xVal - (pixCol[0] + 1);
	      uNum = yVal - pixRow[0];
	    }
	  else if (origincode == HE5_HDFE_GD_LL)
	    {
	      tNum = xVal - pixCol[0];
	      uNum = yVal - (pixRow[0] + 1);
	    }
	  else if (origincode == HE5_HDFE_GD_LR)
	    {
	      tNum = xVal - (pixCol[0] + 1);
	      uNum = yVal - (pixRow[0] + 1);
	    }
			
			
	  /* Get rows and columns of other nearest neighbor pixels */
	  /* ----------------------------------------------------- */
	  pixCol[1] = pixCol[0];
	  pixRow[3] = pixRow[0];
			
	  if (tNum >= 0)
	    {
	      pixCol[2] = pixCol[0] + 1;
	      pixCol[3] = pixCol[0] + 1;
	    }
			
	  if (tNum < 0)
	    {
	      pixCol[2] = pixCol[0] - 1;
	      pixCol[3] = pixCol[0] - 1;
	    }
			
	  if (uNum >= 0)
	    {
	      pixRow[2] = pixRow[0] + 1;
	      pixRow[1] = pixRow[0] + 1;
	    }
			
	  if (uNum < 0)
	    {
	      pixRow[2] = pixRow[0] - 1;
	      pixRow[1] = pixRow[0] - 1;
	    }
			
			
			
	  /* Get values of nearest neighbors  */
	  /* -------------------------------- */
	  pixVal = (char *)calloc( 4 , size);
	  if(pixVal == NULL)
	    {
	      sprintf(errbuf,"Cannot allocate memory"); 
	      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      free(errbuf);
	      free(dimlist);
	      free(ntype);
				
	      return(FAIL);
	    }
			
	  dum = HE5_GDgetpixvalues(gridID,4,pixRow,pixCol,fieldname,pixVal);
			
			
	  /* Trap interpolation boundary out of range error */
	  /* ---------------------------------------------- */
	  if (dum == FAIL)
	    {
	      sprintf(errbuf, "Interpolation boundary out of grid.\n");
	      H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(dimlist);
	      free(pixVal);
	      free(ntype);
				
	      return(FAIL);
				
	    }
	  else
	    {
				
	      /*
	       * Algorithm taken for Numerical Recipies in C, 2nd
	       * edition, Section 3.6
	       */
				
	      /* Perform bilinear interpolation */
	      /* ------------------------------ */
	      tDen = pixCol[3] - pixCol[0];
	      uDen = pixRow[1] - pixRow[0];
				
	      status = HE5_GDgetfieldID( gridID, fieldname, &dataID);
	      if ( status == FAIL )
		{
		  sprintf(errbuf,"Cannot get \"%s\" field ID.\n", fieldname);
		  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(dimlist);
		  free(pixVal);
		  free(ntype);
					
		  return(FAIL);
		}
				
	      dtype = H5Dget_type( dataID);
	      if ( status == FAIL )
		{
		  sprintf(errbuf,"Cannot get the dataset datatype.\n");
		  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(dimlist);
		  free(pixVal);
		  free(ntype);
					
		  return(FAIL);
		}
				
				
	      if ( H5Tequal( dtype, H5T_NATIVE_SHORT) ||
		   H5Tequal( dtype, H5T_STD_I16BE) ||
		   H5Tequal( dtype, H5T_STD_I16LE) )
		tmp = 1;
	      else if ( H5Tequal(dtype, H5T_NATIVE_INT) ||
			H5Tequal(dtype, H5T_STD_I32BE) ||
			H5Tequal(dtype, H5T_STD_I32LE) )
		tmp = 2;
	      else if ( H5Tequal(dtype, H5T_NATIVE_FLOAT) ||
			H5Tequal( dtype, H5T_IEEE_F32BE) ||
			H5Tequal( dtype, H5T_IEEE_F32LE) )
		tmp = 3;
	      else if ( H5Tequal( dtype, H5T_NATIVE_DOUBLE) ||
			H5Tequal(dtype, H5T_IEEE_F64BE) ||
			H5Tequal(dtype, H5T_IEEE_F64LE) )
		tmp = 4;
				
	      status = H5Tclose(dtype);
	      if ( status == FAIL )
		{
		  sprintf(errbuf,"Cannot release the datatype ID.\n");
		  H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(errbuf);
		  free(dimlist);
		  free(pixVal);
		  free(ntype);
					
		  return(FAIL);
		}
				
				
	      switch ( tmp)
		{
		case 1:
					
					
		  /* Loop through all returned data values */
		  /* ------------------------------------- */
		  for (j = 0; j < nRetn; j++)
		    {
		      /* Copy 4 NN values into working array */
		      /* ----------------------------------- */
		      for (k = 0; k < 4; k++)
			{
			  memmove(&ishort[k],pixVal + j * numsize + k * size, sizeof(short));
			}
						
		      /* Compute interpolated value */
		      /* -------------------------- */
		      interpVal[i * nRetn + j] =
			(1 - tNum / tDen) * (1 - uNum / uDen) *
			ishort[0] +
			(tNum / tDen) * (1 - uNum / uDen) *
			ishort[3] +
			(tNum / tDen) * (uNum / uDen) *
			ishort[2] +
			(1 - tNum / tDen) * (uNum / uDen) *
			ishort[1];
		    }
		  break;
					
					
		case 2:
					
		  for (j = 0; j < nRetn; j++)
		    {
		      for (k = 0; k < 4; k++)
			{
			  memmove(&iINT[k], pixVal + j * numsize + k * size, sizeof(int));
			}
						
		      interpVal[i * nRetn + j] =
			(1 - tNum / tDen) * (1 - uNum / uDen) *
			iINT[0] +
			(tNum / tDen) * (1 - uNum / uDen) *
			iINT[3] +
			(tNum / tDen) * (uNum / uDen) *
			iINT[2] +
			(1 - tNum / tDen) * (uNum / uDen) *
			iINT[1];
		    }
		  break;
					
					
		case  3:
					
		  for (j = 0; j < nRetn; j++)
		    {
		      for (k = 0; k < 4; k++)
			{
			  memmove(&flt[k], pixVal + j * numsize + k * size, sizeof(float));
			}

		      interpVal[i * nRetn + j] =
			(1 - tNum / tDen) * (1 - uNum / uDen) *
			flt[0] +
			(tNum / tDen) * (1 - uNum / uDen) *
			flt[3] +
			(tNum / tDen) * (uNum / uDen) *
			flt[2] +
			(1 - tNum / tDen) * (uNum / uDen) *
			flt[1];
		    }
		  break;


		case  4:

		  for (j = 0; j < nRetn; j++)
		    {
		      for (k = 0; k < 4; k++)
			{
			  memmove(&fdbl[k], pixVal + j * numsize + k * size, sizeof(double));
			}

		      interpVal[i * nRetn + j] =
			(1 - tNum / tDen) * (1 - uNum / uDen) *
			fdbl[0] +
			(tNum / tDen) * (1 - uNum / uDen) *
			fdbl[3] +
			(tNum / tDen) * (uNum / uDen) *
			fdbl[2] +
			(1 - tNum / tDen) * (uNum / uDen) *
			fdbl[1];
		    }
		  break;

		default:
		  {
		    sprintf(errbuf,"Unknown data type.\n");
		    H5Epush(__FILE__, "HE5_GDinterpolate", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
		    HE5_EHprint(errbuf, __FILE__, __LINE__);
		    free(errbuf);
		    free(dimlist);
		    free(pixVal);
		    free(ntype);
					
		    return(FAIL);
		  }
				  
		}         
	    }             
	  free(pixVal);
	  pixVal  = NULL;
	}
                
    }                    
  
  free(dimlist);
  free(errbuf);
  errbuf  = NULL;    
  free(ntype);
  dimlist = NULL;
  
  
 COMPLETION:
  /* always return size of double buffer */
  return ( (long)(nRetn*nValues*sizeof(double)) );	
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwritelocattr                                               |
|                                                                             |
|  DESCRIPTION: Writes/updates attribute associated with a specified field in |
|                a grid.                                                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|  numtype        hid_t               attribute datatype ID                   |
|  count[]        hsize_t             Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 00   A.Muslimov    Original development.                               |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t    
HE5_GDwritelocattr(hid_t gridID, const char *fieldname, const char *attrname, hid_t numtype, hsize_t  count[],  void *datbuf)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
     
  long       idx           = FAIL;/* Grid index                     */

  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */
  hid_t      ntype;

  HE5_LOCK;
  CHECKPOINTER(fieldname);
  CHECKNAME(attrname);
  CHECKPOINTER(count);
  CHECKPOINTER(datbuf);

  /* 
     if numtype is HE5 numbertype, rather than H5 numbertype, then convert
     it, otherwise use ntype itself
  */
  ntype = HE5_EHconvdatatype(numtype);
  if(ntype == FAIL)
    {
      ntype = numtype;
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDwritelocattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
		
      /* Get field ID */
      /* ------------ */
      fieldID = H5Dopen(HE5_GDXGrid[idx].data_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDwritelocattr", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
		
      /* Call EHattr to perform I/O */
      /* -------------------------- */
      status = HE5_EHattr(fieldID, attrname, ntype, count,"w", datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot write Attribute \"%s\" for the \"%s\" field.\n", attrname, fieldname);
	  H5Epush(__FILE__, "HE5_GDwritelocattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
		
      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDwritelocattr", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	

    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreadlocattr                                                |
|                                                                             |
|  DESCRIPTION: Reads attribute associated with a specified field from a grid.|
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char                field name                              |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 00   A.Muslimov    Original development                                |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDreadlocattr(hid_t gridID, const char *fieldname, const char *attrname, void *datbuf)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      ntype         = FAIL;/* hdf5 type data type ID         */
  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
     
  long       idx           = FAIL;/* Grid index                     */
     
  hsize_t    count[]={0};	   /* array with the number of elements */

  char       errbuf[HE5_HDFE_ERRBUFSIZE]; /* Error message buffer   */


  HE5_LOCK;
  CHECKPOINTER(fieldname);
  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDreadattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get field ID */
      /* ------------ */
      fieldID = H5Dopen(HE5_GDXGrid[idx].data_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDreadlocattr", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
		
      /* Call EHattr to perform I/O */
      /* -------------------------- */
      status = HE5_EHattr(fieldID, attrname, ntype, count, "r", datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot read Attribute \"%s\" associated wth the \"%s\" field.\n", attrname,fieldname);
	  H5Epush(__FILE__, "HE5_GDreadlocattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
        
      /* Release dataset ID */
      /* ------------------ */
      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDreadlocattr", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	

		
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDlocattrinfo                                                |
|                                                                             |
|  DESCRIPTION: Retrieves information about local attribute (attribute asso-  |
|                ciated with a specified field) in a grid.                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               attribute data type ID                  |
|  count          hsize_t             Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 00   A.Muslimov    Original Development                                |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Feb 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDlocattrinfo(hid_t gridID, const char *fieldname, const char *attrname, hid_t *ntype, hsize_t *count)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
     
  long       idx           = FAIL;/* Grid index                     */

  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */

  CHECKPOINTER(fieldname);
  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDlocattrinfo", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get field ID */
      /* ------------ */
      fieldID = H5Dopen(HE5_GDXGrid[idx].data_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDlocattrinfo", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}

      /* Call EHattrinfo */
      /* --------------- */
      status = HE5_EHattrinfo(fieldID, attrname, ntype, count);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot retrieve information about Attribute \"%s\" associated with the \"%s\" field.\n", attrname, fieldname);
	  H5Epush(__FILE__, "HE5_GDlocattrinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
	  
      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDlocattrinfo", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	
    }

 COMPLETION:
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDlocattrinfo2                                               |
|                                                                             |
|  DESCRIPTION: Retrieves information about local attribute (attribute asso-  |
|                ciated with a specified field) in a grid.                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               attribute data type ID                  |
|  count          hsize_t *           Number of attribute elements            |
|  size           hsize_t *           buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 00   A.Muslimov    Original Development                                |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Feb 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t 
HE5_GDlocattrinfo2(hid_t gridID, const char *fieldname, const char *attrname, hid_t *ntype, hsize_t *count, hsize_t *size)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      fieldID       = FAIL;/* Field-related dataset ID       */
     
  long       idx           = FAIL;/* Grid index                     */

  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */

  CHECKPOINTER(fieldname);
  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDlocattrinfo2", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get field ID */
      /* ------------ */
      fieldID = H5Dopen(HE5_GDXGrid[idx].data_id, fieldname);
      if(fieldID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDlocattrinfo2", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}

      /* Call EHattrinfo */
      /* --------------- */
      status = HE5_EHattrinfo2(fieldID, attrname, ntype, count, size);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot retrieve information about Attribute \"%s\" associated with the \"%s\" field.\n", attrname, fieldname);
	  H5Epush(__FILE__, "HE5_GDlocattrinfo2", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
	  
      status = H5Dclose(fieldID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"%s\" field dataset ID.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDlocattrinfo2", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	
    }

 COMPLETION:
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqdscaleattrs                                             |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of attributes and string length of      |
|                attribute list associated with a specified dimension scale   |
|                in a grid.                                                   |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char                dimension scale name                    |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  June 10   Abe Taaheri  Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqdscaleattrs(hid_t gridID, const char *fieldname, char *attrnames, long *strbufsize)
{
  long       nattr         =  0;  /* Number of attributes (return)  */
  long       idx           = FAIL;/* Grid index                     */    
  
  herr_t     status        = FAIL;/* routine return status variable */
  
  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  
  char       *dtsname      = NULL;/* Buffer for dataset name        */
  char       errbuf[HE5_HDFE_ERRBUFSIZE];
  
  CHECKPOINTER(fieldname);
  
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqdscaleattrs", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n" );
      H5Epush(__FILE__, "HE5_GDinqdscaleattrs", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  dtsname = (char *) calloc(HE5_HDFE_NAMBUFSIZE, 1);
  if( dtsname == NULL)
    {
      sprintf(errbuf, "Can not allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDinqdscaleattrs", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
	
  strcpy(dtsname,"/HDFEOS/GRIDS/");
  strcat(dtsname, HE5_GDXGrid[idx].gdname);
  strcat(dtsname,"/");
  strcat(dtsname,fieldname);

  nattr = HE5_EHattrcat(fid, dtsname, attrnames, strbufsize);
	
  if (dtsname != NULL) free(dtsname);
    
 COMPLETION:
  return(nattr);
	
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqlocattrs                                                |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of attributes and string length of      |
|                attribute list associated with a specified field in a grid.  |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char                field name                              |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 00   A.Muslimov    Original development.                               |
|  Mar 00   A.Muslimov    Changed the field group to "Data Fields".           |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqlocattrs(hid_t gridID, const char *fieldname, char *attrnames, long *strbufsize)
{
  long       nattr         =  0;  /* Number of attributes (return)  */
  long       idx           = FAIL;/* Grid index                     */    

  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
     
  char       *dtsname      = NULL;/* Buffer for dataset name        */
  /*  char       *errbuf       = NULL;*//* Buffer for error message       */
					char       errbuf[HE5_HDFE_ERRBUFSIZE];
 
  CHECKPOINTER(fieldname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  /*
    errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
    if(errbuf == NULL)
    {
    H5Epush(__FILE__, "HE5_GDinqlocattrs", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
    HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
    return(FAIL);
    }
  */

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqlocattrs", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n" );
      H5Epush(__FILE__, "HE5_GDinqlocattrs", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
	  
      return(FAIL);
    }

  dtsname = (char *) calloc(HE5_HDFE_NAMBUFSIZE, 1);
  if( dtsname == NULL)
    {
      sprintf(errbuf, "Can not allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDinqlocattrs", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
	  
      return(FAIL);
    }
	
  strcpy(dtsname,"/HDFEOS/GRIDS/");
  strcat(dtsname, HE5_GDXGrid[idx].gdname);
  strcat(dtsname,"/Data Fields/");
  strcat(dtsname,fieldname);

  nattr = HE5_EHattrcat(fid, dtsname, attrnames, strbufsize);
	
  if (dtsname != NULL) free(dtsname);
    
 COMPLETION:
  return(nattr);
	
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwritegrpattr                                               |
|                                                                             |
|  DESCRIPTION: Writes/updates attribute associated with "Data Fields" group  |
|               in a grid.                                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char*               attribute name                          |
|  numtype        hid_t               attribute data type ID                  |
|  count[]        hsize_t             Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 00   A.Muslimov    Original development.                               |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDwritegrpattr(hid_t gridID, const char *attrname, hid_t numtype, hsize_t  count[], void *datbuf)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      dataID        = FAIL;/* "Data Fields" group ID         */     
     
  long       idx           = FAIL;/* Grid index                     */
 	
  char       errbuf[HE5_HDFE_ERRBUFSIZE];/*  Error message buffer   */
  hid_t      ntype;

  HE5_LOCK;
  CHECKNAME(attrname);
  CHECKPOINTER(count);
  CHECKPOINTER(datbuf);

  /* 
     if numtype is HE5 numbertype, rather than H5 numbertype, then convert
     it, otherwise use ntype itself
  */
  ntype = HE5_EHconvdatatype(numtype);
  if(ntype == FAIL)
    {
      ntype = numtype;
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDwritegrpattr", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
	  
      /* Get "Data Fields" group ID */
      /* -------------------------- */
      dataID = H5Gopen(HE5_GDXGrid[idx].gd_id,"Data Fields");
      if(dataID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"Data Fields\" group.\n");
	  H5Epush(__FILE__, "HE5_GDwritegrpattr", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
		
      /* Call EHattr to perform I/O */
      /* -------------------------- */
      status = HE5_EHattr(dataID, attrname, ntype, count,"w", datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot write Attribute \"%s\" for the \"Data Fields\" group.\n", attrname);
	  H5Epush(__FILE__, "HE5_GDwritegrpattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
	  
      /* Release group ID */
      /* ---------------- */
      status = H5Gclose(dataID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"Data Fields\" group ID.\n");
	  H5Epush(__FILE__, "HE5_GDwritegrpattr", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	
	  
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);  
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreadgrpattr                                                |
|                                                                             |
|  DESCRIPTION: Reads attribute associated with "Data Fields" group in a grid.|
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 00   A.Muslimov    Original development                                |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDreadgrpattr(hid_t gridID, const char *attrname, void *datbuf)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      ntype         = FAIL;/* hdf5 type data type ID         */
  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      dataID        = FAIL;/* "Data Fields" group ID         */     
     
  long       idx           = FAIL;/* Grid index                     */
     
  hsize_t    count[]={0};      /* array with the number of elements */

  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */

  HE5_LOCK;
  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDreadgrpattr", &fid, &gid, &idx);	
  if (status == SUCCEED)
    {
      /* Get "Data Fields"  group ID  */
      /* ---------------------------- */
      dataID = H5Gopen(HE5_GDXGrid[idx].gd_id, "Data Fields");
      if(dataID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"Data Fields\" group.\n");
	  H5Epush(__FILE__, "HE5_GDreadgrpattr", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
		
      /* Call HE5_EHattr to perform I/O */
      /* ------------------------------ */
      status = HE5_EHattr(dataID, attrname, ntype, count, "r", datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot read Attribute \"%s\" associated wth the \"Data Fields\" group.\n", attrname);
	  H5Epush(__FILE__, "HE5_GDreadgrpattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
	  
      /* Release group ID */
      /* ---------------- */
      status = H5Gclose(dataID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"Data Fields\" group ID.\n");
	  H5Epush(__FILE__, "HE5_GDreadgrpattr", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}	
	  
		
    }

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgrpattrinfo                                                |
|                                                                             |
|  DESCRIPTION: Retrieves information about group attribute (attribute asso-  |
|                ciated with "Data Fields" group) in a grid.                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               attribute data type ID                  |
|  count          hsize_t             Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 00   A.Muslimov    Original Development                                |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Feb 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDgrpattrinfo(hid_t gridID, const char *attrname, hid_t *ntype, hsize_t *count)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      dataID        = FAIL;/* "Data Fields" group ID         */     
     
  long       idx           = FAIL;/* Grid index                     */

  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */

  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgrpattrinfo", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get "Data Fields" group ID */
      /* -------------------------- */
      dataID = H5Gopen(HE5_GDXGrid[idx].gd_id, "Data Fields");
      if(dataID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"Data Fields\" group.\n");
	  H5Epush(__FILE__, "HE5_GDgrpattrinfo", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
	  
      /* Call HE5_EHattrinfo */
      /* ------------------- */
      status = HE5_EHattrinfo(dataID, attrname, ntype, count);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot retrieve information about Attribute \"%s\" associated with the \"Data Fields\" group.\n", attrname);
	  H5Epush(__FILE__, "HE5_GDgrpattrinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
	  
      /* Release group ID */
      /* ---------------- */
      status = H5Gclose(dataID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"Data Fields\" group ID.\n");
	  H5Epush(__FILE__, "HE5_GDgrpattrinfo", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}		
    }

 COMPLETION:
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgrpattrinfo2                                               |
|                                                                             |
|  DESCRIPTION: Retrieves information about group attribute (attribute asso-  |
|                ciated with "Data Fields" group) in a grid.                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          hid_t               attribute data type ID                  |
|  count          hsize_t *           Number of attribute elements            |
|  size           hsize_t *           buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 00   A.Muslimov    Original Development                                |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|  Feb 03   S.Zhao        Changed the type of 'ntype' from an H5T_class_t to  |
|                         an hid_t.                                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t  
HE5_GDgrpattrinfo2(hid_t gridID, const char *attrname, hid_t *ntype, hsize_t *count, hsize_t *size)
{
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  hid_t      dataID        = FAIL;/* "Data Fields" group ID         */     
     
  long       idx           = FAIL;/* Grid index                     */

  char       errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer    */

  CHECKPOINTER(attrname);

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgrpattrinfo2", &fid, &gid, &idx);
  if (status == SUCCEED)
    {
      /* Get "Data Fields" group ID */
      /* -------------------------- */
      dataID = H5Gopen(HE5_GDXGrid[idx].gd_id, "Data Fields");
      if(dataID == FAIL)
	{
	  sprintf(errbuf,"Cannot open the \"Data Fields\" group.\n");
	  H5Epush(__FILE__, "HE5_GDgrpattrinfo2", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
	  
      /* Call HE5_EHattrinfo */
      /* ------------------- */
      status = HE5_EHattrinfo2(dataID, attrname, ntype, count, size);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot retrieve information about Attribute \"%s\" associated with the \"Data Fields\" group.\n", attrname);
	  H5Epush(__FILE__, "HE5_GDgrpattrinfo2", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}
	  
      /* Release group ID */
      /* ---------------- */
      status = H5Gclose(dataID);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot release the \"Data Fields\" group ID.\n");
	  H5Epush(__FILE__, "HE5_GDgrpattrinfo2", __LINE__, H5E_DATASET, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(status);
	}		
    }

 COMPLETION:
  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqgrpattrs                                                |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of attributes and string length of      |
|                attribute list associated with "Data Fields" group in a grid.|
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Mar 00   A.Muslimov    Original development.                               |
|  7/12/00  A.Muslimov    Unmasked hdf5 data types.                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqgrpattrs(hid_t gridID, char *attrnames, long *strbufsize)
{
  long       nattr         =  0;  /* Number of attributes (return)  */
  long       idx           = FAIL;/* Grid index                     */    
  
  herr_t     status        = FAIL;/* routine return status variable */

  hid_t      fid           = FAIL;/* HDF-EOS file ID                */
  hid_t      gid           = FAIL;/* "HDFEOS" group ID              */
  
  char       *grpname      = NULL;/* Buffer for group  name         */
  char       *errbuf       = NULL;/* Buffer for error message       */
 

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqgrpattrs", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

	
  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDinqgrpattrs", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf,"Checking for grid ID failed.\n" );
      H5Epush(__FILE__, "HE5_GDinqgrpattrs", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	  
      return(FAIL);
    }
  
  /* Allocate memory for a group name buffer */
  /* --------------------------------------- */
  grpname = (char *) calloc(HE5_HDFE_NAMBUFSIZE, 1);
  if( grpname == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory.\n");
      H5Epush(__FILE__, "HE5_GDinqgrpattrs", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	  
      return(FAIL);
    }
  
  /* Construct group pathname string */
  /* ------------------------------- */
  strcpy(grpname,"/HDFEOS/GRIDS/");
  strcat(grpname, HE5_GDXGrid[idx].gdname);
  strcat(grpname,"/Data Fields");
  
  /* search group <grpname> for the number of attributes */
  /* --------------------------------------------------- */     
  nattr = HE5_EHattrcat(fid, grpname, attrnames, strbufsize);
	
  if (grpname != NULL) free(grpname);
    
  
  free(errbuf);
  errbuf = NULL;
  
  return (nattr);
	
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetextdata                                                 |
|                                                                             |
|  DESCRIPTION: Sets external data files.                                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid  structure ID                      |
|  filelist       const char*         list of external files                  |
|  offset         off_t               array of offsets (in bytes) from the    |
|                                     beginning of the file to the location   |
|                                     in the file where the data starts       |
|  size           hsize_t             array of sizes (in bytes) reserved in   |
|                                     the file for the data.                  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 01   A.Muslimov    Original development.                               |
| 09/13/01  A.Muslimov    Added mutex "lock"/"unlock" calls.                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t   
HE5_GDsetextdata(hid_t gridID, const char *filelist, off_t offset[], hsize_t size[])
{
  herr_t          status       = FAIL;        /* return status variable */

  int             i;                          /* Loop index             */

  hid_t           fid          = FAIL;        /* HDF-EOS file ID        */
  hid_t           gid          = FAIL;        /* "HDFEOS" group ID      */
  
  long            idx          = FAIL;        /* Grid   index           */
  
  char            *namebuf     = (char *)NULL;/* File list buffer       */
  char            *filename    = (char *)NULL;/* File name buffer       */
  char            *comma       = (char *)NULL;/* Pointer to comma       */
  char            *errbuf      = (char *)NULL;/* error message buffer   */

  HE5_LOCK;
  CHECKPOINTER(filelist);
  CHECKPOINTER(offset);
  CHECKPOINTER(size);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetextdata", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDsetextdata", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDsetextdata", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
		
      return( status );
    }


  /* Get current dataset creation property list */
  /* ------------------------------------------ */  
  if( HE5_GDXGrid[idx].plist == FAIL)
    HE5_GDXGrid[idx].plist = H5Pcreate(H5P_DATASET_CREATE);


  /* Allocate space for namebuf, copy dimlist into it, & append comma */
  /* ---------------------------------------------------------------- */
  namebuf = (char *)calloc(strlen(filelist) + 64, sizeof(char));
  if(namebuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetextdata", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory.");
      HE5_EHprint("Error: Cannot allocate memory, occured", __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  /*
********************************************************************
*   C H E C K  T H E   C O N T E N T   O F  filelist  S T R I N G  *   
********************************************************************
*/

  strcpy(namebuf, filelist);
  strcat(namebuf, ",");

  /* Find comma */
  /* ---------- */
  comma = strchr(namebuf, ',');
  
  i = 0;
  
  /* Parse the list of file names */
  /* ---------------------------- */
  while (comma != NULL)
    {
      /* Allocate memory for filename buffer */
      /* ----------------------------------- */
      filename = (char *) calloc(comma - namebuf + 1, sizeof(char));
      if (filename == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for filename. \n") ;
	  H5Epush(__FILE__, "HE5_GDsetextdata", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(namebuf);
	  return(FAIL);
	}
	  
      /* Copy file list entry to filename */
      /* -------------------------------- */
      memmove(filename, namebuf, comma - namebuf);
      filename[comma-namebuf] = 0;
	  
      /* Set the property list */
      /* --------------------- */
      status = H5Pset_external(HE5_GDXGrid[idx].plist, filename, offset[i], size[i]);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot set external dataset property list.\n");
	  H5Epush(__FILE__, "HE5_GDsetextdata", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(namebuf);
	  free(filename);
	  return(status);
	}
	  
	  
      /* Go to next file  entry, find next comma, ... */
      /* ============================================ */ 
      memmove(namebuf, comma + 1, strlen(comma + 1) + 1); 
      comma = strchr(namebuf, ',');
	  
      if (filename != NULL) free(filename);
	  
      i++;
    }
  
  if (namebuf != NULL) free(namebuf);
  free(errbuf);

 COMPLETION:
  HE5_UNLOCK;
  return (status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetextdata                                                 |
|                                                                             |
|  DESCRIPTION: Gets external data files information.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nfiles         int                 number of external files  SUCCEED,      |
|                                               (-1) FAIL                     |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fieldname      char*               External field name                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  namelength     size_t              Length of each name entry               |
|  filelist       char*               List of file names                      |
|  offset         off_t               array of offsets (in bytes) from the    |
|                                     beginning of the file to the location   |
|                                     in the file where the data starts       |
|  size           hsize_t             ARRAY of sizes (in bytes) reserved in   |
|                                     the file for the data.                  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 01   A.Muslimov    Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDgetextdata(hid_t gridID, char *fieldname, size_t namelength, char *filelist, off_t offset[], hsize_t size[])
{
  int             nfiles       = FAIL;        /* Number of ext. files   */
  int             i;                          /* Loop index             */
  int             found        = 0;	          /* found  flag            */

  size_t          slen         = 0;           /* String length          */

  herr_t          status       = FAIL;        /* return status variable */

  hid_t           fid          = FAIL;        /* HDF-EOS file ID        */
  hid_t           gid          = FAIL;        /* "HDFEOS" group ID      */
  hid_t           fieldID      = FAIL;        /* Data field ID          */
  hid_t           plist        = FAIL;        /* Property list ID       */

  off_t           off          = 0;           /* Offset of data segment */
 
  hsize_t         sz           = 0;           /* Size of data segment   */

  long            idx          = FAIL;        /* Grid index             */
  
  char            *filename    = (char *)NULL;/* File name buffer       */
  char            *errbuf      = (char *)NULL;/*error message buffer    */

  CHECKPOINTER(fieldname);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /*
**********************************************************
*  Check for proper grid ID and return HDF-EOS file ID,  * 
*        "HDFEOS" group ID and Grid index                *  
**********************************************************
*/
  status = HE5_GDchkgdid(gridID, "HE5_GDgetextdata", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }


  /* Loop through all data datasets in grid */
  /* -------------------------------------- */
  for (i = 0; i < HE5_GDXGrid[ idx ].nDFLD; i++)
    {
      /* Get dataset name */
      /* ---------------- */
      if( strcmp(fieldname, HE5_GDXGrid[ idx ].ddataset[ i ].name) == 0 )
	{
	  found = 1; 
	  break;
	} 
    }

	
  /* Get dataset ID */
  /* -------------- */
  if( found == 1) 
    {
      fieldID = HE5_GDXGrid[ idx ].ddataset[ i ].ID; 
   
      /* Get the property list ID */
      /* ------------------------ */
      plist = H5Dget_create_plist(fieldID);
      if ( plist == FAIL )
	{
	  sprintf(errbuf, "Cannot get the property list ID for the \"%s\" data field.\n", fieldname);
	  H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_PLIST, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
	  
      /* Get the number of external files */
      /* -------------------------------- */
      nfiles = H5Pget_external_count(plist);
      if ( nfiles < 0 )
	{
	  sprintf(errbuf, "Cannot get the number of external files.\n");
	  H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
	  

      /* Allocate memory for file name */
      /* ----------------------------- */
      filename = (char *)calloc(HE5_HDFE_NAMBUFSIZE, sizeof(char));
      if(filename == NULL)
	{
	  H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory.");
	  HE5_EHprint("Error: Cannot allocate memory, occured", __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
	  
      strcpy(filelist,"");
	  
      /* Loop through all external files */
      /* ------------------------------- */
      for (i = 0; i < nfiles; i++)
	{
	  strcpy(filename,"");
		  
	  /* Get the file name, offset, and size */
	  /* ----------------------------------- */
	  status = H5Pget_external(plist, i, namelength, filename, &off, &sz);
	  if( status == FAIL)
	    {
	      sprintf(errbuf,"Cannot get information about external file.\n");
	      H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(errbuf);
	      free(filename);
	      return(FAIL);
	    }

		  
	  offset[i] = off;
	  size[i]   = sz;
		  
	  strcat(filelist, filename);
		  
	  /* Append comma */
	  /* ------------ */
	  if (nfiles > 1 && i < nfiles - 1) 
	    strcat(filelist,",");
		  
	}
	  
      slen = strlen(filelist);
	  
      filelist[slen] = 0;
	  
      if (filename != NULL) free(filename);
	  
      /* Release property list ID */
      /* ------------------------ */
      status = H5Pclose(plist);
      if (status == FAIL )
	{
	  sprintf(errbuf, "Cannot release property list ID.\n");
	  H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_PLIST, H5E_CLOSEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
	}
    }
  else
    {
      nfiles = FAIL;
      sprintf(errbuf, "Data field \"%s\" not found. \n", fieldname);
      H5Epush(__FILE__, "HE5_GDgetextdata", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
    
	
  free(errbuf);

 COMPLETION:
  return(nfiles);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDfldnameinfo                                                |
|                                                                             |
|  DESCRIPTION: Retrieves actual name of the field                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nameFlag       int     None        return (1) actual name, (0) alias,      |
|                                                (-1) FAIL                    |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|  fieldname      char*               name of field                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  actualname     char*               field actual name                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
static int
HE5_GDfldnameinfo(hid_t gridID, const char *fieldname, char *actualname)
{
  int         nameFlag       = FAIL;/* Return value of flag            */
  int         length         = 0;   /* String length                   */
  int         fldgroup       = FAIL;/* Field group code                */
 
  hid_t       fid            = FAIL;/* HDF-EOS file ID                 */
  hid_t       gid            = FAIL;/* "HDFEOS" group ID               */
  hid_t       groupID        = FAIL;/* data field group ID             */
 
  long        idx            = FAIL;/* grid index                      */
 
  H5G_stat_t  *statbuf = (H5G_stat_t *)NULL;/* buffer for link info    */
 
  herr_t      status         = FAIL;/* routine return status variable  */
 
  char        *namebuf       = NULL;/* Buffer for an actual field name */
  char        errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer      */
  
  CHECKPOINTER(fieldname);
 
  /* Get HDF-EOS file ID, "HDFEOS" group ID and grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDfldnameinfo", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed.\n");
      H5Epush(__FILE__, "HE5_GDfldnameinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  statbuf = (H5G_stat_t *)calloc(1, sizeof(H5G_stat_t ));
 
  /* Try to get information about specified field */
  /* -------------------------------------------- */
  H5E_BEGIN_TRY {
    groupID  = HE5_GDXGrid[idx].data_id;
    fldgroup = HE5_HDFE_DATAGROUP;
    status   = H5Gget_objinfo(groupID, fieldname, 0, statbuf);
  }
  H5E_END_TRY;
  if (status == FAIL)
    {
      nameFlag = FAIL;
      sprintf(errbuf, "Cannot find \"%s\" field.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDfldnameinfo", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(statbuf);
      return(nameFlag);
    }
 
  /* If the field name is an alias */
  /* ----------------------------- */
  if (statbuf->type == H5G_LINK)
    nameFlag = FALSE;
  else
    nameFlag = TRUE;
 
  if (nameFlag == FALSE)
    {
      if (actualname != NULL)
	{
	  status = HE5_GDaliasinfo(gridID, fldgroup, fieldname, &length, NULL);
	  if ( status == FAIL )
	    {
	      sprintf(errbuf, "Cannot get information about alias \"%s\".\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDfldnameinfo", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(FAIL);
	    }
 
	  namebuf = (char *)calloc(length, sizeof(char));
	  if ( namebuf == NULL )
	    {
	      sprintf(errbuf, "Cannot allocate memory for namebuf.\n");
	      H5Epush(__FILE__, "HE5_GDfldnameinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(FAIL);
	    }
 
	  /* Retrieve information about alias */
	  /* -------------------------------- */
	  status = HE5_GDaliasinfo(gridID, fldgroup, fieldname, &length, namebuf);
	  if ( status == FAIL )
	    {
	      sprintf(errbuf, "Cannot get information about alias \"%s\".\n", fieldname);
	      H5Epush(__FILE__, "HE5_GDfldnameinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(namebuf);
	      return(FAIL);
	    }
 
	  strcpy(actualname,"");
	  strcpy(actualname,namebuf);
	  free(namebuf);
	}
    }
 
  if (nameFlag == TRUE)
    {
      if (actualname != NULL)
	{
	  strcpy(actualname,"");
	  strcpy(actualname, fieldname);
	}
    }
 
  free(statbuf);
 
 COMPLETION: 
  return(nameFlag);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetalias                                                   |
|                                                                             |
|  DESCRIPTION:  Defines alias for a specified field name                     |
|                                                                             |
|                                                                             |
|  Return Value    Type        Units       Description                        |
|  ============   ===========  =========   =================================  |
|  status         herr_t                   Return status                      |
|                                                                             |
|  INPUTS:                                                                    |
|    gridID       hid_t                    Grid structure ID                  |
|    fieldname    char                     Original field name                |
|                                                                             |
|  OUTPUTS:                                                                   |
|    aliaslist    char                     List of aliases for the field name |
|                                                                             |
|  NOTES:                                                                     |
|    None                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDsetalias(hid_t gridID, char *fieldname, const char *aliaslist)
{
  herr_t   status     = FAIL;          /* return status variable      */
 
  hid_t    fid        = FAIL;          /* HDF-EOS file ID             */
  hid_t    gid        = FAIL;          /* "GRIDS"  group ID           */
  hid_t    groupID    = FAIL;          /* Field group ID              */
 
  long     idx        = FAIL;          /* grid index                  */
 
  char     *buf       = NULL;          /* Pointer to temporary buffer */
  char     *comma     = NULL;          /* Pointer to comma            */
  char     *aliasname = NULL;          /* Pointer to the alias name   */
  char     errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer        */
 
 
  HE5_LOCK;
  CHECKPOINTER(fieldname);
  CHECKPOINTER(aliaslist);
 
 
  /* Get HDF-EOS file ID, "HDFEOS" group ID and grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDsetalias", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed. \n");
      H5Epush(__FILE__, "HE5_GDsetalias", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Find out the field group */
  /* ------------------------ */
  groupID = HE5_GDXGrid[idx].data_id;
  if (groupID == FAIL) 
    {        
      sprintf(errbuf, "Cannot find \"%s\" field in grid. \n", fieldname);
      H5Epush(__FILE__, "HE5_GDsetalias", __LINE__, H5E_DATASET, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
 
  /* Allocate memory for temporary buffer */
  /* ------------------------------------ */
  buf = (char *)calloc(strlen(aliaslist)+64, sizeof(char));
  if (buf == NULL)
    {
      sprintf(errbuf, "Cannot allocate memory for \"buf\". \n");
      H5Epush(__FILE__, "HE5_GDsetalias", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
 
  /* Make a list like "name1,name2,name3," */
  /* ------------------------------------- */
  strcpy(buf,aliaslist);
  strcat(buf,",");
 
  /* Find first comma and make pointer pointing to it */
  /* ------------------------------------------------ */
  comma = strchr(buf, ',');
  while(comma != NULL)
    {
      /* Allocate memory for individual entry */
      /* ------------------------------------ */
      aliasname = (char *)calloc(comma-buf+1, sizeof(char));
      if (aliasname == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for \"aliasname\". \n");
	  H5Epush(__FILE__, "HE5_GDsetalias", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (buf != NULL) free(buf);
	  return(FAIL);
	}
         
      /* Pick up an individual entry and put it to the "aliasname" */
      /* --------------------------------------------------------- */
      memmove(aliasname,buf,comma-buf);
 
      /* Create a symbolic link for a specified object */
      /* --------------------------------------------- */
      status = H5Glink(groupID, H5G_LINK_SOFT, fieldname, aliasname);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot create an alias \"%s\" for \"%s\" field. \n", aliasname, fieldname);
	  H5Epush(__FILE__, "HE5_GDsetalias", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  if (aliasname != NULL) free(aliasname);
	  if (buf != NULL) free(buf);
	  return(FAIL);
	}
 
      /* Go to the next name entry */
      /* ------------------------- */
       memmove(buf,comma+1,strlen(comma+1)+1); 
      comma = strchr(buf, ',');
      if (aliasname != NULL) free(aliasname);
    }
 
  if (buf != NULL) free(buf);
         
 COMPLETION:
  HE5_UNLOCK;
  return(status);
}
 
 
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdropalias                                                  |
|                                                                             |
|  DESCRIPTION:  Removes the alias for a specified field name                 |
|                                                                             |
|                                                                             |
|  Return Value    Type        Units       Description                        |
|  ============   ===========  =========   =================================  |
|  status         herr_t                   Return status                      |
|                                                                             |
|  INPUTS:                                                                    |
|    gridID       hid_t                    Grid structure ID                  |
|    aliasname    char                     Alias name to remove               |
|    fldgroup     int                      Field group flag                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|    None                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDdropalias(hid_t gridID, int fldgroup, const char *aliasname)
{ 
  herr_t   status     = FAIL;          /* return status variable   */
 
  hid_t    fid        = FAIL;          /* HDF-EOS file ID          */
  hid_t    gid        = FAIL;          /* "GRIDS"  group ID        */
  hid_t    groupID    = FAIL;          /* Field group ID           */
 
  long     idx        = FAIL;          /* grid index               */
 
  char     errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer     */
 
 
  HE5_LOCK;
  CHECKPOINTER(aliasname);
 
  /* Get HDF-EOS file ID, "HDFEOS" group ID and grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDdropalias", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed. \n");
      H5Epush(__FILE__, "HE5_GDdropalias", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Get Group ID */
  /* ------------ */
  groupID = HE5_GDXGrid[idx].data_id;
  if (groupID == FAIL)
    {        
      sprintf(errbuf, "Invalid input group flag. \n");
      H5Epush(__FILE__, "HE5_GDdropalias", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Destroy a symbolic link */
  /* ----------------------- */
  status = H5Gunlink(groupID, aliasname);
  if (status == FAIL)
    {        
      sprintf(errbuf, "Cannot remove alias named \"%s\". \n", aliasname);
      H5Epush(__FILE__, "HE5_GDdropalias", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
 COMPLETION:
  HE5_UNLOCK;
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDaliasinfo                                                  |
|                                                                             |
|  DESCRIPTION:  Retrieves information about field aliases                    |
|                                                                             |
|                                                                             |
|  Return Value    Type        Units       Description                        |
|  ============   ===========  =========   =================================  |
|  status         herr_t                   Return status                      |
|                                                                             |
|  INPUTS:                                                                    |
|    gridID       hid_t                    Grid structure ID                  |
|    aliasname    char                     alias name                         |
|    fldgroup     int                      Field group flag                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|    length       int                      Buffer size                        |
|    buffer       char                     Buffer with original field name    |
|                                                                             |
|  NOTES:                                                                     |
|    None                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDaliasinfo(hid_t gridID, int fldgroup, const char *aliasname, int *length, char *buffer)
{
  herr_t        status     = FAIL;               /* return status variable   */
 
  int           type       = FAIL;               /* type-value of an object  */
 
  size_t        size       = 0;                  /* Size of the name buffer  */
 
  hid_t         fid        = FAIL;               /* HDF-EOS file ID          */
  hid_t         gid        = FAIL;               /* "HDF-EOS"  group ID      */
  hid_t         groupID    = FAIL;               /* Field group ID           */
 
  long          idx        = FAIL;               /* grid index               */
 
  H5G_stat_t    *statbuf   = (H5G_stat_t *)NULL; /* pointer to a structure   */
 
  char          errbuf[HE5_HDFE_ERRBUFSIZE];     /* Error message buffer     */
 
  CHECKPOINTER(aliasname);
 
  /* Get HDF-EOS file ID, "HDFEOS" group ID and grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDaliasinfo", &fid, &gid, &idx);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Checking for grid ID failed. \n");
      H5Epush(__FILE__, "HE5_GDaliasinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
 
  /* Get the group ID */
  /* ---------------- */
  if (fldgroup == HE5_HDFE_DATAGROUP)
    groupID = HE5_GDXGrid[idx].data_id;
  else
    {        
      sprintf(errbuf, "Invalid input group flag. \n");
      H5Epush(__FILE__, "HE5_GDaliasinfo", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  if (buffer == NULL)
    {
      /* Get the string length of a "real" name  */
      /* --------------------------------------  */
      statbuf = (H5G_stat_t *)calloc(1, sizeof(H5G_stat_t));
      if (statbuf == NULL)
	{
	  sprintf(errbuf, "Cannot allocate memory for \"statbuf\". \n");
	  H5Epush(__FILE__, "HE5_GDaliasinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
 
      /* Get the Object Info */
      /* ------------------- */
      status = H5Gget_objinfo(groupID, aliasname, 0, statbuf);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot get information about \"%s\" alias. \n", aliasname);
	  H5Epush(__FILE__, "HE5_GDaliasinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
 
      /* LINK name length with a null terminator */
      /* --------------------------------------- */
      size = statbuf->linklen;
 
      /* Object type (dataset, link, etc) */
      /* -------------------------------- */
      type   = statbuf->type;
 
      /* Make sure that the object is a LINK */
      /* ----------------------------------- */
      if (type != H5G_LINK)
	{
	  sprintf(errbuf,"The object named \"%s\" is not a symbolic link.\n", aliasname);
	  H5Epush(__FILE__, "HE5_GDaliasinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
         
      *length = (int)size;
         
      if ( statbuf != (H5G_stat_t *)NULL ) free(statbuf);
         
    }
 
  if (buffer != NULL)
    {
      size = (size_t)*length;
         
      /* Get the "real" name by an "alias" */
      /* --------------------------------- */
      status = H5Gget_linkval(groupID, aliasname, size, buffer);
      if (status == FAIL)
	{
	  sprintf(errbuf,"Cannot get the real name for the alias named \"%s\".\n", aliasname);
	  H5Epush(__FILE__, "HE5_GDaliasinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	}
    }
 
 COMPLETION:
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqfldalias                                                |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of fields & aliases and string length of|
|                fields & aliases list in "Data Fields" group                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nfldalias      long                Number of fields & aliases in "Data     |
|                                     Fields" group.                          |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               Grid structure ID                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fldalias       char*               Fields & aliases names in "Data Fields" |
|                                     group (Comma-separated list)            |
|  strbufsize     long*               Fields & aliases name list string length|
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jul 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long
HE5_GDinqfldalias(hid_t gridID, char *fldalias, long *strbufsize)
{
  long            nfldalias   = FAIL;         /* Number of fields & aliases (return)  */
  long            idx     = FAIL;             /* grid index                     */

  herr_t          status  = FAIL;             /* Return status variable         */

  hid_t           fid     = FAIL;             /* HDF-EOS file ID                */
  hid_t           gid     = FAIL;             /* "HDF-EOS" group ID             */

  char            *grpname = (char *)NULL;    /* Group name string              */
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer           */


  /* Get HDF-EOS file ID, "HDFEOS" group ID and grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDinqfldalias", &fid, &gid, &idx);
  if(status == SUCCEED )
    {
      grpname = (char *)calloc(HE5_HDFE_NAMBUFSIZE, sizeof(char) );
      if( grpname == NULL)
	{
	  H5Epush(__FILE__, "HE5_GDinqfldalias", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory");
	  HE5_EHprint("Error: Cannot allocate memory, occured", __FILE__, __LINE__);
	  return(FAIL);
	}

      strcpy(grpname,"/HDFEOS/GRIDS/");
      strcat(grpname, HE5_GDXGrid[idx].gdname);
      strcat(grpname,"/Data Fields");

      /* search group with grpname for the number of fields & aliases */
      /* ------------------------------------------------------------ */
      nfldalias = HE5_EHdatasetcat(fid,  grpname, fldalias, strbufsize);
      if ( nfldalias < 0 )
	{
	  sprintf(errbuf, "Cannot find the fields & aliases. \n");
	  H5Epush(__FILE__, "HE5_GDinqfldalias", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(grpname);
	}

      if (grpname != NULL) free(grpname);
    }
  else
    {
      sprintf(errbuf, "Checking for grid ID failed. \n");
      H5Epush(__FILE__, "HE5_GDinqfldalias", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  return (nfldalias);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDll2mm_cea                                                  |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  projparm       long                Projection parameters                   |
|  spherecode     int                 GCTP spheriod code                      |
|  xdimsize       long                xdimsize from GDcreate                  |
|  ydimsize       long                ydimsize from GDcreate                  |
|  upleftpt       double              upper left corner coordinates  (DMS)    |
|  lowrightpt     double              lower right corner coordinates (DMS)    |
|  longitude      long                longitude array (DMS)                   |
|  latitude       long                latitude array (DMS)                    |
|  npnts          long                number of lon-lat points                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  x              double              X value array                           |
|  y              double              Y value array                           |
|  scaleX         double              X grid size                             |
|  scaley         double              Y grid size                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer    Description                                        |
|  ======   ============   =================================================  |
|  Dec 04   Adura Adekunjo Added support for EASE grid                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDll2mm_cea(int projcode,int zonecode, int spherecode,
		double projparm[],
		long xdimsize, long ydimsize,
		double upleftpt[], double lowrightpt[], long npnts,
		double lon[], double lat[],
		double x[], double y[], double *scaleX, double *scaleY)
{
  herr_t          status = SUCCEED;         /* routine return status variable       */
#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*for_trans[100]) (double, double, double *, double *);
  int            errorcode = 0;         /* GCTP error code                      */
#else
  long            (*for_trans[100]) (double, double, double *, double *);
  long            errorcode = 0;         /* GCTP error code                      */
#endif

  double       xMtr0, xMtr1, yMtr0, yMtr1;
  double         lonrad0;    /* Longitude in radians of upleft point */
  double         latrad0;     /* Latitude in radians of upleft point */
  double         lonrad;     /* Longitude in radians of point */
  double         latrad;     /* Latitude in radians of point */
  
  char            *errbuf;               /* Buffer for error message             */
 
  /*CHECKPOINTER(upleftpt);
    CHECKPOINTER(lowrightpt);
    CHECKPOINTER(longitude);
    CHECKPOINTER(latitude);*/

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDll2mm_cea", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
 
  if(npnts <= 0)
    {
      status =  FAIL;
      sprintf(errbuf,"Improper npnts value\"%li\" must be greater than zero. \n", (long)npnts);
      H5Epush(__FILE__, "HE5_GDll2mm_cea", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return (status);
    }
  if ( projcode == HE5_GCTP_BCEA)
    {
      for_init(projcode, zonecode, projparm, spherecode, NULL, NULL,
	       &errorcode, for_trans);
      /* Convert upleft and lowright X coords from DMS to radians */
      /* -------------------------------------------------------- */

      lonrad0 = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_RAD);
      lonrad = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_RAD);

      /* Convert upleft and lowright Y coords from DMS to radians */
      /* -------------------------------------------------------- */
      latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_RAD);
      latrad = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_RAD);

      /* Convert from lon/lat to meters(or whatever unit is, i.e unit
	 of r_major and r_minor) using GCTP */
      /* ----------------------------------------- */
      errorcode = for_trans[projcode] (lonrad0, latrad0, &xMtr0, &yMtr0);
      x[0] = xMtr0;
      y[0] = yMtr0;

      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDll2mm_cea", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return (status);
	}
    
      /* Convert from lon/lat to meters(or whatever unit is, i.e unit
	 of r_major and r_minor) using GCTP */
      /* ----------------------------------------- */
      errorcode = for_trans[projcode] (lonrad, latrad, &xMtr1, &yMtr1);
      x[1] = xMtr1;
      y[1] = yMtr1;

      /* Report error if any */
      /* ------------------- */
      if (errorcode != 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	  H5Epush(__FILE__, "HE5_GDll2mm_cea", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return (status);
	}
      /* Compute x scale factor */
      /* ---------------------- */
      *scaleX = (xMtr1 - xMtr0) / xdimsize;

      /* Compute y scale factor */
      /* ---------------------- */
      *scaleY = (yMtr1 - yMtr0) / ydimsize;
    }
  else
    {
      status = FAIL;
      sprintf(errbuf, "Wrong projection code; this function is only for EASE grid \n");
      H5Epush(__FILE__, "HE5_GDll2mm_cea", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return (status);
    }


  if (errbuf != NULL) free(errbuf);
 COMPLETION:
  return(status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDmm2ll_cea                                                  |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t              return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  projparm       double              Projection parameters                   |
|  spherecode     int                 GCTP spheriod code                      |
|  xdimsize       long                xdimsize from GDcreate                  |
|  ydimsize       long                ydimsize from GDcreate                  |
|  upleftpt       double              upper left corner coordinates (DMS)     |
|  lowrightpt     double              lower right corner coordinates (DMS)    |
|  x              double              X value array                           |
|  y              double              Y value array                           |
|  npnts          long                number of x-y points                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|  longitude      double                longitude array (DMS)                 |
|  latitude       double                latitude array (DMS)                  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer     Description                                       |
|  ======   ============    ===============================================   |
|  Dec 04   Adura Adekunjo  Added support for EASE grid                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDmm2ll_cea(int projcode,int zonecode, int spherecode, double projparm[],
		long xdimsize, long ydimsize,
		double  upleftpt[], double lowrightpt[], long npnts,
		double x[], double  y[],
		double longitude[], double latitude[])
{
  herr_t          status = FAIL;         /* routine return status variable       */
      
  /*
    #if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
    int             (*for_trans[100]) (double, double, double *, double *);
    #else
    long            (*for_trans[100]) (double, double, double *, double *);
    #endif
  */

#if defined(SGI64) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN) || defined(DEC_ALPHA)
  int             (*inv_trans[100]) (double, double, double*, double*);
  int              errorcode = 0;      /* GCTP error code */
#else
  long            (*inv_trans[100]) (double, double, double*, double*);
  long             errorcode = 0;      /* GCTP error code */
#endif

  int            i;
  char            *errbuf;               /* Buffer for error message             */

  CHECKPOINTER(upleftpt);
  CHECKPOINTER(lowrightpt);
  CHECKPOINTER(longitude);
  CHECKPOINTER(latitude);

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDmm2ll_cea", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  if(npnts <= 0)
    {
      status =  FAIL;
      sprintf(errbuf,"Improper npnts value\"%li\" must be greater than zero. \n", (long)npnts);
      H5Epush(__FILE__, "HE5_GDmm2ll_cea", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return (status);
    }
  
  if ( projcode == HE5_GCTP_BCEA)
    {
      inv_init(projcode, zonecode, projparm, spherecode, NULL, NULL, &errorcode, inv_trans);
     
      /* Convert from meters(or whatever unit is, i.e unit
	 of r_major and r_minor) to lat/lon using GCTP */
      /* ----------------------------------------- */
  
      for(i=0; i<npnts; i++)
	{
	  errorcode =
	    inv_trans[projcode] (x[i], y[i],&longitude[i], &latitude[i]);
	  /* Report error if any */
	  /* ------------------- */
	  if (errorcode != 0)
	    {
	      status = FAIL;
	      sprintf(errbuf, "GCTP Error: %li\n", (long)errorcode);
	      H5Epush(__FILE__, "HE5_GDmm2ll_cea", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return (status);
	    }
 
	  longitude[i] = HE5_EHconvAng(longitude[i], HE5_HDFE_RAD_DMS);
	  latitude[i] = HE5_EHconvAng(latitude[i], HE5_HDFE_RAD_DMS);
	}
    }
  else
    {
      status = FAIL;
      sprintf(errbuf, "Wrong projection code; this function is only for EASE grid \n");
      H5Epush(__FILE__, "HE5_GDmm2ll_cea", __LINE__, H5E_ARGS, H5E_BADVALUE , errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return (status);
    }


  if (errbuf != NULL) free(errbuf);
 COMPLETION:
  return(status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetaliaslist                                               |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of aliases and the list of aliases in   |
|                "Data Fields" group                                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nalias         long                number of aliases in "Data Fields"      |
|                                     group                                   |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t               grid structure ID                       |
|  fldgroup       int                 field group flag                        |
|                                                                             |
|  OUTPUTS:                                                                   |
|  aliaslist      char*               list of aliases in "Data Fields" group  |
|                                     (comma-separated list)                  |
|  strbufsize     long*               length of aliases list                  |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jul 05    S.Zhao       Original development                                |
|  Mar 06    Abe Taaheri  Added code to get alias strbufsize only when user   |
|                         passes aliaslist as NULL pointer                    |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long
HE5_GDgetaliaslist(hid_t gridID, int fldgroup, char *aliaslist, long *strbufsize)
{
  long            nalias  = FAIL;             /* Number of aliases (return)  */
  long            idx     = FAIL;             /* Grid index                  */
  herr_t          status  = FAIL;             /* Return status variable      */
  hid_t           fid     = FAIL;             /* HDF-EOS file ID             */
  hid_t           gid     = FAIL;             /* "HDF-EOS" group ID          */
  char            *fieldlist = (char *)NULL;  /* List of Data fields         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer        */
  long            fldstrbuf = FAIL;           /* Buffer size for Data fields */
  long            nflds   = FAIL;             /* Number of Data fields       */
  long            nfldalias = FAIL;           /* Number of fields & aliases  */
  char            *fldalias = (char *)NULL;   /* List of fields & aliases    */
  long            fldaliasbuf = FAIL;         /* Buffer size for fields & 
						 aliases */
  char            *buff   = (char *)NULL;     /* Pointer to temporary buffer */
  char            *comma  = (char *)NULL;     /* Pointer to comma            */
  char            *comma1 = (char *)NULL;     /* Pointer to comma            */
  char            *nameptr = (char *)NULL;    /* Pointer to each name        */
  char            *tmpbuf  = (char *)NULL;    /* Pointer to temp buffer      */
  long            nameflag = FAIL;            /* Name flag                   */

  /* Get HDF-EOS file ID, "HDFEOS" group ID and Grid index */
  /* ----------------------------------------------------- */
  status = HE5_GDchkgdid(gridID, "HE5_GDgetaliaslist", &fid, &gid, &idx);
  if(status == SUCCEED )
    {
      /* If aliaslist and strbufsize desired */
      /* ----------------------------------- */
      if (fldgroup == HE5_HDFE_DATAGROUP)
	{
	  /* Call "HE5_GDnentries" routine to get number of fields */
	  /* ----------------------------------------------------- */
	  nflds = HE5_GDnentries(gridID, HE5_HDFE_NENTDFLD, &fldstrbuf);
	  if (nflds == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the number of fields in \"Data Fields\" group. \n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(FAIL);
	    }
	  
	  /* Allocate memory for fields list buffer */
	  /* -------------------------------------- */
	  fieldlist = (char *) calloc(fldstrbuf+6, sizeof(char));
	  if(fieldlist == NULL)
	    {
	      sprintf(errbuf,"Cannot allocate memory.\n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      return(FAIL);
	    }
	  
	  /* Call "HE5_GDinqfields" routine to get the list of Data fields */
	  /* ------------------------------------------------------------- */
	  nflds = HE5_GDinqfields(gridID, fieldlist, NULL, NULL);
	  if (nflds == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the list of fields in \"Data Fields\" group. \n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(fieldlist);
	      return(FAIL);
	    }
	  
	  /* Call "HE5_GDinqfldalias" routine to get number of fields & 
	     aliases */
	  /* -------------------------------------------------------- */
	  nfldalias = HE5_GDinqfldalias(gridID, NULL, &fldaliasbuf);
	  if (nfldalias == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the number of fields & aliases in \"Data Fields\" group. \n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(fieldlist);
	      return(FAIL);
	    }
	  
	  /* Allocate memory for fields & aliases list buffer */
	  /* ------------------------------------------------ */
	  fldalias = (char *) calloc(fldaliasbuf+6, sizeof(char));
	  if(fldalias == NULL)
	    {
	      sprintf(errbuf,"Cannot allocate memory.\n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_RESOURCE, H5E_NOSPACE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(fieldlist);
	      return(FAIL);
	    }
	  
	  /* Call "HE5_GDinqfldalias" routine to get the list of fields & 
	     aliases */
	  /* ----------------------------------------------------------- */
	  nfldalias = HE5_GDinqfldalias(gridID, fldalias, &fldaliasbuf);
	  if (nfldalias == FAIL)
	    {
	      sprintf(errbuf, "Cannot get the list of fields & aliases in \"Data Fields\" group. \n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_ARGS, H5E_BADVALUE, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(fieldlist);
	      free(fldalias);
	      return(FAIL);
	    }
	  
	  *strbufsize = strlen(fldalias) - strlen(fieldlist);
	  if (*strbufsize <= 0)
	    {
	      sprintf(errbuf, "Cannot find the aliases.\n");
	      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
		      H5E_OHDR, H5E_NOTFOUND, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(fieldlist);
	      free(fldalias);
	      return(FAIL);
	    }
	  else
	    {
	      nalias = 0;
	      
	      /* Allocate memory for temporary buffer */
	      /* ------------------------------------ */
	      buff = (char *)calloc(strlen(fldalias)+6, sizeof(char));
	      if (buff == NULL)
		{
		  sprintf(errbuf, "Cannot allocate memory for \"buff\". \n");
		  H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
			  H5E_RESOURCE, H5E_NOSPACE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(fieldlist);
		  free(fldalias);
		  return(FAIL);
		}
	      
	      /* Allocate memory for aliases */
	      /* --------------------------- */
	      tmpbuf = (char *)calloc(*strbufsize+6, sizeof(char));
	      if (tmpbuf == NULL)
		{
		  sprintf(errbuf, "Cannot allocate memory for \"tmpbuf\". \n");
		  H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
			  H5E_RESOURCE, H5E_NOSPACE, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(fieldlist);
		  free(fldalias);
		  free(buff);
		  return(FAIL);
		}
	      
	      strcpy(buff, fldalias);
	      strcat(buff, ",");
	      strcat(fieldlist, ",");
	      
	      /* Find first comma and make pointer pointing to it */
	      /* ------------------------------------------------ */
	      comma = strchr(buff, ',');
	      while(comma != NULL)
		{
		  /* Allocate memory for individual entry */
		  /* ------------------------------------ */
		  nameptr = (char *)calloc(comma-buff+6, sizeof(char));
		  if (nameptr == NULL)
		    {
		      sprintf(errbuf, "Cannot allocate memory for \"nameptr\". \n");
		      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
			      H5E_RESOURCE, H5E_NOSPACE, errbuf);
		      HE5_EHprint(errbuf, __FILE__, __LINE__);
		      free(fieldlist);
		      free(fldalias);
		      free(buff);
		      free(tmpbuf);
		      return(FAIL);
		    }
		  
		  /* Pick up an individual entry and put it to the "nameptr" */
		  /* ------------------------------------------------------- */
		  memmove(nameptr,buff,comma-buff);
		  strcat(nameptr, ",");
		  
		  nameflag = (strstr(fieldlist,nameptr) == NULL) ? 1 : 0;
		  if (nameflag == 1)
		    {
		      comma1 = strchr(tmpbuf, ',');
		      if(comma1 == NULL)
			strcpy(tmpbuf, nameptr);
		      else
			strcat(tmpbuf, nameptr);
		      
		      nalias++;
		    }
		  
		  memmove(buff,comma+1,strlen(comma+1)+1); 
		  comma = strchr(buff, ',');
		  
		  if (nameptr != NULL) free(nameptr);
		}
	    }
	  
	  if(aliaslist == NULL)/* just return buffersize 
				  and number of aliases */
	    {
	      if(nalias > 0 )
		{
		  if (fieldlist != NULL) free(fieldlist);
		  if (fldalias != NULL) free(fldalias);
		  if (buff != NULL) free(buff);
		  if (tmpbuf != NULL) free(tmpbuf);
		  return (nalias);
		}
	      else
		{
		  sprintf(errbuf, "Cannot find the aliases.\n");
		  H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
			  H5E_OHDR, H5E_NOTFOUND, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  if(fieldlist != NULL) free(fieldlist);
		  if(fldalias != NULL) free(fldalias);
		  if (buff != NULL) free(buff);
		  if (tmpbuf != NULL) free(tmpbuf);
		  return(FAIL);
		}
	    }
	  else
	    {
	      if(nalias > 0 )
		{
		  strncpy(aliaslist, tmpbuf, *strbufsize-1);
		  aliaslist[*strbufsize-1] = '\0';
		}
	      else
		{
		  sprintf(errbuf, "Cannot find the aliases.\n");
		  H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, 
			  H5E_OHDR, H5E_NOTFOUND, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  if(fieldlist != NULL) free(fieldlist);
		  if(fldalias != NULL) free(fldalias);
		  if (buff != NULL) free(buff);
		  if (tmpbuf != NULL) free(tmpbuf);
		  return(FAIL);
		}
	    }
	}
      else
	{
	  sprintf(errbuf, "Invalid input field group flag. \n");
	  H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, H5E_OHDR, 
		  H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return(FAIL);
	} 
    }
  else
    {
      sprintf(errbuf, "Checking for grid ID failed. \n");
      H5Epush(__FILE__, "HE5_GDgetaliaslist", __LINE__, H5E_FUNC, 
	      H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
  
  if (fieldlist != NULL) free(fieldlist);
  if (fldalias != NULL) free(fldalias);
  if (buff != NULL) free(buff);
  if (tmpbuf != NULL) free(tmpbuf);
  
  return (nalias);
}



/* 
*****************************************************************************
|                                                                           |
|          F  O  R  T  R  A  N  7 7     W  R  A  P  P  E  R  S              |
|                                                                           |
*****************************************************************************
*/



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDopenF   (FORTRAN wrapper)                                  |
|                                                                             |
|  DESCRIPTION: Opens or creates HDF file in order to create, read, or write  |
|                a grid.                                                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  FileID         int     None        HDF-EOS file ID                         |
|                                                                             |
|  INPUTS:                                                                    |
|  filename       char*   None        Filename                                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/28/00  A. Muslimov                                                       |
|  3/13/02  A. Muslimov   Added "Flags" options for core metadata.            |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDopenF(char *filename, int Flags)
{
  int       FileID  = FAIL;/* Return file ID        */

  hid_t     fid     = FAIL;/* hdf5 type file ID     */ 

  uintn     flags   = 9999;/* HDF5 file access code */
 
  char      *errbuf = NULL;/* Error message buffer  */


  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDopenF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory to error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }  
  
  /* Set up the file access flag */
  /* --------------------------- */
  if (Flags == HE5F_ACC_RDWR || Flags == HDF5_ACC_RDWR) flags = H5F_ACC_RDWR;
  else if (Flags == HE5F_ACC_RDONLY || Flags == HDF5_ACC_RDONLY) flags = H5F_ACC_RDONLY;
  else if (Flags == HE5F_ACC_TRUNC || Flags == HDF5_ACC_CREATE) flags = H5F_ACC_TRUNC;
  else
    {
      sprintf(errbuf, "File access flag is not supported. \n");
      H5Epush(__FILE__, "HE5_GDopenF", __LINE__, H5E_ARGS, H5E_UNSUPPORTED, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }  


  /* Call HE5_GDopen to perform file access */
  /* -------------------------------------- */
  fid = HE5_GDopen(filename,flags);
  if(fid == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDopen() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDopenF", __LINE__, H5E_FILE, H5E_CANTOPENFILE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }  


  FileID = (int)fid;

  free(errbuf);

  return(FileID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDcreateF    (FORTRAN wrapper)                               |
|                                                                             |
|  DESCRIPTION: Creates a grid within the file.                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  GridID         int     None        Grid structure ID                       |
|                                                                             |
|  INPUTS:                                                                    |
|  FileID         int     None        File ID                                 |
|  gridname       char    None        Grid structure name                     |
|  xdimsize       long    None        Number of columns in grid               |
|  ydimsize       long    None        Number of rows in grid                  |
|  upleftpt       double  None        Location (m/deg) of upper left corner   |
|  lowrightpt     double  None        Location (m/deg) of lower right corner  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  8/28/00  A. Muslimov                                                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDcreateF(int FileID, char *gridname, long xdimsize, long ydimsize, double upleftpt[], double lowrightpt[])
{
  int             GridID    = FAIL;/* grid ID (return value)              */

  hid_t           gridID    = FAIL;/* HDF5 type grid ID                   */
  hid_t           fid       = FAIL;/* HDF5 type file ID                   */

  char            *errbuf   = (char *)NULL; /* Buffer for error message   */

  errbuf  = (char *)calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char) );
  if (errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDcreateF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  fid = (hid_t)FileID;

  gridID = HE5_GDcreate(fid, gridname, xdimsize, ydimsize, upleftpt, lowrightpt);
  if (gridID == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDcreate() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDcreateF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  free(errbuf);

  GridID = (int)gridID;
  return(GridID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDattachF    (FORTRAN wrapper)                               |
|                                                                             |
|  DESCRIPTION: Attaches to an existing grid within the file.                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|                                                                             |
|  INPUTS:                                                                    |
|  FileID         int     None        HDF-EOS file id                         |
|  gridname       char*   None        grid sructure name                      |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDattachF(int FileID, char *gridname)
{
  int             GridID  = FAIL;	/* Return value of the Grid ID    */

  hid_t           gridID  = FAIL;	/* HDF5 type Grid  ID             */
  hid_t           fid     = FAIL;	/* HDF5 type file ID              */

  char            *errbuf = (char *)NULL;/* Buffer for error message  */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDattachF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory to error buffer.");
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  
  fid = (hid_t)FileID;

  gridID = HE5_GDattach(fid, gridname);
  if(gridID == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDattach() from FORTRAN wrapper. \n");
      H5Epush(__FILE__,  "HE5_GDattachF", __LINE__,H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  GridID = (int)gridID;
  return(GridID);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdetachF    (FORTRAN wrapper)                               |
|                                                                             |
|  DESCRIPTION: Detaches from grid interface and performs file housekeeping.  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|  HDF5 Library Functions Called:                                             |
|             H5Dclose                                                        |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDdetachF(int GridID)
{
  int             ret    = FAIL;/* (int) Return status variable   */

  herr_t          status = FAIL;/* routine return status variable */    
    
  hid_t           gridID = FAIL;/* HDF5 type grid ID              */

  char            *errbuf = (char *)NULL;/*Error message buffer   */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdetachF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  status = HE5_GDdetach(gridID);
  if(status == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDdetach() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdetachF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
	
  free(errbuf);

  ret = (int)status;
  return(ret);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDcloseF     (FORTRAN wrapper)                               |
|                                                                             |
|  DESCRIPTION: Closes file.                                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  FileID         int                 HDF-EOS type file ID                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDcloseF(int FileID)
{
  int               ret    = FAIL;/* (int) return status variable   */

  hid_t             fid    = FAIL;/* HDF5 type file ID              */

  herr_t            status = FAIL;/* routine return status variable */

  char              *errbuf = (char *)NULL;/*Error message buffer   */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDcloseF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  fid = (hid_t)FileID;

  /* Call HE5_GDclose to perform file close */
  /* -------------------------------------- */
  status = HE5_GDclose(fid);
  if(status == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDclose() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDcloseF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

	
  free(errbuf);

  ret = (int)status;
  return(ret);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefdimF                                                    |
|                                                                             |
|  DESCRIPTION: Defines numerical value of dimension (FORTRAN wrapper)        |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int      None        return status (0) SUCCEED, (-1) FAIL   |
|                                                                             |
|  INPUTS:                                                                    |
|  GrdiID         int                 grid structure ID                       |
|  dim. name      char                dimension name                          |
|  dim. size      long                dimension size                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 00   D.Wynne       Original Version                                    |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDdefdimF(int GridID,  char *dimname, long dim)
{
  int          ret     = SUCCEED;

  herr_t       status  = SUCCEED;

  hid_t        gridID  = FAIL;

  hsize_t      tdim    = 0;

  char         *errbuf = (char *)NULL;
 
 
  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
 
  tdim = (hsize_t)dim;
  gridID = (hid_t)GridID;

  status = HE5_GDdefdim(gridID, dimname, tdim);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling HE5_GDdefdim from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdefdimF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

 
  free(errbuf);

  ret = (int)status;
  return(ret);

}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefprojF    (FORTRAN wrapper)                              |
|                                                                             |
|  DESCRIPTION: Defines projection of grid.                                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units       Description                           |
|  ============   ======    =========   ===================================== |
|  ret            int       None        return status (0) SUCCEED, (-1) FAIL  |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int       None        HDF-EOS type grid  ID                 |
|  projcode       int                   GCTP projection code                  |
|  zonecode       int                   UTM zone code                         |
|  spherecode     int                   GCTP spheriod code                    |
|  projparm       double                Projection parameters                 |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDdefprojF(int GridID, int projcode, int zonecode,  int spherecode, double projparm[])
{
  int             ret      = FAIL;      /* routine return status variable */  

  herr_t          status   = FAIL;      /* routine return status variable */  

  hid_t           gridID   = FAIL;      /* HDF5 type grid ID              */

  char            *errbuf = (char *)NULL;/* Buffer for error message      */
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefprojF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDdefproj(gridID, projcode, zonecode, spherecode, projparm);
  if(status == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDdefproj() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdefprojF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	
      return(FAIL);
    }

  
  free(errbuf);

  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeforiginF   (FORTRAN wrapper)                             |
|                                                                             |
|  DESCRIPTION: Defines the origin of the grid data.                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|  origincode     int                 origin code                             |
|                                     HDFE_GD_UL (0)                          |
|                                     HDFE_GD_UR (1)                          |
|                                     HDFE_GD_LL (2)                          |
|                                     HDFE_GD_LR (3)                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDdeforiginF(int GridID, int origincode)
{
  int             ret     = FAIL;/* routine return status variable   */

  herr_t          status  = FAIL;/* routine return status variable   */

  hid_t           gridID  = FAIL;/* HDF5 type grid ID                */

  char            *errbuf = (char *)NULL;/* Buffer for error message */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdeforigin", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  

  gridID = (hid_t)GridID;

  status = HE5_GDdeforigin(gridID, origincode);
  if ( status == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDdeforigin() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdeforiginF", __LINE__, H5E_ARGS, H5E_BADRANGE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
	  
      return(FAIL);
    }
  

  free(errbuf);


  ret = (int)status;
  return(ret);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeffld                                                     |
|                                                                             |
|                                                                             |
|  DESCRIPTION: Defines data field within grid structure (FORTRAN)            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid  structure ID                      |
|  fieldname      char                fieldname                               |
|  fortdimlist    char                Dimension list (comma-separated list)   |
|                                         FORTRAN dimesion order              |
|  fortmaxdimlist char                Max Dimension list (FORTRAN order)      |
|  numtype        int                 field type                              |
|  merge          int                 merge code                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 00   D.Wynne       Modified for HDF5                                   |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|  Nov 00   A.Muslimov    Updated to reverse order of "fortmaxdimlist"entries.|
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDdeffld(int GridID, char *fieldname, char *fortdimlist, char *fortmaxdimlist, int numtype, int merge)
{
  int          ret    = SUCCEED;/* routine return status variable  */

  herr_t       status = SUCCEED;/* routine return status variable  */

  hid_t        gridID   = FAIL;/* HDF5 type grid ID                */
  hid_t        numbertype = FAIL;/* HDF5 type data type ID         */

  char         *dimlist = (char *)NULL;/* Dimension list (C order) */
  char         *maxdimlist = (char *)NULL;/* Max. Dim. list (C)    */
  char         *errbuf  = (char *)NULL;/* error message buffer     */

   
 
  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
   
  numbertype = HE5_EHconvdatatype(numtype);
  if(numbertype == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_EHconvdatatype() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
   
  if(strcmp(fortmaxdimlist,"") == 0)
    fortmaxdimlist = NULL;

  /* Allocate space for C order dimension list */
  /* ----------------------------------------- */
  dimlist = (char *)calloc(strlen(fortdimlist) + 1, sizeof(char));
  if(dimlist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for dimlist.\n");
      H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
   

  /* Reverse entries in dimension list (FORTRAN -> C) */
  /* ------------------------------------------------ */
  status = HE5_EHrevflds(fortdimlist, dimlist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_EHrevflds() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);

      return(FAIL);
    }

   
  if (fortmaxdimlist != NULL)
    {
      /* Allocate space for C order dimension list */
      /* ----------------------------------------- */
      maxdimlist = (char *)calloc(strlen(fortmaxdimlist) + 1, sizeof(char));
      if(maxdimlist == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory for maxdimlist.\n");
	  H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  return(FAIL);
	}
   
      /* Reverse entries in maximum dimension list (FORTRAN -> C) */
      /* -------------------------------------------------------- */
      status = HE5_EHrevflds(fortmaxdimlist, maxdimlist);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Error calling HE5_EHrevflds() from FORTRAN wrapper.\n");
	  H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dimlist);
	  free(maxdimlist);
		   
	  return(FAIL);
	}
    }
  else 
    {
      maxdimlist = NULL;
    }
   

  gridID = (hid_t)GridID;
   
  /* Call Define Field routine */
  /* ------------------------- */
  status = HE5_GDdeffield(gridID, fieldname, dimlist, maxdimlist, numbertype, merge);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDdeffld() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdeffld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      if (maxdimlist !=NULL) 
	free(maxdimlist);

      return(FAIL);
    }

   
   
  free(dimlist);
  if (maxdimlist !=NULL) 
    free(maxdimlist);
   
  free(errbuf);
   
  ret = (int)status;
  return(ret);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetfill     (FORTRAN wrapper)                              |
|                                                                             |
|  DESCRIPTION: Sets fill value for the specified field.                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char*               field name                              |
|  fillval        void*               fill value                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDsetfill(int GridID, char *fieldname, int numtype, void *fillval)
{
  int       ret    = FAIL;/* (int) return status variable   */

  herr_t    status = FAIL;/* routine return status variable */

  hid_t     gridID = FAIL;/* HDF5 type grid ID              */
  hid_t     ntype  = FAIL;/* HDF5 type data type ID         */
 
  char      *errbuf  = (char *)NULL;/* error message buffer */

   
  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetfill", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
   
  ntype = HE5_EHconvdatatype(numtype);
  if(ntype == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_EHconvdatatype() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDsetfill", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  gridID = (hid_t)GridID;
  
  status = HE5_GDsetfillvalue(gridID, fieldname, ntype, fillval);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDsetfillvalue() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDsetfill", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }  


  free(errbuf);

  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeftileF                                                   |
|                                                                             |
|  DESCRIPTION: Defines tiling parameters, FORTRAN wrapper for GDdeftile      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  tilecode       int                 tile code                               |
|  tilerank       int                 number of tiling dimensions             |
|  tiledims       long                tiling dimensions                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|  None                                                                       |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 00   D.Wynne       Original Version                                    |
|  Aug 00   A.Muslimov    Updated to reflect data type changes                |
|  Jan 01   A.Muslimov    Added proper FORTRAN to C dimension order conversion|
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDdeftileF(int GridID, int  tilecode, int tilerank, long *tiledims)
{
  int		ret     = FAIL;           /* (int) return status  */
  int		i       = 0;              /* Loop index           */

  hid_t     gridID  = FAIL;           /* HDF5 type grid ID    */

  herr_t	status  = FAIL;           /* return status        */

  hsize_t	*tdims  = (hsize_t *)NULL;/* size variable        */  

  char      *errbuf = (char *)NULL;   /* error message buffer */


  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdeftileF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  
  tdims = (hsize_t *)calloc(tilerank, sizeof(hsize_t));
  if(tdims == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for tdims.\n");
      H5Epush(__FILE__, "HE5_GDdeftileF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }  
  
  /* Convert from FORTRAN to C dimension order */
  /* ----------------------------------------- */
  for(i = 0; i < tilerank; i++)
    tdims[i] = (hsize_t)tiledims[tilerank - 1 - i];


  gridID = (hid_t)GridID;

  status = HE5_GDdeftile(gridID, tilecode, tilerank, tdims);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling HE5_GDdeftile() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdeftileF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(tdims);
      return(FAIL);
    }
 
  
  free(tdims);
  free(errbuf);


  ret = (int)status;
  return(ret);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefcompF    (FORTRAN wrapper)                              |
|                                                                             |
|  DESCRIPTION: Defines compression type and parameters                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  compcode       int                 compression code                        |
|  compparm       int                 compression parameters                  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:   Before calling this function, storage must be CHUNKED             |
|                      Values of compression code                             |
|                         HDFE_COMP_NONE                  0                   |
|                         HDFE_COMP_RLE                   1                   |
|                         HDFE_COMP_NBIT                  2                   |
|                         HDFE_COMP_SKPHUFF               3                   |
|                         HDFE_COMP_DEFLATE               4                   |
|                         HDFE_COMP_SZIP_CHIP             5                   |
|                         HDFE_COMP_SZIP_K13              6                   |
|                         HDFE_COMP_SZIP_EC               7                   |
|                         HDFE_COMP_SZIP_NN               8                   |
|                         HDFE_COMP_SZIP_K13orEC          9                   |
|                         HDFE_COMP_SZIP_K13orNN          10                  |
|                         HDFE_COMP_SHUF_DEFLATE          11                  |
|                         HDFE_COMP_SHUF_SZIP_CHIP        12                  |
|                         HDFE_COMP_SHUF_SZIP_K13         13                  |
|                         HDFE_COMP_SHUF_SZIP_EC          14                  |
|                         HDFE_COMP_SHUF_SZIP_NN          15                  |
|                         HDFE_COMP_SHUF_SZIP_K13orEC     16                  |
|                         HDFE_COMP_SHUF_SZIP_K13orNN     17                  |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|  Aug 03   S.Zhao        Added Szip compression methods.                     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDdefcompF(int GridID, int compcode, int compparm[])
{
  int       ret      = FAIL;/* (int) return status variable   */

  herr_t    status   = FAIL;/* routine return status variable */

  hid_t     gridID   = FAIL;/* HDF5 type grid ID              */
 
  char      *errbuf = (char *)NULL;   /* error message buffer */


  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefcompF", __LINE__, H5E_RESOURCE, H5E_NOSPACE,"Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDdefcomp(gridID, compcode, compparm);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling HE5_GDdefcomp() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdefcompF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  

  free(errbuf);

  ret = (int)status;
  return(ret);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefpixregF    (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION: Defines pixel registration within grid cell.                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  pixregcode     int     None        Pixel registration code                 |
|                                     HDFE_CENTER (0)                         |
|                                     HDFE_CORNER (1)                         |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDdefpixregF(int GridID, int pixregcode)
{
  int             ret     = FAIL;        /* (int) returmn status variable  */

  herr_t          status  = FAIL;        /* routine return status variable */
  
  hid_t           gridID  = FAIL;        /* HDF5 type grid ID              */   

  char            *errbuf = (char *)NULL;/* Buffer for error message       */ 


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefpixregF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  status = HE5_GDdefpixreg(gridID, pixregcode);
  if ( status == FAIL)
    { 
      sprintf(errbuf, "Error calling HE5_GDdefpixreg() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdefpixregF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  

  free(errbuf);
  
  ret = (int)status;
  return(ret);
}
 

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrcharfld                                                  |
|                                                                             |
|  DESCRIPTION: Writes data to a character field (FORTRAN wrapper around      |
|               GDwritefield)                                                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char                fieldname                               |
|  elemlen        int                 each element length in array of string  |
|  numelem        int                 number of elements in declared buffer   |
|                                     array                                   |
|  fortstart      long                start array                             |
|  fortstride     long                stride array                            |
|  fortedge       long                edge array                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  data           void                data buffer for write                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Feb 04   S.Zhao        For an array of character string dataset.           |
|  Jun 04   S.Zhao        Added one more argument (numelem).                  |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDwrcharfld(int GridID, char *fieldname, int elemlen, int numelem, long fortstart[], long fortstride[], long fortedge[], void *data)
 
{
  int         ret      = FAIL;   /* (int) return status variable   */
  int         i        = 0;      /* Loop index                     */
  int         rank     = 0;      /* Field rank                     */
 
  hid_t       gridID   = FAIL;   /* HDF5 type grid ID              */
 
  hid_t       ntype[1] = {FAIL}; /* Field number type              */
 
  herr_t      status   = FAIL;   /* return status variable         */
 
  hsize_t     dims[HE5_DTSETRANKMAX];/* Field dimensions           */
  hsize_t     *stride  = (hsize_t *)NULL;/* Stride array (C order) */
  hsize_t     *edge    = (hsize_t *)NULL;/* Edge array (C order)   */
 
  hssize_t    *start   = (hssize_t *)NULL;/* Start array (C order) */
 
  char        *errbuf  = (char *)NULL;   /* error message buffer   */
  char        **strdatabuf = NULL;       /* string data buffer                */
  int         nelem = 0;                 /* number of elements in array of str*/
  int         strsize = 0;               /* each str length in array of str   */
  char        *blankPtr = (char *)NULL;  /* pointer to blank character        */
  char        *tmpString = (char *)NULL; /* pointer to temp string            */
  int         attr = 0;                  /* attribute value                   */
  hsize_t     count[1];                  /* number of attribute elements      */
 
 
  /* Initialize dims[] array */
  /* ----------------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    dims[i] = 0;
 
 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
  gridID = (hid_t)GridID;
 
  /* Get field info  */
  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, NULL, NULL);
  if (status == SUCCEED)
    {
      start = (hssize_t *)calloc(rank, sizeof(hssize_t));
      if(start == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for start.\n");
	  H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
        }
      stride = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(stride == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for stride.\n");
	  H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(errbuf);
	  return(FAIL);
        }
      edge = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(edge == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for edge.\n");
	  H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(errbuf);
	  return(FAIL);
        }
      /* Reverse order of dimensions (FORTRAN -> C) */
      /* ------------------------------------------ */
      for (i = 0; i < rank; i++)
        {
	  start[i]  = (hssize_t)fortstart[rank - 1 - i];
	  stride[i] = (hsize_t)fortstride[rank - 1 - i];
	  edge[i]   = (hsize_t)fortedge[rank - 1 - i];
        }
         
      strsize = elemlen;
      nelem = dims[0];

      tmpString = (char *)calloc(1,strsize+1);
      if(tmpString == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory for tmpString.\n");
	  H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  return(FAIL);
	}
 
      strdatabuf = (char **)malloc(nelem*sizeof(char *));
      for (i = 0; i<nelem; i++)
	{
	  strdatabuf[i] = NULL;
	  strdatabuf[i] = (char *)malloc((strsize+1)*sizeof(char));
	  strncpy(strdatabuf[i],(char *)data+(strsize*i), strsize);
	  strdatabuf[i][strsize] = '\0';
	  strcpy(tmpString,strdatabuf[i]);
 
	  /* Find the first non blank character from the end */
	  /* ----------------------------------------------- */
	  blankPtr = tmpString + strsize -1;
	  while (*blankPtr == ' ')
	    {
	      blankPtr--;
	    }
 
	  /* Turn it into a C string */
	  /* ----------------------- */
	  blankPtr++;
	  *blankPtr = '\0';
 
	  strcpy(strdatabuf[i], tmpString);
	}
 
      free(tmpString);
 
      count[0] = 1;
      attr = strsize;
      status = HE5_GDwritelocattr(gridID, fieldname, "StringLengthAttribute", H5T_NATIVE_INT, count, &attr);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot write attribute to the field \"%s\".",fieldname) ;
	  H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  if (strdatabuf != NULL)
	    {
	      for (i = 0; i<nelem; i++)
		{
		  if (strdatabuf[i] != NULL)
		    {
		      free (strdatabuf[i]);
		      strdatabuf[i] = NULL;
		    }
		}
	      free (strdatabuf);
	      strdatabuf = NULL;
	    }
	  return(FAIL);
	}
 
      status = HE5_GDwrrdfield(gridID, fieldname, "w", start, stride, edge, strdatabuf);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot write data to the field \"%s\".",fieldname) ;
	  H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  if (strdatabuf != NULL)
	    {
	      for (i = 0; i<nelem; i++)
		{
		  if (strdatabuf[i] != NULL)
		    {
		      free (strdatabuf[i]);
		      strdatabuf[i] = NULL;
		    }
		}
	      free (strdatabuf);
	      strdatabuf = NULL;
	    }
	  return(FAIL);
	}

    }
  else
    {
      sprintf(errbuf, "Error calling GDfieldinfo() from FORTRAN wrapper.") ;
      H5Epush(__FILE__, "HE5_GDwrcharfld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      status = FAIL;
    }
 
 
  if (start  != NULL) free(start);
  if (stride != NULL) free(stride);
  if (edge   != NULL) free(edge);
  if (errbuf != NULL) free(errbuf);
  if (strdatabuf != NULL)
    {
      for (i = 0; i<nelem; i++)
        {
	  if (strdatabuf[i] != NULL)
	    {
	      free (strdatabuf[i]);
	      strdatabuf[i] = NULL;
	    }
        }
      free (strdatabuf);
      strdatabuf = NULL;
    }
 
  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrfld                                                      |
|                                                                             |
|  DESCRIPTION: Writes data to field (FORTRAN wrapper around GDwritefield)    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char                fieldname                               |
|  fortstart      long                start array                             |
|  fortstride     long                stride array                            |
|  fortedge       long                edge array                              |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  data           void                data buffer for write                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 99   Abe Taaheri   Modified data types for HDF5                        |
|  Jun 00   D.Wynne       Updated for native datatypes                        |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|  Feb 05   S.Zhao        Replaced the "myedge" array by the "dims" array if  |
|                         it was larger than the dimension size.              |
|  Sep 11   Abe Taaheri   Modified for correcting Unlimited dimension         |
|                         behavior and extension                              |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDwrfld(int GridID, char *fieldname, long fortstart[], long fortstride[], 
long fortedge[], void *data)
 
{
  int         ret      = FAIL;   /* (int) return status variable   */
  int         i        = 0;      /* Loop index                     */
  int         rank     = 0;      /* Field rank                     */

  hid_t       gridID   = FAIL;   /* HDF5 type grid ID              */

  hid_t       ntype[1] = {FAIL}; /* Field number type              */

  herr_t      status   = FAIL;   /* return status variable         */

  hsize_t     dims[HE5_DTSETRANKMAX];/* Field dimensions           */
  hsize_t     *stride  = (hsize_t *)NULL;/* Stride array (C order) */
  hsize_t     *edge    = (hsize_t *)NULL;/* Edge array (C order)   */

  hssize_t    *start   = (hssize_t *)NULL;/* Start array (C order) */

  char        *errbuf  = (char *)NULL;   /* error message buffer   */
  hsize_t     *myedge = (hsize_t *)NULL;
  hsize_t      maxdims[HE5_DTSETRANKMAX];/* Field maximum dimensions     */
  int          append   = FALSE;         /* FLAG (if field is appendable)*/
  int          unlimdim;

  /* Initialize dims[] array */
  /* ----------------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    {
      dims[i] = 0;
      maxdims[ i ] = 0;
    }
 
 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  /* Get field info  */
  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, NULL, NULL);
  if (status == SUCCEED)
    {
      start = (hssize_t *)calloc(rank, sizeof(hssize_t));
      if(start == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for start.\n");
	  H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
        }
      stride = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(stride == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for stride.\n");
	  H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(errbuf);
	  return(FAIL);
        }
      edge = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(edge == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for edge.\n");
	  H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(errbuf);
	  return(FAIL);
        }

      /* Reverse order of dimensions (FORTRAN -> C) */
      /* ------------------------------------------ */
      for (i = 0; i < rank; i++)
        {
	  start[i]  = (hssize_t)fortstart[rank - 1 - i];
	  stride[i] = (hsize_t)fortstride[rank - 1 - i];
	  edge[i]   = (hsize_t)fortedge[rank - 1 - i];
        }

      myedge = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(myedge == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for edge.\n");
	  H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  return(FAIL);
        }
      
      /* get maxdims for the field */
      status = HE5_GDflddiminfo(gridID, fieldname, &rank, dims, maxdims);

      /* see if we need first to extend data dimensions for unlimited 
	 dimensions */

      for (i = 0; i < rank; i++)
        {
	  if( dims[i] == maxdims[i] )
	    append = FALSE;
	  else if ( (dims[i] < maxdims[i]) || (maxdims[i] == H5S_UNLIMITED))
	    {
	      append = TRUE;
	      break;
	    }
	}
      unlimdim = i;

      if(append == FALSE)
	{
	  for (i = 0; i < rank; i++)
	    {
	      if(edge[i] > dims[i])
		myedge[i] = dims[i];
	      else
		myedge[i] = edge[i];
	    }
	}
      else
	{
	  for (i = 0; i < rank; i++)
	    {
	      myedge[i] = edge[i];
	    }
	}

      if((append == TRUE) && (edge[unlimdim] > dims[unlimdim]))
	{
	  hssize_t newstart[8];
	  hsize_t newedge[8];

	  for (i = 0; i < rank; i++)
	    {
	      newstart[i]=start[i];
	      newedge[i] = edge[i];
	    }
	  newstart[unlimdim]=edge[unlimdim]-1;
	  newedge[unlimdim] = 1;
	  status = HE5_GDwrrdfield(gridID, fieldname, "w", newstart, stride, newedge,data);
	  if (status == FAIL)
	    {
	      sprintf(errbuf, "Cannot write data to the field \"%s\".",fieldname) ;
	      H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	      free(start);
	      free(stride);
	      free(edge);
	      free(myedge);
	      free(errbuf);
	      return(FAIL);
	    }
	  else
	    {
	      for (i = 0; i < rank; i++)
		{
		  dims[i]=edge[i];
		}
	    }
	}

      status = HE5_GDwrrdfield(gridID, fieldname, "w", start, stride, myedge,data);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot write data to the field \"%s\".",fieldname) ;
	  H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(myedge);
	  free(errbuf);
	  return(FAIL);
	}
    }
  else
    {
      sprintf(errbuf, "Error calling GDfieldinfo() from FORTRAN wrapper.") ;
      H5Epush(__FILE__, "HE5_GDwrfld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      status = FAIL;
    }
  

  if (start  != NULL) free(start);
  if (stride != NULL) free(stride);
  if (edge   != NULL) free(edge);
  if (errbuf != NULL) free(errbuf);
  if (myedge != NULL) free(myedge);

  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDrdfld                                                      |
|                                                                             |
|  DESCRIPTION: Reads data from field (FORTRAN wrapper around GDreadfield)    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid  structure ID                      |
|  fieldname      char                fieldname                               |
|  fortstart      long                start array                             |
|  fortstride     long                stride array                            |
|  fortedge       long                edge array                              |
|  buffer         void                data buffer for read                    |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Nov 99   Abe Taaheri   Modified for HDF5                                   |
|  Jun 00   D.Wynne       Updated to reflect data type changes                |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDrdfld(int GridID, char *fieldname, long fortstart[], long fortstride[], long fortedge[], void *buffer)
{
  int         ret      = FAIL;   /* (int) return status variable   */
  int         i        = 0;      /* Loop index                     */
  int         rank     = 0;      /* Field rank                     */
 
  hid_t       gridID   = FAIL;   /* HDF5 type grid ID              */
 
  hid_t       ntype[1] = {FAIL}; /* Field number type              */
 
  herr_t      status   = FAIL;   /* return status variable         */
 
  hsize_t     dims[HE5_DTSETRANKMAX];/* Field dimensions           */
  hsize_t     *stride  = (hsize_t *)NULL;/* Stride array (C order) */
  hsize_t     *edge    = (hsize_t *)NULL;/* Edge array (C order)   */
 
  hssize_t    *start   = (hssize_t *)NULL;/* Start array (C order) */
 
  char        *errbuf  = (char *)NULL;   /* error message buffer  */
 
 
  /* Initialize dims[] array */
  /* ----------------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    dims[i] = 0;
 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDrdfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
 
 
  gridID = (hid_t)GridID;
 
 
  /* Get field info */
  /* -------------- */
  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, NULL,NULL);
  if (status != FAIL)
    {
      start =  (hssize_t *)calloc(rank, sizeof(hssize_t));
      if(start == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for start.\n");
	  H5Epush(__FILE__, "HE5_GDrdfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
        }
 
      stride = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(stride == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for stride.\n");
	  H5Epush(__FILE__, "HE5_GDrdfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(errbuf);
	  return(FAIL);
        }
 
      edge = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(edge == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for edge.\n");
	  H5Epush(__FILE__, "HE5_GDrdfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(errbuf);
	  return(FAIL);
        }
 
      /* Reverse order of dimensions (FORTRAN -> C) */
      for (i = 0; i < rank; i++)
        {
	  start[i]  = (hssize_t)fortstart[rank - 1 - i];
	  stride[i] = (hsize_t)fortstride[rank - 1 - i];
	  edge[i]   = (hsize_t)fortedge[rank - 1 - i];
        }
 
 
      status = HE5_GDwrrdfield(gridID, fieldname, "r", start, stride, edge, buffer);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Error calling HE5_GDwrrdfield() from FORTRAN wrapper.") ;
	  H5Epush(__FILE__, "HE5_GDrdfld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  return(FAIL);
	}
 
    }
  else
    {
      sprintf(errbuf, "Error calling HE5_GDfieldinfo() from FORTRAN wrapper.") ;
      H5Epush(__FILE__, "HE5_GDrdfld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      status = FAIL;
    }
 
  if (start  != NULL) free(start);
  if (stride != NULL) free(stride);
  if (edge   != NULL) free(edge);
  if (errbuf != NULL) free(errbuf);
 
  ret = (int)status;
  return(ret);
 
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDrdcharfld                                                  |
|                                                                             |
|  DESCRIPTION: Reads data from a character string field (FORTRAN wrapper     |
|               around GDreadfield)                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid  structure ID                      |
|  fieldname      char                fieldname                               |
|  elemlen        int                 each element length in array of string  |
|  numelem        int                 number of elements in declared buffer   |
|                                     array                                   |
|  fortstart      long                start array                             |
|  fortstride     long                stride array                            |
|  fortedge       long                edge array                              |
|  buffer         void                data buffer for read                    |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 04   S.Zhao        For an array of character string dataset.           |
|  Jun 04   S.Zhao        Added two more arguments (elemlen and numelem).     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDrdcharfld(int GridID, char *fieldname, int elemlen, int numelem, long fortstart[], long fortstride[], long fortedge[], void *buffer)
{
  int         ret      = FAIL;   /* (int) return status variable   */
  int         i        = 0;      /* Loop index                     */
  int         rank     = 0;      /* Field rank                     */

  hid_t       gridID   = FAIL;   /* HDF5 type grid ID              */

  hid_t       ntype[1] = {FAIL}; /* Field number type              */

  herr_t      status   = FAIL;   /* return status variable         */

  hsize_t     dims[HE5_DTSETRANKMAX];/* Field dimensions           */
  hsize_t     *stride  = (hsize_t *)NULL;/* Stride array (C order) */
  hsize_t     *edge    = (hsize_t *)NULL;/* Edge array (C order)   */

  hssize_t    *start   = (hssize_t *)NULL;/* Start array (C order) */

  char        *errbuf  = (char *)NULL;   /* error message buffer  */
  char        **strdatabuf = NULL;       /* string data buffer                */
  int         stlen = 0;                 /* whole string array length         */
  int         nelem = 0;                 /* number of elements in array of str*/
  int         strsize = 0;               /* each str length in array of str   */
  int         attr = 0;                  /* attribute value                   */
  int         j = 0;                     /* Loop index                        */

  int              num_elem_passed_out;
  int              numread;


  /* Initialize dims[] array */
  /* ----------------------- */
  for (i = 0; i < HE5_DTSETRANKMAX; i++)
    dims[i] = 0;
 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  


  gridID = (hid_t)GridID;
  

  /* Get field info */
  /* -------------- */
  status = HE5_GDfieldinfo(gridID, fieldname, &rank, dims, ntype, NULL,NULL);  
  if (status != FAIL)
    {
      start =  (hssize_t *)calloc(rank, sizeof(hssize_t));
      if(start == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for start.\n");
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  return(FAIL);
        }

      stride = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(stride == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for stride.\n");
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(errbuf);
	  return(FAIL);
        }

      edge = (hsize_t *)calloc(rank, sizeof(hsize_t));
      if(edge == NULL)
        {
	  sprintf(errbuf,"Cannot allocate memory for edge.\n");
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(errbuf);
	  return(FAIL);
        }

      /* Reverse order of dimensions (FORTRAN -> C) */
      for (i = 0; i < rank; i++)
        {
	  start[i]  = (hssize_t)fortstart[rank - 1 - i];
	  stride[i] = (hsize_t)fortstride[rank - 1 - i];
	  edge[i]   = (hsize_t)fortedge[rank - 1 - i];
        }
 

      status = HE5_GDreadlocattr(gridID, fieldname, "StringLengthAttribute", &attr);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Cannot read attribute from the field \"%s\".",fieldname) ;
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  return(FAIL);
	}
 
      if(elemlen < attr )
	{
	  sprintf(errbuf, "Element length passed in is not correct. Should be same as in declration");
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  return(FAIL);
	}

      strsize = attr;
      stlen = dims[0] * strsize;
      nelem = stlen / strsize;
      strdatabuf = (char **)malloc(nelem*sizeof(char *));
      for (i = 0; i<nelem; i++)
	{
	  strdatabuf[i] = NULL;
	  strdatabuf[i] = (char *)malloc((strsize+1)*sizeof(char));
	}
 
      /* Read data from the field */
      /* ------------------------ */
      status = HE5_GDwrrdfield(gridID, fieldname, "r", start, stride, edge, strdatabuf);
      if (status == FAIL)
	{
	  sprintf(errbuf, "Error calling HE5_GDwrrdfield() from FORTRAN wrapper.") ;
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  if (strdatabuf != NULL)
	    {
	      for (i = 0; i<nelem; i++)
		{
		  if (strdatabuf[i] != NULL)
		    {
		      free (strdatabuf[i]);
		      strdatabuf[i] = NULL;
		    }
		}
	      free (strdatabuf);
	      strdatabuf = NULL;
	    }  
	  return(FAIL);
	}
      if(numelem == 0)
	{
	  sprintf(errbuf, "Number of elements passed in cannot be zero.") ;
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  if (strdatabuf != NULL)
	    {
	      for (i = 0; i<nelem; i++)
		{
		  if (strdatabuf[i] != NULL)
		    {
		      free (strdatabuf[i]);
		      strdatabuf[i] = NULL;
		    }
		}
	      free (strdatabuf);
	      strdatabuf = NULL;
	    }
	  return(FAIL);
	}
 
      if(edge != NULL)
	{
	  numread = edge[0];
	}
      else
	{
	  numread = (dims[0] - start[0])/stride[0];
	}
 
      if(numread <= 0)
	{
	  sprintf(errbuf, "Number of elements passed in cannot be zero.") ;
	  H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_DATASET, H5E_READERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(start);
	  free(stride);
	  free(edge);
	  free(errbuf);
	  if (strdatabuf != NULL)
	    {
	      for (i = 0; i<nelem; i++)
		{
		  if (strdatabuf[i] != NULL)
		    {
		      free (strdatabuf[i]);
		      strdatabuf[i] = NULL;
		    }
		}
	      free (strdatabuf);
	      strdatabuf = NULL;
	    }
	  return(FAIL);
	}
      if(numread <=  numelem)
	{
	  num_elem_passed_out = numread;
	}
      else
	{
	  num_elem_passed_out = numelem;
	}
 
      stlen = strlen(strdatabuf[0]);
      strcpy((char *)buffer,strdatabuf[0]);
      for (j = stlen; j < elemlen; j++)
	{
	  strcat((char *)buffer," ");
	}
      for (i = 1; i < num_elem_passed_out; i++)
	{
	  strcat((char *)buffer,strdatabuf[i]);
	  stlen = strlen(strdatabuf[i]);
	  for (j = stlen; j < elemlen; j++)
	    {
	      strcat((char *)buffer," ");
	    }
	}
 

    }
  else
    {
      sprintf(errbuf, "Error calling HE5_GDfieldinfo() from FORTRAN wrapper.") ;
      H5Epush(__FILE__, "HE5_GDrdcharfld", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      status = FAIL;
    }
  
  if (start  != NULL) free(start);
  if (stride != NULL) free(stride);
  if (edge   != NULL) free(edge);
  if (errbuf != NULL) free(errbuf);
  if (strdatabuf != NULL)
    {
      for (i = 0; i<nelem; i++)
        {
	  if (strdatabuf[i] != NULL)
	    {
	      free (strdatabuf[i]);
	      strdatabuf[i] = NULL;
	    }
        }
      free (strdatabuf);
      strdatabuf = NULL;
    }


  ret = (int)status;
  return(ret);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetfill  (FORTRAN wrapper)                                 |
|                                                                             |
|  DESCRIPTION: Retrieves fill value for a specified field.                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  fieldname      char*               field name                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fillval        void                fill value                              |
|                                                                             |
|  NOTES:                                                                     |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDgetfill(int GridID, char *fieldname, void *fillval)
{
  int             ret    = FAIL;/* (int) return status variable   */

  herr_t          status = FAIL;/* routine return status variable */

  hid_t           gridID = FAIL;/* HDF5 type grid ID              */

  char            *errbuf = (char *)NULL;/* error message buffer  */
    

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetfill", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  gridID = (int)GridID;
  
  status = HE5_GDgetfillvalue(gridID, fieldname, fillval);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling HE5_GDgetfillvalue() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgetfillvalue", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
	
  free(errbuf);
  
  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrattr                                                     |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper for Writes/updates attribute in a grid.       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  attrname       char*               attribute name                          |
|  ntype          int                 attribute HDF numbertype                |
|  fortcount[]    long                Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 99   Abe Taaheri   Modified data types                                 |
|  Jun 00   D.Wynne       Updated for native datatypes                        |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|  Mar 04   S.Zhao        Modified for a character string attribute.          |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDwrattr(int GridID, char *attrname, int ntype, long fortcount[], void *datbuf)
{
  int         ret    = FAIL;	 /* (int) return status variable   */
  int         RANK   = 1;	  	 /* Rank of a dataset              */
  int         i      = 0;        /* Loop index                     */

  herr_t      status = FAIL;	 /* routine return status variable */

  hid_t       gridID = FAIL;     /* HDF5 type grid ID              */
  hid_t       dtype  = FAIL;     /* HDF5 type  data type ID        */            

  hsize_t    *count  = (hsize_t *)NULL;/* Count array (C order)    */

  char       *errbuf = (char *)NULL;   /* error message buffer     */
  char       *tempbuf = (char *)NULL;  /* temp buffer */

 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = HE5_EHconvdatatype(ntype);
  if(dtype == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_EHconvdatatype() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(RANK, sizeof(hsize_t));
  if( count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for count.\n");
      H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Reverse order of dimensions (FORTRAN -> C) */
  /* ------------------------------------------ */
  for (i = 0; i < RANK; i++)
    {
      count[i] = (hsize_t)fortcount[RANK - 1 - i];
    }

  gridID = (hid_t)GridID;
 
  if ((dtype == HE5T_CHARSTRING) || (dtype == H5T_NATIVE_CHAR) || (dtype == H5T_C_S1))
    {
      if (strlen((char *)datbuf) < count[0])
	{
	  sprintf(errbuf,"Size of databuf is less than the number of attribute elements.\n");
	  H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
 
      /* Allocate memory for temp buffer */
      /* ------------------------------- */
      tempbuf = (char * )calloc((count[0]+1), sizeof(char));
      if(tempbuf == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory for temp buffer.\n");
	  H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
 
      strncpy(tempbuf, (char *)datbuf, count[0]);
      tempbuf[count[0]] = '\0';

      status = HE5_GDwriteattr(gridID, attrname, dtype, count, tempbuf);
      if(status == FAIL)
	{
          sprintf(errbuf,"Cannot write data to the attribute \"%s\".\n", attrname);
          H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
          HE5_EHprint(errbuf, __FILE__, __LINE__);
          free(count);
          free(errbuf);
          free(tempbuf);
          return(FAIL);
	}

      free(count);
      free(errbuf);
      free(tempbuf);
    }
  else
    {
      status = HE5_GDwriteattr(gridID, attrname, dtype, count, datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot write data to the attribute \"%s\".\n", attrname);
	  H5Epush(__FILE__, "HE5_GDwrattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
      free(count);
      free(errbuf);
    }

  ret = (int)status;
  return(ret);
 
}
 
 
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrgattr                                                    |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper to write/update group attribute in a grid.    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  attrname       char*               attribute name                          |
|  ntype          int                 attribute HDF numbertype                |
|  fortcount[]    long                Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 99   Abe Taaheri   Modified data types                                 |
|  Jun 00   D.Wynne       Updated for native datatypes                        |
|  Aug 00   A.Muslimov    Updated to reflect recent datatype changes.         |
|  Mar 04   S.Zhao        Modified for a character string attribute.          |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDwrgattr(int GridID, char *attrname, int ntype, long fortcount[], void *datbuf)
{
  int         ret     = FAIL;	  /* (int) return status variable   */
  int         RANK    = 1;	  	  /* Rank of a dataset              */
  int         i       = 0;        /* Loop index                     */

  herr_t      status  = FAIL;	  /* routine return status variable */

  hid_t       gridID  = FAIL;     /* HDF5 type grid ID              */
  hid_t       dtype   = FAIL;     /* HDF5 type  data type ID        */            

  hsize_t     *count  = (hsize_t *)NULL;/* Count array (C order)    */

  char        *errbuf = (char *)NULL;   /* error message buffer     */
  char        *tempbuf = (char *)NULL;  /* temp buffer */

 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = HE5_EHconvdatatype(ntype);
  if(dtype == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_EHconvdatatype() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(RANK, sizeof(hsize_t));
  if( count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for count.\n");
      H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Reverse order of dimensions (FORTRAN -> C) */
  /* ------------------------------------------ */
  for (i = 0; i < RANK; i++)
    {
      count[i] = (hsize_t)fortcount[RANK - 1 - i];
    }

  gridID = (hid_t)GridID;
 
  if ((dtype == HE5T_CHARSTRING) || (dtype == H5T_NATIVE_CHAR) || (dtype == H5T_C_S1))
    {
      if (strlen((char *)datbuf) < count[0])
	{
	  sprintf(errbuf,"Size of databuf is less than the number of group attribute elements.\n");
	  H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
 
      /* Allocate memory for temp buffer */
      /* ------------------------------- */
      tempbuf = (char * )calloc((count[0]+1), sizeof(char));
      if(tempbuf == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory for temp buffer.\n");
	  H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
 
      strncpy(tempbuf, (char *)datbuf, count[0]);
      tempbuf[count[0]] = '\0';
 
      status = HE5_GDwritegrpattr(gridID, attrname, dtype, count, tempbuf);
      if(status == FAIL)
	{
          sprintf(errbuf,"Cannot write group attribute value.\n");
          H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
          HE5_EHprint(errbuf, __FILE__, __LINE__);
          free(count);
          free(errbuf);
          free(tempbuf);
          return(FAIL);
	}
 
      free(count);
      free(errbuf);
      free(tempbuf);
    }
  else
    {
      status = HE5_GDwritegrpattr(gridID, attrname, dtype, count, datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot write group attribute value.\n");
	  H5Epush(__FILE__, "HE5_GDwrgattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
      free(count);
      free(errbuf);
    }

  ret = (int)status;
  return(ret); 
}
 
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrlattr                                                    |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper to Write/update local attribute in a grid.    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char*               field with local attribute              |
|  attrname       char*               local attribute name                    |
|  ntype          int                 local attribute HDF numbertype          |
|  fortcount[]    long                Number of local attribute elements      |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 00   D.Wynne       Original Programmer                                 |
|  Mar 04   S.Zhao        Modified for a character string attribute.          |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDwrlattr(int GridID, char *fieldname, char *attrname, int ntype, long fortcount[], void *datbuf)
{
  int         ret     = FAIL;	  /* (int) return status variable   */
  int         RANK    = 1;	  	  /* Rank of a dataset              */
  int         i       = 0;        /* Loop index                     */

  herr_t      status  = FAIL;	  /* routine return status variable */

  hid_t       gridID  = FAIL;     /* HDF5 type grid ID              */
  hid_t       dtype   = FAIL;     /* HDF5 type  data type ID        */            

  hsize_t     *count  = (hsize_t *)NULL;/* Count array (C order)    */

  char        *errbuf = (char *)NULL;   /* error message buffer     */
  char        *tempbuf = (char *)NULL;  /* temp buffer */

 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = HE5_EHconvdatatype(ntype);
  if(dtype == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_EHconvdatatype() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_DATATYPE, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(RANK, sizeof(hsize_t));
  if( count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for count.\n");
      H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Reverse order of dimensions (FORTRAN -> C) */
  /* ------------------------------------------ */
  for (i = 0; i < RANK; i++)
    {
      count[i] = (hsize_t)fortcount[RANK - 1 - i];
    }


  gridID = (hid_t)GridID;  
 
  if ((dtype == HE5T_CHARSTRING) || (dtype == H5T_NATIVE_CHAR) || (dtype == H5T_C_S1))
    {
      if (strlen((char *)datbuf) < count[0])
	{
	  sprintf(errbuf,"Size of databuf is less than the number of local attribute elements.\n");
	  H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
 
      /* Allocate memory for temp buffer */
      /* ------------------------------- */
      tempbuf = (char * )calloc((count[0]+1), sizeof(char));
      if(tempbuf == NULL)
	{
	  sprintf(errbuf,"Cannot allocate memory for temp buffer.\n");
	  H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
 
      strncpy(tempbuf, (char *)datbuf, count[0]);
      tempbuf[count[0]] = '\0';
 
      status = HE5_GDwritelocattr(gridID, fieldname, attrname, dtype, count, tempbuf);
      if(status == FAIL)
	{
          sprintf(errbuf,"Cannot write local attribute value.\n");
          H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
          HE5_EHprint(errbuf, __FILE__, __LINE__);
          free(count);
          free(errbuf);
          free(tempbuf);
          return(FAIL);
	}
 
      free(count);
      free(errbuf);
      free(tempbuf);
    }
  else
    {
      status = HE5_GDwritelocattr(gridID, fieldname, attrname, dtype, count, datbuf);
      if(status == FAIL)
	{
	  sprintf(errbuf,"Cannot write local attribute value.\n");
	  H5Epush(__FILE__, "HE5_GDwrlattr", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(count);
	  free(errbuf);
	  return(FAIL);
	}
      free(count);
      free(errbuf);
    }

  ret = (int)status;
  return(ret); 
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDrdattr   (FORTRAN wrapper)                                 |
|                                                                             |
|  DESCRIPTION: Reads attribute from a grid.                                  |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDrdattr(int GridID, char *attrname, void *datbuf)
{
  int         ret        = FAIL;/* (int) return status variable   */

  herr_t      status     = FAIL;/* routine return status variable */

  hid_t       gridID     = FAIL;/* HDF5 type grid ID              */
 
  char        *errbuf    = (char *)NULL;/* error message buffer   */

 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDrdattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  gridID = (hid_t)GridID;

  status = HE5_GDreadattr(gridID, attrname, datbuf);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDreadattr() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDrdattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(errbuf);

  ret = (int)status;
  return(ret); 
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDrdgattr  (FORTRAN wrapper)                                 |
|                                                                             |
|  DESCRIPTION: Reads group attribute from a grid.                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDrdgattr(int GridID, char *attrname, void *datbuf)
{
  int         ret        = FAIL;/* (int) return status variable   */

  herr_t      status     = FAIL;/* routine return status variable */

  hid_t       gridID     = FAIL;/* HDF5 type grid ID              */
 
  char        *errbuf    = (char *)NULL;/* error message buffer   */

 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDrdgattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }


  gridID = (hid_t)GridID;

  status = HE5_GDreadgrpattr(gridID, attrname, datbuf);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDreadgrpattr() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDrdgattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(errbuf);

  ret = (int)status;
  return(ret); 
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDrdlattr  (FORTRAN wrapper)                                 |
|                                                                             |
|  DESCRIPTION: Reads local attribute from a grid.                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  fieldname      char                field name                              |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Aug 00   A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDrdlattr(int GridID, char *fieldname, char *attrname, void *datbuf)
{
  int         ret        = FAIL;/* (int) return status variable   */

  herr_t      status     = FAIL;/* routine return status variable */

  hid_t       gridID     = FAIL;/* HDF5 type grid ID              */
 
  char        *errbuf    = (char *)NULL;/* error message buffer   */

 
  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDrdlattr", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  gridID = (hid_t)GridID;

  status = HE5_GDreadlocattr(gridID, fieldname, attrname, datbuf);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDreadlocattr() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDrdlattr", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(errbuf);

  ret = (int)status;
  return(ret); 
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqdimsF                                                   |
|                                                                             |
|  DESCRIPTION: Returns dimension names and values defined in grid  structure |
|               (FORTRAN Wrapper)                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nDim           long                Number of defined dimensions            |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimnames       char                Dimension names (comma-separated)       |
|  dims           long                Dimension values                        |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 00   D.Wynne       Original Version                                    |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|                                                                             |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqdimsF(int GridID, char *dimnames, long dims[])
{
  long         nDim       = FAIL;           /* Number of dimensions */
  long         strbufsize = 0;              /* Size of a string     */

  hid_t        gridID     = FAIL;           /* HDF5 type grid ID    */

  int          i = 0;                       /* Loop index           */
  
  hsize_t      *tdims     = (hsize_t *)NULL;/* Dimension size array */

  char         *errbuf    = (char *)NULL;   /* error message buffer */


  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqdimsF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  
  gridID = (hid_t)GridID;
  
  nDim = HE5_GDnentries(gridID, 0, &strbufsize);
  if(nDim == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDnentries() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqdimsF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  

  tdims = (hsize_t *)calloc(nDim, sizeof(hsize_t));
  if(tdims == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for tdims.\n");
      H5Epush(__FILE__, "HE5_GDinqdimsF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
 

  nDim = HE5_GDinqdims(gridID, dimnames, tdims);
  if(nDim == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDinqdims() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqdimsF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(tdims);
      return(FAIL);
    }
 

  for(i = 0; i < nDim; i++)
    dims[i] = (long)tdims[i];
 

  free(tdims);
  free(errbuf);

  return(nDim);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdiminfoF                                                   |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper for GDdiminfo to Retrieve size of specified   |
|               dimension.                                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  size           long    None        Size of dimension                       |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        grid  structure id                      |
|  dimname        char*   None        Dimension name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/21/99  A.Muslimov    In the call to EHmetagroup() replaced the argument  |
|                         gid by fid.                                         |
|  Oct 99   Abe Taaheri   Added to convert hsize_t to integer                 |
|  Jun 00   D.Wynne       Modified to update datatype changes                 |
|  Aug 00   A.Muslimov    Modified to reflect data type changes               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long
HE5_GDdiminfoF(int GridID, char *dimname)
{
  long        size    = FAIL;        /* dimension size (return) */
  
  hid_t       gridID  = FAIL;        /* HDF5 type grid ID       */

  hsize_t     tsize   = 0;
  
  char        *errbuf = (char *)NULL;/* error message buffer    */


  /* Allocate memory for error message buffers */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdiminfoF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;
   
  tsize = HE5_GDdiminfo(gridID, dimname);
  if(tsize == 0)
    {
      sprintf(errbuf,"Error calling HE5_GDdiminfo() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdiminfoF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  

  size = (long)tsize;
  
  free(errbuf);

  return(size);
}


 
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDfldinfo                                                    |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper arount GDfieldinfo                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure id                       |
|  fieldname      char                name of field                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           long                rank of field (# of dims)               |
|  dims           long                field dimensions                        |
|  ntype          int                 field number type                       |
|  fortdimlist    char                field dimension list (FORTRAN order)    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Nov 99   Abe Taaheri   Modified for HDF5                                   |
|  Jun 00   D.Wynne       Updated to reflect datatypes changes                |
|  Aug 00   A.Muslimov    Updated to reflect data type changes                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDfldinfo(int GridID, char *fieldname, int *rank, long dims[], int *ntype, char *fortdimlist, char *fortmaxdimlist)
{
  int          ret      = SUCCEED;/* (int) return status variable   */
  int          j        = 0;      /* Loop Index                     */

  hid_t        gridID   = FAIL;   /* HDF5 type grid ID              */

  hid_t        dtype[1] = {FAIL};/* number types                    */

  herr_t       status   = SUCCEED;/* routine return status variable */
  
  hsize_t      swap     = 0;      /* Temporary variable             */
  hsize_t      tempdims[HE5_DTSETRANKMAX];
  
  /* Dimension list in C order */
  char         *dimlist    = (char *)NULL;
  char         *maxdimlist = (char *)NULL;
  char         *errbuf     = (char *)NULL;/* error message buffer  */
  
  
  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDfldinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  /* Allocate space for C order dimension list */
  /* ----------------------------------------- */
  dimlist    = (char *)calloc(HE5_HDFE_UTLBUFSIZE, sizeof(char));
  if(dimlist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for dimlist.\n");
      H5Epush(__FILE__, "HE5_GDfldinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }


  /* Allocate space for C order max dimension list */
  /* --------------------------------------------- */
  maxdimlist = (char *)calloc(HE5_HDFE_UTLBUFSIZE, sizeof(char));
  if(maxdimlist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for maxdimlist.\n");
      H5Epush(__FILE__, "HE5_GDfldinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      return(FAIL);
    }

  /* Initialize tempdims[] array */
  /* --------------------------- */
  for (j = 0; j < HE5_DTSETRANKMAX; j++)
    tempdims[j] = 0;


  /* Get field info */
  /* -------------- */
  gridID = (hid_t)GridID;
  status = HE5_GDfieldinfo(gridID, fieldname, rank, tempdims, dtype, dimlist, maxdimlist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDfieldinfo() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDfldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      free(maxdimlist);
      return(FAIL);
    }
  

  *ntype = (int)dtype[0];

  /* If no error then reverse order of dimension sizes */
  /* ------------------------------------------------- */
  if (status == SUCCEED)
    {
      for (j = 0; j < *rank / 2; j++)
        {
	  swap = tempdims[*rank - 1 - j];
	  tempdims[*rank - 1 - j] = tempdims[j];
	  tempdims[j] = swap;
        }
      /*change the datatype */
      for (j = 0; j < *rank; j++)
        {
	  dims[j] = (long)tempdims[j];
        }
 
      /* Reverse order of dimensions entries in dimension list */
      /* ----------------------------------------------------- */
      if(fortdimlist != (char *)NULL)
	{
	  status = HE5_EHrevflds(dimlist, fortdimlist);
	  if(status == FAIL)
	    {
	      sprintf(errbuf,"Error calling HE5_EHrevflds() from FORTRAN wrapper.\n");
	      H5Epush(__FILE__, "HE5_GDfldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
	}
      if(fortmaxdimlist != (char *)NULL)
	{
	  status = HE5_EHrevflds(maxdimlist, fortmaxdimlist);
	  if(status == FAIL)
	    {
	      sprintf(errbuf,"Error calling HE5_EHrevflds() from FORTRAN wrapper.\n");
	      H5Epush(__FILE__, "HE5_GDfldinfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
	      HE5_EHprint(errbuf, __FILE__, __LINE__);
	    }
	}
	   
    }

  if (maxdimlist != NULL) free(maxdimlist);
  if (dimlist    != NULL) free(dimlist);
  if (errbuf     != NULL) free(errbuf);


  ret = (int)status;
  return(ret); 
}
 

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDtileinfoF                                                  |
|                                                                             |
|  DESCRIPTION: FORTRAN wrapper for GDtileinfo                                |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char*               name of field                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  tilecode       int*                tile code                               |
|  tilerank       int*                rank of a dataset                       |
|  tiledims       long                the array containing sizes              |
|                                     of each dimension of a tile             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date         Programmer    Description                                    |
|   =========    ============  ============================================   |
|   Dec 03       S.Zhao        Original development                           |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDtileinfoF(int GridID, char *fieldname, int *tilecode, int *tilerank, long tiledims[])
{
  int           ret       = FAIL;           /* return status        */
  int           j         = 0;              /* Loop index           */
 
  herr_t        status    = FAIL;           /* return status        */
 
  hid_t         gridID   = FAIL;            /* HDF5 type grid ID    */
 
  hsize_t       tempdims[HE5_DTSETRANKMAX]; /* Temporary dimension sizes array */
  hsize_t       swap      = 0;              /* Temporary dimension size   */
 
  char          *errbuf   = (char *)NULL;   /* error message buffer */
 
  /* Allocate memory for error message buffer */
  errbuf  = (char * )calloc( HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDtileinfoF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Initialize tempdims[] array */
  /* --------------------------- */
  for ( j = 0; j < HE5_DTSETRANKMAX; j++)
    tempdims[ j ] = 0;
 
  gridID = (hid_t)GridID;
 
  status = HE5_GDtileinfo(gridID, fieldname, tilecode, tilerank, tempdims);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling GDtileinfo() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDtileinfoF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
 
  for (j = 0; j < *tilerank / 2; j++)
    {
      swap = tempdims[*tilerank - 1 - j];
      tempdims[*tilerank - 1 - j] = tempdims[j];
      tempdims[j] = swap;
    }
 
  for (j = 0; j < *tilerank; j++)
    tiledims[j] = (long)tempdims[j];
 
  free(errbuf);
 
  ret = (int)status;
  return(ret);
 
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqdatatypeF                                               |
|                                                                             |
|  DESCRIPTION: Inquires about data fields in grid  (FORTRAN Wrapper)         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                  return status (0) SUCCEED, (-1) FAIL   |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID          int     None        HDF-EOS type grid  ID                  |
|  fieldname       char *                                                     |
|  attrname        char *                                                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  type            int     None        HDF-EOS data type ID                   |
|  TypeClass       int                                                        |
|  TypeOrder       int                                                        |
|  TypeSize        long                                                       |
|                                                                             |
|  NOTES:                                                                     |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Oct 99   D.Wynne       Original Programmer                                 |
|  Dec 99   A.Muslimov    Changed the status return data type from hid_t to   |
|                         int   .                                             |
|  Feb 00   A.Muslimov    Added error checkings.                              |
|  Mar 00   A.Muslimov    Changed the ID of field group from gd_id to data_id.|
|  Mar 00   A.Muslimov    Updated to include Group/Local attributes.          |
|  5/10/00  A.Muslimov    Changed 'H5T_class_t' type to 'int' data type.      |
|  Aug 00   A.Muslimov    Updated to reflect data type changes.               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDinqdatatypeF(int GridID, char *fieldname, char *attrname, int fieldgroup, int *type, int *TypeClass, int *TypeOrder, long *TypeSize)
{
  int		   ret       = FAIL;      /* (int) return status variable  */

  herr_t	   status    = FAIL;      /* return status variable        */

  hid_t        *typeID   = NULL;      /* HDF5 type data type ID        */
  hid_t        gridID    = FAIL;      /* HDF5 type grid ID             */

  H5T_class_t  *classID  = (H5T_class_t *)NULL;/* Data type class ID   */
  H5T_order_t  *Order    = (H5T_order_t *)NULL;/* Data type byte order */

  size_t	   *tempsize = (size_t *)NULL;/* Temporary variable        */
  
  char         *errbuf   = (char *)NULL;  /* error message buffer      */
  
  
  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqdatatypeF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
  typeID = (hid_t *)calloc(1, sizeof(hid_t));
  if(typeID == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for typeID.\n");
      H5Epush(__FILE__, "HE5_GDinqdatatypeF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  classID = (H5T_class_t *)calloc(1, sizeof(H5T_class_t));
  if(classID == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for classID.\n");
      H5Epush(__FILE__, "HE5_GDinqdatatypeF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(typeID);
      return(FAIL);
    }


  Order = (H5T_order_t *)calloc(1, sizeof(H5T_order_t));
  if(Order == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for Order.\n");
      H5Epush(__FILE__, "HE5_GDinqdatatypeF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(typeID);
      free(classID);
      return(FAIL);
    }

 
  tempsize = (size_t *)calloc(1, sizeof(size_t));
  if(tempsize == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for tempsize.\n");
      H5Epush(__FILE__, "HE5_GDinqdatatypeF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(typeID);
      free(classID);
      free(Order);
      return(FAIL);
    }
  

  gridID = (hid_t)GridID;
  status = HE5_GDinqdatatype(gridID, fieldname, attrname, fieldgroup, typeID,classID, Order, tempsize);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDinqdatatype() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqdatatypeF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(typeID);
      free(classID);
      free(Order);
      free(tempsize);
      return(FAIL);
    }
  

  *type      = (int)typeID[0];
  *TypeSize  = (long)tempsize[0];
  *TypeClass = (int)classID[0];
  *TypeOrder = (int)Order[0]; 	


  free(errbuf);
  free(typeID);
  free(classID);
  free(Order);  
  free(tempsize);
  
  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqgridF   (FORTRAN wrapper)                               |
|                                                                             |
|  DESCRIPTION: Returns number and names of grid structures in file           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nGrid          long                Number of grid structures in file       |
|                                                                             |
|  INPUTS:                                                                    |
|  filename       char                HDF-EOS filename                        |
|                                                                             |
|  OUTPUTS:                                                                   |
|  gridlist       char                List of grid names (comma-separated)    |
|  strbufsize     long                Length of gridlist                      |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer    Description                                        |
|  =======   ============  ================================================   |
|  9/11/00   A.Muslimov                                                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqgridF(char *filename, char *gridlist, long *strbufsize)
{
  long           nGrid   = FAIL;	    /* Number of grid structures in file */
 
  char           *errbuf = (char *)NULL;/* error message buffer              */
  
  
  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqgridF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /* Call "HE5_GDinqgrid" routine */
  /* ------------------------ */
  nGrid = HE5_GDinqgrid(filename, gridlist, strbufsize);
  if(nGrid == FAIL)
    {
      sprintf(errbuf,"Error calling HE5_GDinqgrid() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqgridF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  free(errbuf);
  return(nGrid);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgridinfoF      (FORTRAN wrapper)                           |
|                                                                             |
|  DESCRIPTION: Returns xdim, ydim and location of upper left and lower       |
|                right corners, in meters.                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid  ID                                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  xdimsize       long                Number of columns in grid               |
|  ydimsize       long                Number of rows in grid                  |
|  upleftpt       double              Location (m/deg) of upper left corner   |
|  lowrightpt     double              Location (m/deg) of lower right corner  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  9/11/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDgridinfoF(int GridID, long *xdimsize, long *ydimsize, double upleftpt[], double lowrightpt[])
{
  int             ret      = FAIL;          /* (int) return status variable            */

  herr_t          status   = FAIL;          /* routine return status variable          */

  hid_t           gridID   = FAIL;          /* "HDFEOS" group ID                       */

  char            *errbuf = (char *)NULL;   /* buffer for error message                */
  


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgridinfoF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;


  status = HE5_GDgridinfo(gridID, xdimsize, ydimsize, upleftpt, lowrightpt);
  if(status == FAIL)
    {
      sprintf( errbuf,"Error calling \"HE5_GDgridinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgridinfoF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
  
  free(errbuf);
  
  ret = (int)status;
  
  return(ret);
}


/*----------------------------------------------------------------------------r
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqflds  (FORTRAN wrapper)                                 |
|                                                                             |
|  DESCRIPTION: Retrieve information about all data fields defined in a grid. |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nFld           int                 Number of fields in grid                |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid  ID                                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fieldlist      char*               Field names (comma-separated)           |
|  rank           int                 Array of ranks                          |
|  ntype          int                 Array of field data type class IDs      |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer    Description                                        |
|  =======   ============  =================================================  |
|  9/11/00   A.Muslimov                                                       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDinqflds(int GridID, char *fieldlist, int rank[], int ntype[])
{
  int           nFld       =  0;  /* Number of fields (return)         */
  int           i;                /* Loop index                        */

  hid_t         gridID     = FAIL;/* Grid ID                           */

  hid_t         *dtype     = (hid_t *)NULL;/* number types             */

  char          *errbuf    = (char *)NULL; /* error message buffer     */
  

  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqflds", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;


  /* Call "HE5_GDinqfields" routine to get number of fields */
  /* -------------------------------------------------- */
  nFld = HE5_GDinqfields(gridID, fieldlist, NULL, NULL);
  if (nFld == FAIL)
    {
      sprintf(errbuf, "Error calling \"HE5_GDinqfields()\" from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDinqflds", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
 
  if (nFld > 0)
    {
      dtype = (hid_t *)calloc(nFld, sizeof(hid_t));
      if (dtype == NULL)
        {
          sprintf(errbuf, "Cannot allocate memory. \n");
          H5Epush(__FILE__, "HE5_GDinqflds", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
          HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
          return(FAIL);
        }
	  
      nFld = HE5_GDinqfields(gridID, fieldlist, rank, dtype);
      if (nFld == FAIL)
	{
	  sprintf(errbuf, "Error calling \"HE5_GDinqfields()\" from FORTRAN wrapper. \n");
	  H5Epush(__FILE__, "HE5_GDinqflds", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  free(errbuf);
	  free(dtype);
	  return(FAIL);
	}

      for (i = 0; i < nFld; i++)
        ntype[ i ] = (int)dtype[i];

      free(dtype);
    } 


  free(errbuf);

  return(nFld);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDprojinfoF   (FORTRAN wrapper)                              |
|                                                                             |
|  DESCRIPTION: Returns GCTP projection code, zone code, spheroid code        |
|                and projection parameters.                                   |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grif ID                                 |
|                                                                             |
|  OUTPUTS:                                                                   |
|  projcode       int                 GCTP projection code                    |
|  zonecode       int                 UTM zone code                           |
|  spherecode     int                 GCTP spheriod code                      |
|  projparm       double              Projection parameters                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/11/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDprojinfoF(int GridID, int *projcode,  int *zonecode, int *spherecode, double projparm[])
{
  int             ret     = FAIL;        /* routine return status variable */

  herr_t          status  = FAIL;        /* routine return status variable */

  hid_t           gridID  = FAIL;        /* HDF-EOS file ID                */

  char            *errbuf = (char *)NULL;/* Buffer for error message       */ 
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDprojinfoF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDprojinfo(gridID,projcode,zonecode,spherecode,projparm);
  if (status == FAIL)
    {
      sprintf(errbuf, "Error calling \"HE5_GDprojinfo()\" from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDprojinfoF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }
  
  free(errbuf);
  ret = (int)status;
  return(ret);
}




/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefboxregionF   (FORTRAN wrapper)                          |
|                                                                             |
|  DESCRIPTION: Defines region for subsetting in a grid.                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  RegionID       int     None        Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|  cornerlon      double   dec deg    Longitude of opposite corners of box    |
|  cornerlat      double   dec deg    Latitude of opposite corners of box     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDdefboxregionF(int GridID, double cornerlon[], double cornerlat[])
{
  int             RegionID = FAIL;/* Region ID (return value)                */

  hid_t           regionID = FAIL;/* Region ID                               */
  hid_t           gridID   = FAIL;/* Grid structure ID                       */

  char            *errbuf=(char *)NULL;/* Buffer for error message           */
 

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefboxregionF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 
  gridID = (hid_t)GridID;

  regionID = HE5_GDdefboxregion(gridID, cornerlon, cornerlat);
  if (regionID == FAIL)
    {
      sprintf(errbuf, "Error calling \"HE5_GDdefboxregion()\" from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdefboxregionF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  free(errbuf);
  RegionID = (int)regionID;
  return(RegionID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreginfo                                                    |
|                                                                             |
|  DESCRIPTION: Retrieves size of region in bytes. FORTRAN Wrapper            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  RegionID       int                 Region ID                               |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 field data type class ID                |
|  rank           int                 field rank                              |
|  dims           long                dimensions of field region              |
|  size           long                size in bytes of field region           |
|  upleftpt       double              Upper left corner coord for region      |
|  lowrightpt     double              Lower right corner coord for region     |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Nov 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Modified to reflect datatype changes                |
|  Sep 00   A.Muslimov    Updated to reflect data type changes.               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDreginfo(int GridID, int RegionID, char *fieldname, int *ntype, int *rank, long dims[], long *size, double upleftpt[], double lowrightpt[])
{
  int             ret      = FAIL;       /* (int) return status variable   */  
  int		      j;                     /* Loop index                     */

  hid_t           gridID   = FAIL;       /* Grid ID                        */
  hid_t           regionID = FAIL;       /* Region ID                      */

  herr_t          status   = FAIL;       /* routine return status variable */
  
  hid_t           *dtype = (hid_t *)NULL;/* number type                    */

  hsize_t         swap   = 0;            /* Temporary swap variable        */
  hsize_t         tempdims[HE5_DTSETRANKMAX];/* Temporary dimensions array */
  
  char            *errbuf = (char *)NULL;/* Buffer for error message       */
 

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDreginfoF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
 

  gridID   = (hid_t)GridID; 
  regionID = (hid_t)RegionID;

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if (dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for dtype.\n");
      H5Epush(__FILE__, "HE5_GDreginfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 

  /* Initialize tempdims[] array */
  /* --------------------------- */
  for (j = 0; j <HE5_DTSETRANKMAX; j++)
    tempdims[j] = 0;
  

  /* Call GDregioninfo */
  /* ----------------- */
  status = HE5_GDregioninfo(gridID, regionID, fieldname, dtype, rank,tempdims, size,upleftpt,lowrightpt);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDregioninfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDreginfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    } 
  
  /* Change dimensions to FORTRAN order */
  /* ---------------------------------- */
  for (j = 0; j < *rank / 2; j++)
    {
      swap = tempdims[*rank - 1 - j];
      tempdims[*rank - 1 - j] = tempdims[j];
      tempdims[j] = swap;
    }

  /* change the dimension datatype */
  /* ----------------------------- */
  for (j = 0; j < *rank; j++)
    {
      dims[j] = (long)tempdims[j];
    }


  *ntype = (int)(*dtype);


  free(errbuf);
  free(dtype);

  ret = (int)status;  
  return(ret);
}
 
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDextractregionF    (FORTRAN wrapper)                        |
|                                                                             |
|  DESCRIPTION: Retrieves data from specified region.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|  RegionID       int                 Region ID                               |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                Data buffer containing subsetted region |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int    
HE5_GDextractregionF(int GridID, int RegionID, char *fieldname, void *buffer)
{
  int             ret      = FAIL;/* routine return status variable */

  herr_t          status   = FAIL;/* routine return status variable */

  hid_t           gridID   = FAIL;/* HDF5 type grid ID              */
  hid_t           regionID = FAIL;/* HDF5 type region ID            */

  char            *errbuf  = (char *)NULL;/* error message buffer   */

  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDextractregionF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID   = (hid_t)GridID;
  regionID = (hid_t)RegionID;

  status = HE5_GDextractregion(gridID, regionID, fieldname, buffer);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDextractregion()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDextractregionF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 

  free(errbuf);
  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDatinfo                                                     |
|                                                                             |
|  DESCRIPTION:  FORTRAN wrapper for GDattrinfo                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute datatype ID                   |
|  fortcount      long                Number of attribute elements            |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to herr_t.                                          |
|  Oct 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Updated to reflect datatype changes                 |
|  Sep 00   A.Muslimov    Updated to reflect most recent datatype changes.    |
|                                                                             |
|  END_PROLOG                                                                 |
|                                                                             |
-----------------------------------------------------------------------------*/
int
HE5_GDatinfo(int GridID, char *attrname, int *ntype, long *fortcount)
{
  int          ret     = FAIL;    /* routine return status variable */

  hid_t        gridID  = FAIL;    /* Grid ID                        */

  hid_t        *dtype  = (hid_t *)NULL;/* Data type class ID  */

  herr_t       status  = FAIL;    /* routine return status variable */
  
  hsize_t      *count  = (hsize_t *)NULL;/* C-order count array     */
  
  char         *errbuf = (char *)NULL;   /* error message buffer    */
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDattrinfo(gridID, attrname, dtype, count);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDattrinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDatinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(count);
      free(dtype);
      return(FAIL);
    } 
  
  *fortcount = (long)(*count);
  *ntype     = (int)(*dtype);
  

  free(errbuf);
  free(dtype);
  free(count);
  
  ret = (int)status;
  return(ret);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDatinfo2                                                    |
|                                                                             |
|  DESCRIPTION:  FORTRAN wrapper for GDattrinfo2                              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute datatype ID                   |
|  fortcount      long                Number of attribute elements            |
|  size           long                buf size of attribute elements          |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to herr_t.                                          |
|  Oct 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Updated to reflect datatype changes                 |
|  Sep 00   A.Muslimov    Updated to reflect most recent datatype changes.    |
|                                                                             |
|  END_PROLOG                                                                 |
|                                                                             |
-----------------------------------------------------------------------------*/
int
HE5_GDatinfo2(int GridID, char *attrname, int *ntype, long *fortcount, long *fortsize)
{
  int          ret     = FAIL;    /* routine return status variable */

  hid_t        gridID  = FAIL;    /* Grid ID                        */

  hid_t        *dtype  = (hid_t *)NULL;/* Data type class ID  */

  herr_t       status  = FAIL;    /* routine return status variable */
  
  hsize_t      *count  = (hsize_t *)NULL;/* C-order count array     */
  hsize_t      *size   = (hsize_t *)NULL;/* size  of array element  */
  char         *errbuf = (char *)NULL;   /* error message buffer    */
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }

  size = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(size == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"size\".\n");
      H5Epush(__FILE__, "HE5_GDatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  gridID = (hid_t)GridID;

  status = HE5_GDattrinfo2(gridID, attrname, dtype, count, size);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDattrinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDatinfo2", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(count);
      free(dtype);
      return(FAIL);
    } 
  
  *fortcount = (long)(*count);
  *fortsize  = (long)(*size);
  *ntype     = (int)(*dtype);
  

  free(errbuf);
  free(dtype);
  free(count);
  free(size);
  
  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgatinfo                                                    |
|                                                                             |
|  DESCRIPTION:  FORTRAN wrapper for GDgrpattrinfo                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute datatype class ID             |
|  fortcount      long                Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to herr_t.                                          |
|  Oct 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Updated to reflect datatype changes                 |
|  Sep 00   A.Muslimov    Updated to include most recent datatype changes.    |
|                                                                             |
|  END_PROLOG                                                                 |
|                                                                             |
-----------------------------------------------------------------------------*/
int
HE5_GDgatinfo(int GridID, char *attrname, int *ntype, long *fortcount)
{
  int          ret     = FAIL;    /* routine return status variable */

  hid_t        gridID  = FAIL;    /* Grid ID                        */

  hid_t        *dtype  = (hid_t *)NULL;/* Data type class ID  */

  herr_t       status  = FAIL;    /* routine return status variable */
  
  hsize_t      *count  = (hsize_t *)NULL;/* C-order count array     */
  
  char         *errbuf = (char *)NULL;   /* error message buffer    */
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDgatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDgatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDgrpattrinfo(gridID, attrname, dtype, count);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDgrpattrinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgatinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(count);
      free(dtype);
      return(FAIL);
    } 
  
  
  *fortcount = (long)(*count);
  *ntype     = (int)(*dtype);
  

  free(errbuf);
  free(count);
  free(dtype);

  ret = (int)status;
  return(ret);  
}
 

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgatinfo2                                                   |
|                                                                             |
|  DESCRIPTION:  FORTRAN wrapper for GDgrpattrinfo2                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute datatype class ID             |
|  fortcount      long                Number of attribute elements            |
|  fortsize       long                buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to herr_t.                                          |
|  Oct 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Updated to reflect datatype changes                 |
|  Sep 00   A.Muslimov    Updated to include most recent datatype changes.    |
|                                                                             |
|  END_PROLOG                                                                 |
|                                                                             |
-----------------------------------------------------------------------------*/
int
HE5_GDgatinfo2(int GridID, char *attrname, int *ntype, long *fortcount, long *fortsize)
{
  int          ret     = FAIL;    /* routine return status variable */

  hid_t        gridID  = FAIL;    /* Grid ID                        */

  hid_t        *dtype  = (hid_t *)NULL;/* Data type class ID  */

  herr_t       status  = FAIL;    /* routine return status variable */
  
  hsize_t      *count  = (hsize_t *)NULL;/* C-order count array     */
  
  hsize_t      *size   = (hsize_t *)NULL;/* size of array elements  */
  
  char         *errbuf = (char *)NULL;   /* error message buffer    */
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDgatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDgatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
    
  size = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(size == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"size\".\n");
      H5Epush(__FILE__, "HE5_GDgatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDgrpattrinfo2(gridID, attrname, dtype, count, size);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDgrpattrinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgatinfo2", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(count);
      free(dtype);
      return(FAIL);
    } 
  
  
  *fortcount = (long)(*count);
  *fortsize  = (long)(*size);
  *ntype     = (int)(*dtype);
  

  free(errbuf);
  free(count);
  free(size);
  free(dtype);

  ret = (int)status;
  return(ret);  
}
 

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDlatinfo                                                    |
|                                                                             |
|  DESCRIPTION:  FORTRAN wrapper for GDlocattrinfo                            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char*               attribute name                          |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute data type class ID            |
|  fortcount      long                Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to herr_t.                                          |
|  Oct 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Updated to reflect datatype changes                 |
|  Sep 00   A.Muslimov    Updated to reflect most recent datatype changes.    |
|                                                                             |
|  END_PROLOG                                                                 |
|                                                                             |
-----------------------------------------------------------------------------*/
int
HE5_GDlatinfo(int GridID, char *fieldname, char *attrname, int *ntype, long *fortcount)
{
  int          ret     = FAIL;    /* routine return status variable */

  hid_t        gridID  = FAIL;    /* Grid ID                        */

  hid_t        *dtype  = (hid_t *)NULL;/* Data type class ID  */

  herr_t       status  = FAIL;    /* routine return status variable */
  
  hsize_t      *count  = (hsize_t *)NULL;/* C-order count array     */
  
  char         *errbuf = (char *)NULL;   /* error message buffer    */
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDlatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDlatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDlatinfo", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDlocattrinfo(gridID, fieldname, attrname, dtype, count);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDlocattrinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDlatinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(count);
      free(dtype);
      return(FAIL);
    } 
  
  
  *fortcount = (long)(*count);
  *ntype     = (int)(*dtype);
  
  free(errbuf);
  free(count);
  free(dtype);

  ret = (int)status;
  return(ret);  
}
 

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDlatinfo2                                                   |
|                                                                             |
|  DESCRIPTION:  FORTRAN wrapper for GDlocattrinfo2                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char*               attribute name                          |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute data type class ID            |
|  fortcount      long                Number of attribute elements            |
|  fortsize       long                buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/28/99  A.Muslimov    Changed the type of return value from intn          |
|                         to herr_t.                                          |
|  Oct 99   Abe Taaheri   Added for HDF5                                      |
|  Jun 00   D.Wynne       Updated to reflect datatype changes                 |
|  Sep 00   A.Muslimov    Updated to reflect most recent datatype changes.    |
|                                                                             |
|  END_PROLOG                                                                 |
|                                                                             |
-----------------------------------------------------------------------------*/
int
HE5_GDlatinfo2(int GridID, char *fieldname, char *attrname, int *ntype, long *fortcount, long *fortsize)
{
  int          ret     = FAIL;    /* routine return status variable */

  hid_t        gridID  = FAIL;    /* Grid ID                        */

  hid_t        *dtype  = (hid_t *)NULL;/* Data type class ID  */

  herr_t       status  = FAIL;    /* routine return status variable */
  
  hsize_t      *count  = (hsize_t *)NULL;/* C-order count array     */
  
  hsize_t      *size   = (hsize_t *)NULL;/* size of  array elements */
  
  char         *errbuf = (char *)NULL;   /* error message buffer    */
  
  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDlatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDlatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  
  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDlatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  
  size = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(size == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"size\".\n");
      H5Epush(__FILE__, "HE5_GDlatinfo2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dtype);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  status = HE5_GDlocattrinfo2(gridID, fieldname, attrname, dtype, count, size);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDlocattrinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDlatinfo", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(count);
      free(dtype);
      return(FAIL);
    } 
  
  
  *fortcount = (long)(*count); 
  *fortsize  = (long)(*size);
  *ntype     = (int)(*dtype);
  
  free(errbuf);
  free(count);
  free(size);
  free(dtype);

  ret = (int)status;
  return(ret);  
}
 

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDorigininfoF   (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION: Returns origin code                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|                                                                             |
|  OUTPUTS:                                                                   |
|  origincode     int                 Grid origin code                        |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/11/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDorigininfoF(int GridID, int *origincode)
{
  int             ret      = FAIL;     /* routine return status variable */

  herr_t          status   = FAIL;     /* routine return return status   */  
  
  hid_t           gridID   = FAIL;     /* HDF5 type grid ID              */

  char            *errbuf  = (char *)NULL;/* Buffer for error message    */ 
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDorigininfoF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  status = HE5_GDorigininfo(gridID,origincode);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDorigininfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDorigininfoF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 
  

  free(errbuf);
  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDpixreginfoF   (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|  pixregcode     int       None      Pixel registration code                 |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDpixreginfoF(int GridID, int *pixregcode)
{
  int             ret      = FAIL;      /* routine return status variable */

  herr_t          status   = FAIL;      /* routine return status variable */

  hid_t           gridID   = FAIL;      /* HDF5 type grid ID              */

  char            *errbuf  = (char *)NULL;/* Buffer for error message     */ 
 

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDpixreginfoF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;
  
  status = HE5_GDpixreginfo(gridID, pixregcode);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDpixreginfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDpixreginfoF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 
  

  free(errbuf);

  ret = (int)status;
  return(ret);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDcompinfoF    (FORTRAN wrapper)                             |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|  fieldname      char*   None                                                |
|  compcode       int*    None                                                |
|  compparm       int     none                                                |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|  June 03  S.Zhao        Changed the type of compcode from *char to *int.    |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int      
HE5_GDcompinfoF(int GridID, char *fieldname, int *compcode, int compparm[])
{
  int             ret      = FAIL;         /* routine return status variable */

  herr_t          status   = FAIL;         /* routine return status variable */

  hid_t           gridID   = FAIL;         /* HDF-EOS file ID                */

  char            *errbuf  = (char *)NULL; /* buffer for error message       */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDcompinfoF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  status = HE5_GDcompinfo(gridID, fieldname, compcode, compparm);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDcompinfo()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDcompinfoF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 
  

  free(errbuf);
  ret = (int)status;
  return(ret);
}
  

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDnentriesF   (FORTRAN wrapper)                              |
|                                                                             |
|  DESCRIPTION: Returns number of entries and descriptive string buffer       |
|                size for a specified entity.                                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nEntr          long                Number of entries                       |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|  entrycode      int     None        Entry code                              |
|                                     HDFE_NENTDIM  (0)                       |
|                                     HDFE_NENTDFLD (4)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                Length of comma-separated list          |
|                                     (Does not include null-terminator)      |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDnentriesF(int GridID, int entrycode, long *strbufsize)
{
  long            nEntr    = FAIL;/* Return number of entries        */  

  hid_t           gridID   = FAIL;/* HDF5 type grid ID               */

  char            *errbuf  =  (char *)NULL;/*  error message buffer  */
     

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDnentriesF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  nEntr = HE5_GDnentries(gridID, entrycode, strbufsize);
  if (nEntr == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDnentries()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDnentriesF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 

  free(errbuf);

  return(nEntr);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqattrsF   (FORTRAN wrapper)                              |
|                                                                             |
|  DESCRIPTION:                                                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqattrsF(int GridID, char *attrnames, long *strbufsize)
{  
  long            nattr    = FAIL;/* Number of attributes            */

  hid_t           gridID   = FAIL;/* HDF5 type grid ID               */
 
  char            *errbuf  = (char *)NULL;/* error message buffer    */
  

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqattrsF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  nattr = HE5_GDinqattrs(gridID, attrnames, strbufsize);
  if (nattr == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDinqattrs()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqattrsF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 

  free(errbuf);
  return(nattr);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqgrpattrsF   (FORTRAN wrappers)                          |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of attributes and string length of      |
|                attribute list associated with "Data Fields" group in a grid.|
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqgrpattrsF(int GridID, char *attrnames, long *strbufsize)
{
  long       nattr         = FAIL;/* Number of attributes (return)  */

  hid_t      gridID        = FAIL;/* HDF5 type Grid ID              */

  char       *errbuf;             /* Buffer for error message       */
 

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqgrpattrsF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;
  
  nattr = HE5_GDinqgrpattrs(gridID, attrnames, strbufsize);
  if (nattr == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDinqgrpattrs()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqgrpattrsF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 


  free(errbuf);
  return(nattr);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqlocattrsF     (FORTRAN wrapper)                         |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of attributes and string length of      |
|                attribute list associated with a specified field in a grid.  |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        Grid ID                                 |
|  fieldname      char                field name                              |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqlocattrsF(int GridID, char *fieldname, char *attrnames, long *strbufsize)
{
  long       nattr         = FAIL;/* Number of attributes (return)  */

  hid_t      gridID        = FAIL;/* HDF5 type grid ID              */

  char       *errbuf;		      /* Buffer for error message       */

 
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinqlocattrsF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  gridID = (hid_t)GridID;

  nattr = HE5_GDinqlocattrs(gridID, fieldname, attrnames, strbufsize);
  if (nattr == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDinqlocattrs()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinqlocattrsF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 


  free(errbuf);
  return(nattr);  
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdeftimeperiodF     (FORTRAN wrapper)                       |
|                                                                             |
|  DESCRIPTION: Finds elements of the "Time" field within a given time        |
|               period.                                                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  PeriodID       int                 Period ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|  PeriodID       int                 Period ID                               |
|  starttime      double  TAI sec     Start of time period                    |
|  stoptime       double  TAI sec     Stop of time period                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDdeftimeperiodF(int GridID, int PeriodID, double starttime, double stoptime)
{
  hid_t      gridID   = FAIL;/* HDF5 type Grid ID    */
  hid_t      periodID = FAIL;/* HDF5 type period ID  */

  char       *errbuf = NULL; /* Error message buffer */

  
  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdeftimeperiodF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  periodID = HE5_GDdeftimeperiod(gridID, periodID, starttime, stoptime);
  if (periodID == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDdeftimeperiod()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdeftimeperiodF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 
  PeriodID = (int)periodID;


  free(errbuf);
  return(PeriodID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefvrtregionF    (FORTRAN wrapper)                         |
|                                                                             |
|  DESCRIPTION: Finds elements of a monotonic field within a vertical subset  |
|               region.                                                       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  RegionID       int     None        Region ID                               |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|  RegionID       int                 Region ID                               |
|  vertObj        char                Vertical object to subset               |
|  range          double              Vertical subsetting range               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDdefvrtregionF(int GridID, int RegionID, char *vertObj, double range[])
{
  hid_t           regionID = FAIL;        /* Region ID                */
  hid_t           gridID   = FAIL;        /* HDF5 type Grid ID        */
  
  char	          *errbuf  = (char *)NULL;/* buffer for error message */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefvrtregionF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  regionID = HE5_GDdefvrtregion(gridID, regionID, vertObj, range);
  if (regionID == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDdefvrtregion()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdefvrtregionF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 
  
  RegionID = (int)regionID;
  return(RegionID);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdupregionF    (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION: Duplicates a region                                           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  newRegionID    int                 New region ID                           |
|                                                                             |
|  INPUTS:                                                                    |
|  oldRegionID    int                 Old region ID                           |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDdupregionF(int oldRegionID)
{
  int             newRegionID = FAIL;   /* (int) New Region ID  */

  hid_t           newregionID = FAIL;   /* New region ID        */
  hid_t           oldregionID = FAIL;   /* Old region ID        */
  
  char	          *errbuf  = (char *)NULL;/* error message buff */


  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdupregionF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  oldregionID = (hid_t)oldRegionID;

  newregionID = HE5_GDdupregion(oldregionID);
  if (newregionID == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDdupregion()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdupregionF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 

  free(errbuf);

  newRegionID = (int)newregionID;
  return(newRegionID);
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetpixelsF     (FORTRAN wrapper)                           |
|                                                                             |
|  DESCRIPTION: Finds row and columns for specified lon/lat values            |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|  nLonLat        long                Number of lonlat values                 |
|  lonVal         double   dec deg    Longitude values                        |
|  latVal         double   dec deg    Latitude values                         |
|                                                                             |
|  OUTPUTS:                                                                   |
|  pixRow         long                Pixel rows                              |
|  pixCol         long                Pixel columns                           |
|                                                                             |
|    Date     Programmer   Description                                        |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int  
HE5_GDgetpixelsF(int GridID, long nLonLat, double lonVal[], double latVal[], long pixRow[], long pixCol[])
{
  int             ret        = FAIL;/* routine return status variable */

  herr_t          status     = FAIL;/* routine return status variable */

  hid_t           gridID     = FAIL;/* HDF5 type grid ID              */

  char            *errbuf    = NULL;/* buffer for error message       */



  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetpixelsF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  gridID = (hid_t)GridID;

  status = HE5_GDgetpixels(gridID, nLonLat, lonVal, latVal, pixRow, pixCol);
  if (status == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDgetpixels()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgetpixelsF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 


  free(errbuf);

  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetpixvaluesF   (FORTRAN wrapper)                          |
|                                                                             |
|  DESCRIPTION: Retrieves data from specified pixels.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  BufSize        long      bytes     Size of data buffer                     |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|  nPixels        long                Number of pixels                        |
|  pixRow         long                Pixel row numbers                       |
|  pixCol         long                Pixel column numbers                    |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  buffer         void                Data buffer                             |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDgetpixvaluesF(int GridID, long nPixels, long pixRow[], long pixCol[], char *fieldname, void *buffer)
{
  long              BufSize = FAIL;/* Return value of a buffer size    */

  hid_t             gridID  = FAIL;/* HDF5 type grid ID                */
  
  char              *errbuf = (char *)NULL;/* buffer for error message */	
  
  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetpixvaluesF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;
  
  BufSize = HE5_GDgetpixvalues(gridID, nPixels, pixRow, pixCol, fieldname, buffer);  
  if (BufSize == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDgetpixvalues()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgetpixvaluesF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 

  free(errbuf);
  return(BufSize);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinterpolateF   (FORTRAN wrapper)                           |
|                                                                             |
|  DESCRIPTION: Performs bilinear interpolate on a set of xy values           |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  BufSize         long                Size of data buffer (bytes)            |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|  nValues        long                Number of lon/lat points to interpolate |
|  xyValues       double              XY values of points to interpolate      |
|  fieldname      char*               Fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  interpVal      double              Interpolated Data Values                |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  9/12/00  A.Muslimov                                                        |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinterpolateF(int GridID, long nValues, double lonVal[], double latVal[], char *fieldname, double interpVal[])
{
  long              BufSize  = FAIL;/* Number of data values returned */

  hid_t             gridID   = FAIL;/* HDF5 type grid ID              */

  char              *errbuf  = NULL;/* Error message buffer           */
    

  /* Allocate memory for error message buffer */
  /* ---------------------------------------- */
  errbuf = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDinterpolateF", __LINE__, H5E_FILE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  gridID = (hid_t)GridID;

  BufSize = HE5_GDinterpolate(gridID, nValues, lonVal, latVal, fieldname, interpVal);
  if (BufSize == FAIL)
    {
      sprintf(errbuf,"Error calling \"HE5_GDinterpolate()\" from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDinterpolateF", __LINE__, H5E_ARGS, H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    } 


  free(errbuf);
  return(BufSize);
}  


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefcomtileF    (FORTRAN wrapper)                           |
|                                                                             |
|  DESCRIPTION: Defines compression type and parameters and sets tiling/      |
|                                                       chunking              |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int     None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int     None        HDF-EOS type grid  ID                   |
|  compcode       int                 compression code                        |
|  compparm[]     int                 compression parameters                  |
|  tilerank       int                 number of tiling dimensions             |
|  tiledims       long                tiling dimensions                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|  None                                                                       |
|                                                                             |
|   Date     Programmer    Description                                        |
|  ========  ============  =================================================  |
|  10/25/00  A.Muslimov    Original development.                              |
|  01/16/01  A.Muslimov    Added FORTRAN to C dimension order conversion.     |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDdefcomtileF(int GridID, int compcode, int compparm[], int tilerank, long *tiledims )
{
  int		ret     = FAIL;           /* (int) return status  */
  int		i = 0;                    /* Loop index           */

  hid_t     gridID  = FAIL;           /* HDF5 type grid ID    */

  herr_t	status  = FAIL;           /* return status        */

  hsize_t	*tdims  = (hsize_t *)NULL;/* size variable        */  

  char      *errbuf = (char *)NULL;   /* error message buffer */


  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDdefcomtileF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
  
  
  tdims = (hsize_t *)calloc(tilerank, sizeof(hsize_t));
  if(tdims == (hsize_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for tdims.\n");
      H5Epush(__FILE__, "HE5_GDdefcomtileF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }  
  
  /* Convert from FORTRAN to C dimension order */
  /* ----------------------------------------- */
  for(i = 0; i < tilerank; i++)
    tdims[i] = (hsize_t)tiledims[tilerank - 1 - i];
  

  gridID = (hid_t)GridID;

  /* call HE5_GDdefcomtile() */
  /* ----------------------- */
  status = HE5_GDdefcomtile(gridID, compcode, compparm, tilerank, tdims);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling HE5_GDdefcomtile() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDdefcomtileF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(tdims);
      return(FAIL);
    }
 
  
  free(tdims);
  free(errbuf);

  ret = (int)status;
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetextdataF      (FORTRAN wrapper)                         |
|                                                                             |
|  DESCRIPTION: Sets external data files.                                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  ret            int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         int                 grid  structure ID                      |
|  fortfilelist   char*               list of external files (FORTRAN order)  |
|  offset         long                array of offsets (in bytes) from the    |
|                                     beginning of the file to the location   |
|                                     in the file where the data starts       |
|  size           long                array of sizes (in bytes) reserved in   |
|                                     the file for the data.                  |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 01   A.Muslimov    Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDsetextdataF(int GridID, char *fortfilelist, long offset[], long size[])
{
  int             ret          = FAIL;           /* return status variable */

  herr_t          status       = FAIL;           /* Return status variable */
  hid_t           gridID       = FAIL;           /* Grid  HDF5 type ID     */
  
  off_t           *off         = (off_t *)NULL;  /* Array of data offsets  */
  
  long            nentries     = 0;              /* Number of list entries */
  long            i;                             /* Loop index             */
  
  hsize_t         *sz          = (hsize_t *)NULL;/* Array of data sizes    */

  char            *filelist    = (char *)NULL;   /* Files list (C order)   */
  char            *errbuf      = (char *)NULL;   /* error message buffer   */


  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }
    
  

  /* Allocate space for C order file list */
  /* ------------------------------------ */
  filelist = (char *)calloc(HE5_HDFE_UTLBUFSIZE, sizeof(char));
  if(filelist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for input list.\n");
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Reverse entries in input list */
  /* ----------------------------- */
  status = HE5_EHrevflds(fortfilelist, filelist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot reverse entries in file list.\n");
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      return(FAIL);
    }


  /* Parse the list of entries to get number of files */
  /* ------------------------------------------------ */
  nentries = HE5_EHparsestr(filelist, ',', NULL, NULL);
  if(nentries <= 0)
    {
      sprintf(errbuf,"Cannot parse the input list/input list is empty.\n");
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      return(FAIL);
    }
  

  /* Allocate space for offset array */
  /* ------------------------------- */
  off = (off_t *)calloc(nentries, sizeof(off_t));
  if(off == (off_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for input offset array.\n");
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      return(FAIL);
    }

  /* Allocate space for size array */
  /* ----------------------------- */
  sz = (hsize_t *)calloc(nentries, sizeof(hsize_t));
  if(sz == (hsize_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for input size array.\n");
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      free(off);
      return(FAIL);
    }

  /* Copy the elements of input arrays */
  /* --------------------------------- */
  for (i = 0; i < nentries; i++)
    {
      off[ i ] = (off_t)offset[ i ]; 
      sz[ i ]  = (hsize_t)size[ i ];
    }


  gridID = (hid_t)GridID;

  /* Call the C function */
  /* ------------------- */
  status = HE5_GDsetextdata(gridID, filelist, off, sz);
  if (status == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDsetextdata from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDsetextdataF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      free(off);
      free(sz);
      return(FAIL);
    }

  if (filelist != NULL) free(filelist);
  if (off != NULL) free(off);
  if (sz != NULL) free(sz);

  free(errbuf);

  ret = (int)status;
  return(ret);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetextdataF       (FORTRAN wrapper)                        |
|                                                                             |
|  DESCRIPTION: Gets external data files information.                         |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nfiles         int                 number of external files  SUCCEED,      |
|                                               (-1) FAIL                     |
|  INPUTS:                                                                    |
|  GridID         int                 Grid  structure ID                      |
|  fieldname      char*               External field name                     |
|                                                                             |
|  OUTPUTS:                                                                   |
|  namelength     long                Length of each name entry               |
|  fortfilelist   char*               List of file names (FORTRAN order)      |
|  offset         long                array of offsets (in bytes) from the    |
|                                     beginning of the file to the location   |
|                                     in the file where the data starts       |
|  size           long                array of sizes (in bytes) reserved in   |
|                                     the file for the data.                  |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Apr 01   A.Muslimov    Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDgetextdataF(int GridID, char *fieldname, long namelength, char *fortfilelist, long offset[], long size[])
{
  int             nfiles       = FAIL;           /* number of files (return) */
  int             i;                             /* Loop index               */

  herr_t          status       = FAIL;           /* Return status variable   */
  hid_t           gridID       = FAIL;           /* Grid HDF5 type ID        */
  
  off_t           *off         = (off_t *)NULL;  /* Array of data offsets    */

  hsize_t         *sz          = (hsize_t *)NULL;/* Array of sizes           */

  size_t          nmlen        = 0;              /* Each entry string length */ 

  char            *filelist    = (char *)NULL;   /* Files list (C order)     */
  char            *errbuf      = (char *)NULL;   /* error message buffer     */


  /* Allocate memory for error buffer */
  /* -------------------------------- */
  errbuf = (char *)calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDgetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }


  /* Allocate space for C order output file list */
  /* ------------------------------------------- */
  filelist = (char *)calloc(HE5_HDFE_UTLBUFSIZE, sizeof(char));
  if(filelist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for output list.\n");
      H5Epush(__FILE__, "HE5_GDgetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }


  /* Allocate space for offset array */
  /* ------------------------------- */
  off = (off_t *)calloc(HE5_FLDNUMBERMAX , sizeof(off_t));
  if(off == (off_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for input offset array.\n");
      H5Epush(__FILE__, "HE5_GDgetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      return(FAIL);
    }

  /* Allocate space for size array */
  /* ----------------------------- */
  sz = (hsize_t *)calloc(HE5_FLDNUMBERMAX, sizeof(hsize_t));
  if(sz == (hsize_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for input size array.\n");
      H5Epush(__FILE__, "HE5_GDgetextdataF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      free(off);
      return(FAIL);
    }
  
  gridID = (hid_t)GridID;

  nmlen = (size_t)namelength;
  
  /* Call the C function */
  /* ------------------- */
  nfiles = HE5_GDgetextdata(gridID, fieldname, nmlen, filelist, off, sz);
  if (nfiles == FAIL)
    {
      sprintf(errbuf, "Error calling HE5_GDgetextdata from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDgetextdataF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      free(off);
      free(sz);
      return(FAIL);
    }

  /* Reverse entries in output list */
  /* ----------------------------- */
  status = HE5_EHrevflds(filelist, fortfilelist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot reverse entries in output file list.\n");
      H5Epush(__FILE__, "HE5_GDgetextdataF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(filelist);
      free(off);
      free(sz);
      return(FAIL);
    }
  
  /* Populate the output arrays */
  /* -------------------------- */
  for (i = 0; i < nfiles; i++)
    {
      offset[ nfiles - 1 - i ] = (long)off[ i ];
      size[ nfiles - 1 - i ]   = (long)sz[ i ];
    }

  if (filelist != NULL) free(filelist);
  if (off != NULL) free(off);
  if (sz != NULL) free(sz);

  
  free(errbuf);
  
  return(nfiles);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetaliasF    (FORTRAN wrapper)                             |
|                                                                             |
|  DESCRIPTION:  Defines alias for a specified field name                     |
|                                                                             |
|                                                                             |
|  Return Value    Type        Units       Description                        |
|  ============   ===========  =========   =================================  |
|  ret            int                      Return status                      |
|                                                                             |
|  INPUTS:                                                                    |
|   GridID        int                      Grid structure ID                  |
|   fieldname     char                     Original field name                |
|                                                                             |
|  OUTPUTS:                                                                   |
|   fortaliaslist char                     Comma separated list of aliases    |
|                                          for the field name                 |
|                                                                             |
|  NOTES:                                                                     |
|    None                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDsetaliasF(int GridID, char *fieldname, char *fortaliaslist)
{
  int      ret        = FAIL;/* (int)Return status variable */
 
  herr_t   status     = FAIL;/* return status variable      */
 
  hid_t    gridID     = FAIL;/* HDF5 type grid ID           */
 
  char     *aliaslist = NULL;/* C-order list of aliases     */
  char     errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer  */
 
  gridID = (hid_t)GridID;
 
  /* Allocate space for C order alias list */
  /* ------------------------------------- */
  aliaslist = (char *)calloc(strlen(fortaliaslist) + 1, sizeof(char));
  if(aliaslist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for aliaslist.\n");
      H5Epush(__FILE__, "HE5_GDsetaliasF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  /* Reverse entries in alias list (FORTRAN -> C) */
  /* -------------------------------------------- */
  status = HE5_EHrevflds(fortaliaslist, aliaslist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot reverse entries in alias list.\n");
      H5Epush(__FILE__, "HE5_GDsetaliasF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(aliaslist);
      return(FAIL);
    }
 
 
 
  /* Call GDsetalias() */
  /* ----------------- */
  status = HE5_GDsetalias(gridID, fieldname, aliaslist);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling GDsetalias() from FORTRAN wrapper. \n");
      H5Epush(__FILE__, "HE5_GDsetaliasF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(aliaslist);
      return(FAIL);
    }
 
  free(aliaslist);
 
  ret = (int)status;
  return(ret);
}
 
/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdropaliasF    (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION:  Removes the alias for a specified field name                 |
|                                                                             |
|                                                                             |
|  Return Value    Type        Units       Description                        |
|  ============   ===========  =========   =================================  |
|  ret            int                      Return status                      |
|                                                                             |
|  INPUTS:                                                                    |
|    GridID       int                      Grid structure ID                  |
|    aliasname    char                     Alias name to remove               |
|    fldgroup     int                      Field group flag                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|    None                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDdropaliasF(int GridID, int fldgroup, char *aliasname)
{ 
  int      ret        = FAIL;/* (int)Return status variable */
 
  herr_t   status     = FAIL;/* return status variable      */
 
  hid_t    gridID     = FAIL;/* HDF5 type grid ID           */
 
  char     errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer  */
 
  gridID = (hid_t)GridID;
 
  status = HE5_GDdropalias(gridID, fldgroup, aliasname);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling GDdropalias() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDdropaliasF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  ret = (int)status;
 
  return(ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDaliasinfoF    (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION:  Retrieves information about field aliases                    |
|                                                                             |
|                                                                             |
|  Return Value    Type        Units       Description                        |
|  ============   ===========  =========   =================================  |
|  ret            int                      Return status                      |
|                                                                             |
|  INPUTS:                                                                    |
|    GridID       int                      Grid structure ID                  |
|    aliasname    char                     alias name                         |
|    fldgroup     int                      Field group flag                   |
|                                                                             |
|  OUTPUTS:                                                                   |
|    length       int                      Buffer size                        |
|    buffer       char                     Buffer with original field name    |
|                                                                             |
|  NOTES:                                                                     |
|    None                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  =======  ============  =================================================   |
|  Apr 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int   
HE5_GDaliasinfoF(int GridID, int fldgroup, char *aliasname, int *length, char *buffer)
{
  int           ret        = FAIL;/* (int) return status variable          */
 
  herr_t        status     = FAIL;/* return status variable                */
 
  hid_t         gridID     = FAIL;/* HDF5 type grid ID                     */
 
  char          errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer        */
 
  gridID = (hid_t)GridID;
 
  status = HE5_GDaliasinfo(gridID, fldgroup, aliasname, length, buffer);
  if(status == FAIL)
    {
      sprintf(errbuf,"Error calling GDaliasinfo() from FORTRAN wrapper.\n");
      H5Epush(__FILE__, "HE5_GDaliasinfoF", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }
 
  ret = (int)status;
 
  return(ret); 
 
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqfldaliasF (FORTRAN wrapper)                             |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of fields & aliases and string length of|
|                fields & aliases list in "Data Fields" group                 |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nfldalias      long                Number of fields & aliases in "Data     |
|                                     Fields"  group.                         |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 Grid structure ID                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  fldalias       char*               Fields & aliases names in "Data Fields" |
|                                     group (Comma-separated list)            |
|  strbufsize     long*               Fields & aliases name list string length|
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jul 04    S.Zhao       Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long
HE5_GDinqfldaliasF(int GridID, char *fldalias, long *strbufsize)
{
  long            nfldalias   = FAIL;     /* Number of fields & aliases (return)  */

  hid_t           gridID = FAIL;          /* HDF5 type grid ID                */

  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer       */

  gridID = (hid_t)GridID;

  nfldalias = HE5_GDinqfldalias(gridID, fldalias, strbufsize);
  if ( nfldalias < 0 )
    {
      sprintf(errbuf, "Cannot retrieve the fields & aliases. \n");
      H5Epush(__FILE__, "HE5_GDinqfldaliasF", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return(nfldalias);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDwrmeta                                                     |
|                                                                             |
|  DESCRIPTION: Defines structural metadata for pre-existing field            |
|               within grid structure (FORTRAN)                               |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fieldname      char                fieldname                               |
|  fortdimlist    char                Dimension list (comma-separated list)   |
|                                         FORTRAN dimesion order              |
|  ntype          int                 field type                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 05    S. Zhao      Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDwrmeta(int GridID, char *fieldname, char *fortdimlist, int ntype)
{
  int       ret        = FAIL;   /* (int) return status variable   */
  herr_t    status     = FAIL;   /* routine return status variable */

  hid_t     gridID     = FAIL;   /* HDF5 type grid ID              */
  hid_t     numbertype = FAIL;   /* HDF5 type data type ID         */

  char      *dimlist = (char *)NULL;   /* Dimension list (C order) */
  char      *errbuf  = (char *)NULL;   /* error message buffer     */


  gridID = (hid_t)GridID;

  numbertype = HE5_EHconvdatatype(ntype);
  if(numbertype == FAIL)
    {
      H5Epush(__FILE__, "HE5_GDwrmeta", __LINE__, H5E_DATATYPE, H5E_BADVALUE, "Cannot convert datatype for FORTRAN wrapper.");
      HE5_EHprint("Error: Cannot convert datatype for FORTRAN wrapper, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /* Allocate memory for error message buffers */
  /* ----------------------------------------- */
  errbuf  = (char * )calloc(HE5_HDFE_ERRBUFSIZE, sizeof(char));
  if(errbuf == NULL)
    {
      H5Epush(__FILE__, "HE5_GDwrmeta", __LINE__, H5E_RESOURCE, H5E_NOSPACE, "Cannot allocate memory for error buffer.");
      HE5_EHprint("Error: Cannot allocate memory for error buffer, occured", __FILE__, __LINE__);
      return(FAIL);
    }

  /* Allocate space for C order dimension list */
  /* ----------------------------------------- */
  dimlist = (char *) calloc(strlen(fortdimlist) + 1, sizeof(char));
  if(dimlist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for dimlist.\n");
      H5Epush(__FILE__, "HE5_GDwrmeta", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      return(FAIL);
    }

  /* Reverse entries in dimension list (FORTRAN -> C) */
  /* ------------------------------------------------ */
  status = HE5_EHrevflds(fortdimlist, dimlist);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot reverse entries in dimension list.\n");
      H5Epush(__FILE__, "HE5_GDwrmeta", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      return(FAIL);
    }

  /* Call Write Metadata routine */
  /* --------------------------- */
  status = HE5_GDwritefieldmeta(gridID, fieldname, dimlist, numbertype);
  if(status == FAIL)
    {
      sprintf(errbuf,"Cannot write \"%s\" field metadata.\n", fieldname);
      H5Epush(__FILE__, "HE5_GDwrmeta", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(errbuf);
      free(dimlist);
      return(FAIL);
    }

  free(dimlist);
  free(errbuf);

  ret = (int)status;
  return (ret);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetaliaslistF (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of aliases and aliases list in "Data    |
|                Fields" group                                                |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nalias         long                number of aliases in "Data Fields"      |
|                                     group                                   |
|                                                                             |
|  INPUTS:                                                                    |
|  GridID         int                 grid structure ID                       |
|  fldgroup       int                 field group flag                        |
|                                                                             |
|  OUTPUTS:                                                                   |
|  aliaslist      char*               list of aliases  in "Data Fields" group |
|                                     (comma-separated list)                  |
|  strbufsize     long*               length of aliases list                  |
|                                                                             |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jul 05    S.Zhao       Original development                                |
|  Dec 05    T.Roegner    NCR 44092 - Added CYGWIN capability                 |
|                                                                             |
|   END_PROLOG                                                                |
-----------------------------------------------------------------------------*/
long
HE5_GDgetaliaslistF(int GridID, int fldgroup, char *aliaslist, long *strbufsize)
{
  long            nalias  = FAIL;         /* Number of aliases (return)     */
  hid_t           gridID  = FAIL;         /* HDF5 type grid ID              */
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer       */


  gridID = (hid_t)GridID;

  nalias = HE5_GDgetaliaslist(gridID, fldgroup, aliaslist, strbufsize);
  if (nalias < 0)
    {
      sprintf(errbuf, "Cannot retrieve the aliases. \n");
      H5Epush(__FILE__, "HE5_GDgetaliaslistF", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return(nalias);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetdimscaleF (FORTRAN wrapper)                             |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale for a fields dimension in a GRID    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int                 GRID structure ID                       |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|  dim            long                Dimemsion value                         |
|  numbertype_in  int                 dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|                None                                                         |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDsetdimscaleF(int GridID, char *fieldname, char *dimname,
		  long dim, int numbertype_in, void * data)
{
  herr_t          status;
  hid_t           gdID;
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer       */


  gdID = (hid_t)GridID;

  status = HE5_GDsetdimscale(gdID, fieldname, dimname,
			     (hsize_t) dim, (hid_t) numbertype_in, data);

  if (status < 0)
    {
      sprintf(errbuf, "Cannot set dimension scale %s for field %s. \n", dimname, fieldname);
      H5Epush(__FILE__, "HE5_GDsetdimscaleF", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return((int)status);

}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDsetdimscale2F (FORTRAN wrapper forHE5_GDsetdimscale2 )     |
|                                                                             |
|  DESCRIPTION: Defines a dimension scale for a fields dimension in a GRID    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int                 GRID structure ID                       |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|  dimnscaleame   char                dim scale name                          |
|  dim            long                Dimemsion value                         |
|  numbertype_in  int                 dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|                None                                                         |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|   March 17 Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDsetdimscale2F(int GridID, char *fieldname, char *dimname, char *dimscalename,
		  long dim, int numbertype_in, void * data)
{
  herr_t          status;
  hid_t           gdID;
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer       */


  gdID = (hid_t)GridID;

  status = HE5_GDsetdimscale2(gdID, fieldname, dimname, dimscalename,
			     (hsize_t) dim, (hid_t) numbertype_in, data);

  if (status < 0)
    {
      sprintf(errbuf, "Cannot set dimension scale %s for field %s. \n", dimscalename, fieldname);
      H5Epush(__FILE__, "HE5_GDsetdimscale2F", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return((int)status);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefdimscaleF (FORTRAN wrapper)                             |
|                                                                             |
|  DESCRIPTION: Defines dimension scale for a dimension for all fields in a   |
|               GRID                                                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int                 GRID structure ID                       |
|  dimname        char                dim name                                |
|  dim            long                Dimemsion value                         |
|  numbertype_in  int                 dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|                None                                                         |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jan 14    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDdefdimscaleF(int GridID, char *dimname,
		  long dim, int numbertype_in, void * data)
{
  herr_t          status;
  hid_t           gdID;
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer       */


  gdID = (hid_t)GridID;

  status = HE5_GDdefdimscale(gdID, dimname,
			     (hsize_t) dim, (hid_t) numbertype_in, data);

  if (status < 0)
    {
      sprintf(errbuf, "Cannot set dimension scale %s for all grid fields. \n", dimname);
      H5Epush(__FILE__, "HE5_GDdefdimscaleF", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return((int)status);

}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdefdimscale2F (FORTRAN wrapper for HE5_GDdefdimscale2)     |
|                                                                             |
|  DESCRIPTION: Defines dimension scale for a dimension for all fields in a   |
|               GRID                                                          |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int                 GRID structure ID                       |
|  dimname        char                dim name                                |
|  dimscalename   char                dim scale name                          |
|  dim            long                Dimemsion value                         |
|  numbertype_in  int                 dim scale data type such as DFNT_INT32, |
|                                     DFNT_FLOAT64, DFNT_FLOAT32, etc.        |
|  data           void                data buffer for write                   |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|                None                                                         |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  March 17  Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDdefdimscale2F(int GridID, char *dimname, char *dimscalename,
		  long dim, int numbertype_in, void * data)
{
  herr_t          status;
  hid_t           gdID;
  char            errbuf[HE5_HDFE_ERRBUFSIZE];/* Error message buffer       */


  gdID = (hid_t)GridID;

  status = HE5_GDdefdimscale2(gdID, dimname, dimscalename,
			     (hsize_t) dim, (hid_t) numbertype_in, data);

  if (status < 0)
    {
      sprintf(errbuf, "Cannot set dimension scale %s for all grid fields. \n", dimscalename);
      H5Epush(__FILE__, "HE5_GDdefdimscale2F", __LINE__, H5E_DATASET, H5E_WRITEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return((int)status);

}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetdimscaleF  (FORTRAN wrapper)                            |
|                                                                             |
|  DESCRIPTION: Get dimension scale for a dimension of a field in a GRID      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return databuffsize  SUCCEED, (-1) FAIL |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int                 GRID structure ID                       |
|  fieldname      char                field name                              |
|  dimname        char                dim name                                |
|                                                                             |
|                                                                             |
|  OUTPUTS:                                                                   |
|  dimsize        long                dimension size                          |
|  ntype          int                 number type                             |
|  databuff       void                data buffer for read                    |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10    Abe Taaheri  Original Programmer                                 |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long
HE5_GDgetdimscaleF(int GridID, char *fieldname, char *dimname, long *dimsize,
		   int *ntype, void * databuff)
{
  hsize_t         databuffsize = (hsize_t)FAIL;/* Size of buffer            */
  hid_t           gdID         = FAIL;         /* HDF5 type grid ID         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Buffer for error message  */
  hsize_t         ds;
  hid_t           numtype;

  gdID = (hid_t)GridID;

  databuffsize = HE5_GDgetdimscale(gdID, fieldname, dimname, &ds, &numtype,
				   databuff);
  *dimsize = (long) ds;
  *ntype = (int) numtype;

  if ( databuffsize < 0 )
    {
      sprintf(errbuf,"Cannot get dimension scale %s for field %s. \n", dimname, fieldname);
      H5Epush(__FILE__, "HE5_GDgetdimscaleF", __LINE__, H5E_OHDR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
						 
  return((long)databuffsize);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDreaddscaleattrF (FORTRAN wrapper)                          |
|                                                                             |
|  DESCRIPTION: Reads attribute associated with a dimension scale field       |
|               from a GD.                                                    |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int     None        HDF-EOS type GRID  ID                   |
|  fieldname      char                field name                              |
|  attrname       char                attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Jun 10   Abe Taaheri   Original development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int
HE5_GDreaddscaleattrF(int GridID, char *fieldname, char *attrname, void *datbuf)
{
  herr_t          status         = FAIL;       /* return status             */
  hid_t           gdID           = FAIL;       /* HDF5 type grid ID         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Buffer for error message  */
  

  gdID = (hid_t)GridID;

  status = HE5_GDreaddscaleattr(gdID, fieldname, attrname, datbuf);
  if ( status < 0 )
    {
      sprintf(errbuf,"Cannot read attribute %s for dimension scale %s. \n", attrname, fieldname);
      H5Epush(__FILE__, "HE5_GDreaddscaleattrF", __LINE__, H5E_IO, H5E_SEEKERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
						 
  return((int)status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION:  HE5_GDwritedscaleattrF (FORTRAN wrapper)                        |
|                                                                             |
|  DESCRIPTION: Writes/updates attribute associated with a dimension scale    |
|               field in a GD.                                                |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int                 GRID structure ID                       |
|  fieldname      char*               dimension scale SDS name                |
|  attrname       char*               attribute name                          |
|  numtype        int                 attribute datatype ID                   |
|  count[]        long                Number of attribute elements            |
|  datbuf         void                I/O buffer                              |
|                                                                             |
|  OUTPUTS:                                                                   |
|  None                                                                       |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10   Abe Taaheri   Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int    
HE5_GDwritedscaleattrF(int GridID, char *fieldname, char *attrname, int numtype, long count[], void *datbuf)
{
  herr_t          status         = FAIL;       /* return status             */
  hid_t           gdID           = FAIL;       /* HDF5 type grid ID         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Buffer for error message  */
  hsize_t         fort_count[HE5_FLDNUMBERMAX];

  gdID = (hid_t)GridID;

  fort_count[0] = (hsize_t)count[0];
  status = HE5_GDwritedscaleattr(gdID, fieldname, attrname, (hid_t)numtype, fort_count, datbuf);

  if ( status < 0 )
    {
      sprintf(errbuf,"Cannot write attribute %s for dimension scale %s. \n", attrname, fieldname);
      H5Epush(__FILE__, "HE5_GDwritedscaleattrF", __LINE__, H5E_ATTR, H5E_WRITEERROR, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }
						 
  return((int)status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdscaleattrinfoF (FORTRAN wrapper)                          |
|                                                                             |
|  DESCRIPTION: Retrieves information about dimension scale attribute         |
|               (attribute associated with a specified dimension scale field) |
|                in a GD.                                                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int       None      HDF-EOS type GRID  ID                   |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute data type ID                  |
|  fortcount      long                Number of attribute elements            |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10   Abe Taaheri   Original Development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDdscaleattrinfoF(int GridID, char *fieldname, char *attrname, int *ntype, long *fortcount)
{
  herr_t          status         = FAIL;       /* return status             */
  hid_t           gdID           = FAIL;       /* HDF5 type grid ID         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Buffer for error message  */
  hsize_t         *count = (hsize_t *)NULL;    /* C-order count array       */
  hid_t           *dtype  = (hid_t *)NULL;     /* Data type class ID        */

  gdID = (hid_t)GridID;

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(dtype);
      return(FAIL);
    }

  count[0] = 0;

  status = HE5_GDdscaleattrinfo(gdID, fieldname, attrname, dtype, count);

  if ( status == FAIL)
    {
      sprintf(errbuf, "Cannot retrieve attribute info for the %s dimension scale. \n", fieldname);
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(count);
      free(dtype);
      return(FAIL);
    }

  *fortcount = (long)(*count);
  *ntype     = (int)(*dtype);

  free(count);
  free(dtype);
  return((int)status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDdscaleattrinfoF2 (FORTRAN wrapper)                         |
|                                                                             |
|  DESCRIPTION: Retrieves information about dimension scale attribute         |
|               (attribute associated with a specified dimension scale field) |
|                in a GD.                                                     |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         int                 return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int       None      HDF-EOS type GRID  ID                   |
|  fieldname      char*               field name                              |
|  attrname       char*               attribute name                          |
|                                                                             |
|  OUTPUTS:                                                                   |
|  ntype          int                 attribute data type ID                  |
|  fortcount      long                Number of attribute elements            |
|  fortsize       long                buf size of attribute elements          |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 10   Abe Taaheri   Original Development                                |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
int 
HE5_GDdscaleattrinfoF2(int GridID, char *fieldname, char *attrname, int *ntype, long *fortcount, long *fortsize)
{
  herr_t          status         = FAIL;       /* return status             */
  hid_t           gdID           = FAIL;       /* HDF5 type grid ID         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Buffer for error message  */
  hsize_t         *count = (hsize_t *)NULL;    /* C-order count array       */
  hsize_t         *size  = (hsize_t *)NULL;    /* size of array elements    */
  hid_t           *dtype  = (hid_t *)NULL;     /* Data type class ID        */

  gdID = (hid_t)GridID;

  dtype = (hid_t *)calloc(1, sizeof(hid_t));
  if(dtype == (hid_t *)NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"dtype\".\n");
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  count = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(count == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"count\".\n");
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(dtype);
      return(FAIL);
    }

  size = (hsize_t *)calloc(1, sizeof(hsize_t));
  if(size == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for \"size\".\n");
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF2", __LINE__, H5E_RESOURCE, H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(dtype);
      return(FAIL);
    }

  count[0] = 0;

  status = HE5_GDdscaleattrinfo2(gdID, fieldname, attrname, dtype, count, size);

  if ( status == FAIL)
    {
      sprintf(errbuf, "Cannot retrieve attribute info for the %s dimension scale. \n", fieldname);
      H5Epush(__FILE__, "HE5_GDdscaleattrinfoF2", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      free(count);
      free(dtype);
      return(FAIL);
    }

  *fortcount = (long)(*count);
  *fortsize  = (long)(*size);
  *ntype     = (int)(*dtype);

  free(count);
  free(size);
  free(dtype);
  return((int)status);
}


/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDinqdscaleattrsF (FORTRAN wrapper)                          |
|                                                                             |
|  DESCRIPTION:  Retrieves the number of attributes and string length of      |
|                attribute list associated with a specified dimension scale   |
|                in a GD.                                                     |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  nattr          long                number of attributes (-1 if fails)      |
|                                                                             |
|  INPUTS:                                                                    |
|  gdID           int     None        HDF-EOS type GRID  ID                   |
|  fieldname      char                dimension scale name                    |
|  attrnames      char                attribute name(s)                       |
|                                                                             |
|  OUTPUTS:                                                                   |
|  strbufsize     long                String length of attribute (in bytes)   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|  None                                                                       |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  June 10   Abe Taaheri  Original development.                               |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
long 
HE5_GDinqdscaleattrsF(int GridID, char *fieldname, char *attrnames, long *strbufsize)
{
  long            status         = FAIL;       /* return status             */
  hid_t           gdID           = FAIL;       /* HDF5 type grid ID         */
  char            errbuf[HE5_HDFE_ERRBUFSIZE]; /* Buffer for error message  */
  

  gdID = (hid_t)GridID;

  status = HE5_GDinqdscaleattrs(gdID, fieldname, attrnames, strbufsize);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Cannot find the attribute %s for dimension scale %s. \n",attrnames,fieldname);
      H5Epush(__FILE__, "HE5_GDinqdscaleattrsF", __LINE__, H5E_ATTR, H5E_NOTFOUND, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
    }

  return (status);
}



/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDgetEastAndNorthFiles                                       |
|                                                                             |
|  DESCRIPTION:  With user provided STPDATADIR environment variable this      |
|                functions returns the files needed for STP projection.       |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  None           void                                                        |
|                                                                             |
|  INPUTS:                                                                    |
|  eastFile       char                 nad27 file provides in gctp            |
|  northFile      char                 nad83 file provides in gctp            |
|                                                                             |
|  OUTPUTS:                                                                   |
|                                                                             |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  May 11   Abe Taaheri   Added support for State Plane Projection grid       |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
void HE5_GDgetEastAndNorthFiles(char *eastFile, char *northFile)
{
    char *ptr = NULL;
    char lastables[256];

    /*ptr = (char *)malloc(256*sizeof(char)); */
    ptr = (char *)getenv("STPDATADIR");

    if(ptr == NULL)
      {
	/* first try MRTDATADIR for HEG */
	ptr = (char *)getenv("MRTDATADIR");
      }


#if defined(HDFVIEWPLUGIN)
    if(ptr == NULL)
      {
	ptr = (char *)getenv("PWD");
	strcpy(lastables, "STPDATADIR=");
	strcat(lastables,ptr);
	strcat(lastables,"/lib/ext/eosdata");
	putenv(lastables);
	ptr = (char *)getenv("STPDATADIR");
      }
#endif

    if (ptr == NULL)
    {
      eastFile = (char *) NULL;
      northFile = (char *) NULL;
    }
    else
    {
	memmove(lastables, ptr, strlen(ptr));
	lastables[(int)strlen(ptr)] = '\0';
        /*strcpy(lastables, ptr);*/

#if defined(CYGWIN) || defined(LINUX) || defined(LINUX32) || defined(LINUX64) || defined(MACINTEL) || defined(MACINTEL32) || defined(MACINTEL64) || defined(DECALPHA)
        snprintf( eastFile,   sizeof(eastFile),"%s/nad27sp_le", lastables );    /* use littlt endian binary files */
        snprintf( northFile,  sizeof(northFile),"%s/nad83sp_le", lastables );
#else
        snprintf( eastFile, sizeof(eastFile), "%s/nad27sp_be", lastables );    /* use big endian binary files */
        snprintf( northFile,sizeof(northFile), "%s/nad83sp_be", lastables );
#endif


    }
    /*
    if(ptr != NULL)
      {
	free(ptr);
	ptr = NULL;
      }
    */
    return;
}

/*----------------------------------------------------------------------------|
|  BEGIN_PROLOG                                                               |
|                                                                             |
|  FUNCTION: HE5_GDflddiminfo                                                 |
|                                                                             |
|  DESCRIPTION:  This functions returns dims and maxdims                      |
|                                                                             |
|                                                                             |
|  Return Value    Type     Units     Description                             |
|  ============   ======  =========   =====================================   |
|  status         herr_t  None        return status (0) SUCCEED, (-1) FAIL    |
|                                                                             |
|  INPUTS:                                                                    |
|  gridID         hid_t   None        HDF-EOS type grid  ID                   |
|  fieldname      char*               fieldname                               |
|                                                                             |
|  OUTPUTS:                                                                   |
|  rank           int                 field rank                              |
|  dims           hsize_t             dimensions of field                     |
|  maxdims        hsize_t             max dimensions of field                 |
|  NOTES:                                                                     |
|                                                                             |
|                                                                             |
|   Date     Programmer   Description                                         |
|  ======   ============  =================================================   |
|  Sep 11   Abe Taaheri   Added support for unlimited dimension adjustment    |
|                                                                             |
|  END_PROLOG                                                                 |
-----------------------------------------------------------------------------*/
herr_t
HE5_GDflddiminfo(hid_t GridID, char *fieldname, int *rank,  hsize_t dims[], hsize_t maxdims[])
{
  herr_t      status         = FAIL;      /* return status             */
  hid_t       gdID           = FAIL;      /* HDF5 type grid ID         */
  char        errbuf[HE5_HDFE_ERRBUFSIZE];/* Buffer for error message  */
  hid_t       ntype[1] = {FAIL};          /* Field numbertypes         */
  char	      *dimlist    = (char *)NULL; /* Dimension list in C order */
  char	      *maxdimlist = (char *)NULL; /* max Dimension list in C order */
  char        *dimbuf   = (char *)NULL;   /* Dimension buffer          */
  char        *comma    = (char *)NULL;   /* Pointer to comma          */
  char        *dimcheck = (char *)NULL;   /* Dimension check buffer    */
  hsize_t     dimsize   = 0;              /* Dimension size            */
  int         maxrank     = 0;            /* max dim  rank             */
  int         i           = 0;            /* Loop index                */
  int         foundAllDim = 1;            /* found all dimensions flag */
  int         first       = 1;            /* first entry flag          */
  char        utlbuf[HE5_HDFE_UTLBUFSIZE];/* Utility buffer            */
  long        xdim  = 0;                  /* X dim size                */
  long        ydim  = 0;                  /* Y dim size                */

  gdID = (hid_t)GridID;

  /* Allocate space for C order dimension list */
  /* ----------------------------------------- */
  maxdimlist = (char *)calloc(HE5_HDFE_UTLBUFSIZE, sizeof(char));
  dimlist    = (char *)calloc(HE5_HDFE_UTLBUFSIZE, sizeof(char));
  if(dimlist == NULL || maxdimlist == NULL)
    {
      sprintf(errbuf,"Cannot allocate memory for input list.\n");
      H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_RESOURCE, 
	      H5E_NOSPACE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  /* Get field info  */
  /* --------------- */
  status = HE5_GDfieldinfo(gdID, fieldname, rank, dims, ntype, 
			   dimlist, maxdimlist);
  if ( status == FAIL )
    {
      sprintf(errbuf, "Error calling HE5_GDfieldinfo. \n") ;
      H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_ARGS, 
	      H5E_BADVALUE, errbuf);
      HE5_EHprint(errbuf, __FILE__, __LINE__);
      return(FAIL);
    }

  /* Allocate space for dimbuf, copy maxdimlist into it, & append comma */
  /* ------------------------------------------------------------------ */
  if(maxdimlist != NULL)
    {
      dimbuf = (char *) calloc(strlen(maxdimlist) + 64, sizeof(char));
      if(dimbuf == NULL)
	{
	  H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_RESOURCE, 
		  H5E_NOSPACE, "Cannot allocate memory. \n");
	  HE5_EHprint("Error: Can not allocate memory, occured", 
		      __FILE__, __LINE__);
	  return(FAIL);

	}
	  
      /* Copy "maxdimlist" to "dimbuf", & append comma */
      /* --------------------------------------------- */
      strcpy(dimbuf, maxdimlist);
      strcat(dimbuf, ",");

      /* Find comma */
      /* ---------- */
      comma = strchr(dimbuf, ',');

      /*
       * Loop through entries in dimension list to make sure they are
       *                     defined in grid
       */
      while (comma != NULL)
	{
	  /* Copy dimension list entry to dimcheck */
	  /* ------------------------------------- */
	  dimcheck = (char *) calloc(comma - dimbuf + 1, sizeof(char));
	  if(dimcheck == NULL)
	    {
	      H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_RESOURCE, 
		      H5E_NOSPACE, "Cannot allocate memory. \n");
	      HE5_EHprint("Error: Can not allocate memory, occured", 
			  __FILE__, __LINE__);
	      free(dimbuf);
	      free(dimlist);
	      free(maxdimlist);
	      return(FAIL);
	    }
	  memmove(dimcheck, dimbuf, comma - dimbuf);

	  /* Get dimension size */
	  /* ------------------ */
	  if ((strcmp(dimcheck, "XDim") == 0) || (strcmp(dimcheck, "YDim") == 0))
	    {
	      status = HE5_GDgridinfo(gdID, &xdim, &ydim, NULL, NULL);
	      if(status == FAIL)
		{
		  sprintf(errbuf, "Cannot get information about Grid.\n");
		  H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_FUNC, H5E_CANTINIT, errbuf);
		  HE5_EHprint(errbuf, __FILE__, __LINE__);
		  free(dimbuf);
		  free(dimlist);
		  free(maxdimlist);
		  return(FAIL);
		}

	      if(strcmp(dimcheck, "XDim") == 0)
		{
		  dimsize =  (hsize_t)xdim;
		}
	      else if(strcmp(dimcheck, "YDim") == 0)
		{
		  dimsize = (hsize_t)ydim;
		}
	    }
	  else
	    {
	      dimsize = HE5_GDdiminfo(gdID, dimcheck);
	    }

	  if ( (dimsize > 0) || (dimsize == H5S_UNLIMITED) )
	    {
	      maxdims[maxrank] = dimsize;
	      maxrank++;
	    }
	  else
	    {
	      /*
	       * If dimension list entry not found - set error return
	       * status, append name to utility buffer for error report
	       */
	      status = FAIL;
	      foundAllDim = 0;
	      if (first == 1)
		strcpy(utlbuf, dimcheck);
	      else
		{
		  strcat(utlbuf, ",");
		  strcat(utlbuf, dimcheck);
		}
	      first = 0;
	    }

	  /*
	   * Go to next dimension entry, find next comma, & free up
	   * dimcheck buffer
	   */

	  memmove(dimbuf, comma + 1, strlen(comma + 1) + 1); 
	  comma = strchr(dimbuf, ',');
	  free(dimcheck);
	}

      free(dimbuf);
      free(dimlist);
      free(maxdimlist);

      /* If no dimensions found, report error */
      /* ------------------------------------ */
      if (foundAllDim == 0)
	{
	  status = FAIL;
	  sprintf(errbuf, "Dimension(s) \"%s\" not found for \"%s\" field. \n",
		  utlbuf, fieldname);
	  H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_BTREE, 
		  H5E_NOTFOUND, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return (status);
	}

      /* If maxrank !=rank  then report error */
      /* ------------------------------------ */
      if ( maxrank != *rank )
	{
	  status = FAIL;
	  sprintf(errbuf,"Dimension rank doesn't match Max dimension rank.\n");
	  H5Epush(__FILE__, "HE5_GDflddiminfo", __LINE__, H5E_ARGS,
		  H5E_BADVALUE, errbuf);
	  HE5_EHprint(errbuf, __FILE__, __LINE__);
	  return (status);
	}
    } 
  /* "maxlist == NULL"  ==> maxdims[]= dims[] */
  /* ---------------------------------------- */
  else
    {
      for(i = 0; i < *rank; i++ )
	maxdims[ i ] = dims[ i ];
    }

  return (status);
}




#ifndef  __cplusplus

/* HDF types used in FORTRAN bindings */
 
#if defined(DEC_ALPHA) || defined(IRIX) || defined(UNICOS) || defined(LINUX64) || defined(IA64) || defined(MACINTOSH) || defined(MACINTEL) || defined(IBM6000) || defined(CYGWIN)
 
#define INT32  INT
#define INT32V INTV
#define PINT32 PINT
 
#else
 
#define INT32  LONG
#define INT32V LONGV
#define PINT32 PLONG
 
#endif


/* File/Grid access routines */
 
FCALLSCFUN2(INT, HE5_GDopenF, HE5_GDOPEN, he5_gdopen, STRING, INT)
FCALLSCFUN6(INT, HE5_GDcreateF, HE5_GDCREATE, he5_gdcreate, INT, STRING, LONG, LONG, DOUBLEV, DOUBLEV)
FCALLSCFUN2(INT, HE5_GDattachF, HE5_GDATTACH, he5_gdattach, INT, STRING)
FCALLSCFUN1(INT, HE5_GDdetachF, HE5_GDDETACH, he5_gddetach, INT)
FCALLSCFUN1(INT, HE5_GDcloseF, HE5_GDCLOSE, he5_gdclose, INT)


/* Definition routines */

FCALLSCFUN3(INT, HE5_GDdefdimF, HE5_GDDEFDIM, he5_gddefdim, INT, STRING, LONG)
FCALLSCFUN5(INT, HE5_GDdefprojF, HE5_GDDEFPROJ, he5_gddefproj, INT, INT, INT, INT, DOUBLEV)
FCALLSCFUN2(INT, HE5_GDdeforiginF, HE5_GDDEFORIGIN, he5_gddeforigin, INT, INT)
FCALLSCFUN6(INT, HE5_GDdeffld, HE5_GDDEFFLD, he5_gddeffld, INT, STRING, STRING, STRING, INT, INT)
FCALLSCFUN4(INT, HE5_GDsetfill, HE5_GDSETFILL, he5_gdsetfill, INT, STRING, INT, PVOID)
FCALLSCFUN3(INT, HE5_GDdefcompF, HE5_GDDEFCOMP, he5_gddefcomp, INT, INT, INTV)
FCALLSCFUN4(INT, HE5_GDdeftileF, HE5_GDDEFTLE, he5_gddeftle, INT, INT, INT, PLONG)
FCALLSCFUN5(INT, HE5_GDdefcomtileF, HE5_GDDEFCOMTLE, he5_gddefcomtle, INT, INT, PINT, INT, PLONG)
FCALLSCFUN2(INT, HE5_GDdefpixregF, HE5_GDDEFPREG, he5_gddefpreg, INT, INT)
FCALLSCFUN3(INT, HE5_GDsetaliasF, HE5_GDSETALIAS, he5_gdsetalias, INT, STRING, STRING)
FCALLSCFUN3(INT, HE5_GDdropaliasF, HE5_GDDRPALIAS, he5_gddrpalias, INT, INT, STRING)


/* I/O routines */

FCALLSCFUN6(INT, HE5_GDwrfld, HE5_GDWRFLD, he5_gdwrfld, INT, STRING, LONGV, LONGV, LONGV, PVOID)
FCALLSCFUN8(INT, HE5_GDwrcharfld, HE5_GDWRCHARFLD, he5_gdwrcharfld, INT, STRING, INT, INT, LONGV, LONGV, LONGV, PVOID)
FCALLSCFUN6(INT, HE5_GDrdfld, HE5_GDRDFLD, he5_gdrdfld, INT, STRING, LONGV, LONGV, LONGV, PVOID)
FCALLSCFUN8(INT, HE5_GDrdcharfld, HE5_GDRDCHARFLD, he5_gdrdcharfld, INT, STRING, INT, INT, LONGV, LONGV, LONGV, PVOID)
FCALLSCFUN3(INT, HE5_GDgetfill, HE5_GDGETFILL, he5_gdgetfill, INT, STRING, PVOID)
FCALLSCFUN5(INT, HE5_GDwrattr, HE5_GDWRATTR, he5_gdwrattr, INT, STRING, INT, LONGV, PVOID)
FCALLSCFUN5(INT, HE5_GDwrgattr, HE5_GDWRATTR, he5_gdwrgattr, INT, STRING, INT, LONGV, PVOID)
FCALLSCFUN6(INT, HE5_GDwrlattr, HE5_GDWRLATTR, he5_gdwrlattr, INT, STRING, STRING, INT, LONGV, PVOID)
FCALLSCFUN3(INT, HE5_GDrdattr, HE5_GDRDATTR, he5_gdrdattr, INT, STRING, PVOID)
FCALLSCFUN3(INT, HE5_GDrdgattr, HE5_GDRDGATTR, he5_gdrdgattr, INT, STRING, PVOID)
FCALLSCFUN4(INT, HE5_GDrdlattr, HE5_GDRDLATTR, he5_gdrdlattr, INT, STRING, STRING, PVOID)
FCALLSCFUN4(INT, HE5_GDwrmeta, HE5_GDWRMETA, he5_gdwrmeta, INT, STRING, STRING, INT)


/* Inquiry routines */

FCALLSCFUN3(LONG, HE5_GDinqdimsF, HE5_GDINQDIMS, he5_gdinqdims, INT, PSTRING, LONGV)
FCALLSCFUN2(LONG, HE5_GDdiminfoF, HE5_GDDIMINFO, he5_gddiminfo, INT, STRING)
FCALLSCFUN4(INT, HE5_GDinqflds, HE5_GDINQFLDS, he5_gdinqflds, INT, PSTRING, INTV, INTV)
FCALLSCFUN7(INT, HE5_GDfldinfo, HE5_GDFLDINFO, he5_gdfldinfo, INT, STRING, PINT, LONGV, INTV, PSTRING, PSTRING)
FCALLSCFUN8(INT, HE5_GDinqdatatypeF, HE5_GDINQDATATYPE, he5_gdinqdatatype, INT, STRING, STRING, INT, PINT, PINT, PINT, PLONG)
FCALLSCFUN3(LONG, HE5_GDinqgridF, HE5_GDINQGRID, he5_gdinqgrid, STRING, PSTRING, PLONG)
FCALLSCFUN5(INT, HE5_GDgridinfoF, HE5_GDGRIDINFO, he5_gdgridinfo, INT, PLONG, PLONG, DOUBLEV, DOUBLEV)
FCALLSCFUN5(INT, HE5_GDprojinfoF, HE5_GDPROJINFO, he5_gdprojinfo, INT, PINT, PINT, PINT, DOUBLEV)
FCALLSCFUN9(INT, HE5_GDreginfo, HE5_GDREGINFO, he5_gdreginfo, INT, INT, STRING, PINT, PINT, LONGV, PLONG, DOUBLEV, DOUBLEV)

FCALLSCFUN4(INT, HE5_GDatinfo, HE5_GDATINFO, he5_gdattrinfo, INT, STRING, PINT, PLONG)
FCALLSCFUN4(INT, HE5_GDgatinfo, HE5_GDGATINFO, he5_gdgatinfo, INT, STRING, PINT, PLONG)
FCALLSCFUN5(INT, HE5_GDlatinfo, HE5_GDLATINFO, he5_gdlatinfo, INT, STRING, STRING, PINT, PLONG)
FCALLSCFUN5(INT, HE5_GDatinfo2, HE5_GDATINFO2, he5_gdattrinfo2, INT, STRING, PINT, PLONG, PLONG)
FCALLSCFUN5(INT, HE5_GDgatinfo2, HE5_GDGATINFO2, he5_gdgatinfo2, INT, STRING, PINT, PLONG, PLONG)
FCALLSCFUN6(INT, HE5_GDlatinfo2, HE5_GDLATINFO2, he5_gdlatinfo2, INT, STRING, STRING, PINT, PLONG, PLONG)

FCALLSCFUN2(INT, HE5_GDorigininfoF, HE5_GDORGINFO, he5_gdorginfo, INT, PINT)
FCALLSCFUN2(INT, HE5_GDpixreginfoF, HE5_GDPREGINFO, he5_gdpreginfo, INT, PINT)
FCALLSCFUN4(INT, HE5_GDcompinfoF, HE5_GDCOMPINFO, he5_gdcompinfo, INT, STRING, PINT, INTV)
FCALLSCFUN3(LONG, HE5_GDnentriesF, HE5_GDNENTRIES, he5_gdnentries, INT, INT, PLONG)
FCALLSCFUN3(LONG, HE5_GDinqattrsF, HE5_GDINQATTRS, he5_gdinqattrs, INT, PSTRING, PLONG)
FCALLSCFUN3(LONG, HE5_GDinqgrpattrsF, HE5_GDINQGATTRS, he5_gdinqgattrs, INT, PSTRING, PLONG)
FCALLSCFUN4(LONG, HE5_GDinqlocattrsF, HE5_GDINQLATTRS, he5_gdinqlattrs, INT, STRING, PSTRING, PLONG)
FCALLSCFUN5(INT, HE5_GDtileinfoF, HE5_GDTILEINFO, he5_gdtileinfo,INT,STRING,PINT,PINT,LONGV)
FCALLSCFUN5(INT, HE5_GDaliasinfoF, HE5_GDALIASINFO, he5_gdaliasinfo, INT, INT, STRING, PINT, STRING)
FCALLSCFUN3(LONG, HE5_GDinqfldaliasF, HE5_GDINQFLDALIAS, he5_gdinqfldalias,INT,PSTRING,PLONG)
FCALLSCFUN4(LONG, HE5_GDgetaliaslistF, HE5_GDGETALIASLIST, he5_gdgetaliaslist,INT,INT,PSTRING,PLONG)



/* Subsetting/Retrieving routines */

FCALLSCFUN3(INT, HE5_GDdefboxregionF, HE5_GDDEFBOXREG, he5_gddefboxreg, INT, DOUBLEV, DOUBLEV)
FCALLSCFUN4(INT, HE5_GDextractregionF, HE5_GDEXTREG, he5_gdextreg, INT, INT, STRING, PVOID)
FCALLSCFUN4(INT, HE5_GDdeftimeperiodF, HE5_GDDEFTMEPER, he5_gddeftmeper, INT, INT, DOUBLE, DOUBLE)
FCALLSCFUN4(INT, HE5_GDdefvrtregionF, HE5_GDDEFVRTREG, he5_gddefvrtreg, INT, INT, STRING, DOUBLEV)
FCALLSCFUN1(INT, HE5_GDdupregionF, HE5_GDDUPREG, he5_gddupreg, INT)
FCALLSCFUN6(INT, HE5_GDgetpixelsF, HE5_GDGETPIX, he5_gdgetpix, INT, LONG, DOUBLEV, DOUBLEV, LONGV, LONGV)
FCALLSCFUN6(LONG, HE5_GDgetpixvaluesF, HE5_GDGETPIXVAL, he5_gdgetpixval, INT, LONG, LONGV, LONGV, STRING, PVOID)
FCALLSCFUN6(LONG, HE5_GDinterpolateF, HE5_GDINTERPOLATE, he5_gdinterpolate, INT, LONG, DOUBLEV, DOUBLEV, STRING, DOUBLEV)

/* EXTERNAL DATA FILE INTERFACE */

FCALLSCFUN4(INT, HE5_GDsetextdataF, HE5_GDSETXDAT, he5_gdsetxdat,INT,STRING,LONGV,LONGV)
FCALLSCFUN6(INT, HE5_GDgetextdataF, HE5_GDGETXDAT, he5_gdgetxdat,INT,STRING,LONG,STRING,LONGV,LONGV)


/* Utility routine */


FCALLSCFUN15(INT,HE5_GDij2ll, HE5_GDIJ2LL, he5_gdij2ll, INT, INT, DOUBLEV, INT, LONG, LONG, DOUBLEV, DOUBLEV, LONG, LONGV, LONGV, DOUBLEV, DOUBLEV, INT, INT)
FCALLSCFUN15(INT,HE5_GDll2ij, HE5_GDLL2IJ, he5_gdll2ij, INT, INT, DOUBLEV, INT, LONG, LONG, DOUBLEV, DOUBLEV, LONG, DOUBLEV, DOUBLEV, LONGV, LONGV, DOUBLEV, DOUBLEV)
FCALLSCFUN13(INT, HE5_GDrs2ll, HE5_GDRS2LL, he5_gdrs2ll, INT, DOUBLEV, LONG, LONG, DOUBLEV, DOUBLEV, INT, DOUBLEV, DOUBLEV, DOUBLEV, DOUBLEV, INT, INT) 

FCALLSCFUN5(INT, HE5_GDdefdimscaleF, HE5_GDDEFDIMSCALE, he5_gddefdimscale,INT,STRING,LONG,INT,PVOID)
FCALLSCFUN6(INT, HE5_GDdefdimscale2F, HE5_GDDEFDIMSCALE2, he5_gddefdimscale2,INT,STRING,STRING,LONG,INT,PVOID)
FCALLSCFUN6(INT, HE5_GDsetdimscaleF, HE5_GDSETDIMSCALE, he5_gdsetdimscale,INT,STRING,STRING,LONG,INT,PVOID)
FCALLSCFUN7(INT, HE5_GDsetdimscale2F, HE5_GDSETDIMSCALE2, he5_gdsetdimscale2,INT,STRING,STRING,STRING,LONG,INT,PVOID)
FCALLSCFUN6(LONG, HE5_GDgetdimscaleF, HE5_GDGETDIMSCALE, he5_gdgetdimscale,INT,STRING,STRING,PLONG,PINT,PVOID)
FCALLSCFUN4(INT, HE5_GDreaddscaleattrF,HE5_GDREADDSCALEATTR, he5_gdreaddscaleattr,INT,STRING,STRING,PVOID)
FCALLSCFUN6(INT, HE5_GDwritedscaleattrF, HE5_GDWRITEDSCALEATTR, he5_gdwritedscaleattr,INT,STRING,STRING,INT,LONGV,PVOID)
FCALLSCFUN5(INT, HE5_GDdscaleattrinfoF, HE5_GDDSCALEATTRINFO, he5_gddscaleattrinfo,INT,STRING,STRING,PINT,PLONG)
FCALLSCFUN6(INT, HE5_GDdscaleattrinfoF2, HE5_GDDSCALEATTRINFO2, he5_gddscaleattrinfo2,INT,STRING,STRING,PINT,PLONG,PLONG)
FCALLSCFUN4(INT, HE5_GDinqdscaleattrsF, HE5_GDINQDSCALATTRS, he5_gdinqdscaleattrs,INT,STRING,STRING,PLONG)

#endif











