/**************************************************************************
*                                                                         *
*        HDF Read Program for these SAGEs I & II Profile Data Sets        *
*                                                                         *
*                       SAGE I Aerosol Profiles                           *
*                       SAGE II Aerosol Profiles                          *
*                       SAGE II Ozone Profiles (O3)                       *
*                       SAGE II Nitrogen Dioxide Profiles (NO2)           *
*                       SAGE II Water Vapor Profiles (H2O)                *
*                                                                         *
* Version 7.0                                        January 26, 1999     *
*                                                                         *
* HDF Library:  Version 4.4r2                                             *
*                                                                         *
* NOTE:  When you compile this program, make sure you include the HDF     *
*        library path.  The compile program that can also be used to      *
*        build this read program is called compile_read_sage.             *
*                                                                         *
*                                                                         *
* 08/10/1994  Modifications were made to the code to make the report file *
*           more readable for the user.  The following modifications were *
*           done:                                                         *
*           (1) Currently, the Langley DAAC has three of the seven exper- *
*           iments on-line, therefore, this read program has been tested  *
*           for the three experiments.  If another option is selected,    *
*           then the program will terminate with an error message.        *
*           (2) Instead of printing out the annotation labels onto the    *
*           screen, now the program is printing out the data labels which *
*           are more explicit.                                            *
*           (3) The term Geometric Altitude was replaced with Minimum Alt.*
*           where event information is printed for every event in the     *
*           report file.  The value printed here is actually the first    *
*           value in the Geometric Altitude set of data for each event.   *
*           (4) The code which prints out Dimension information has been  *
*           suppressed.  If the user wishes to print this information in  *
*           the report file, just remove the comments.                    *
*           (5) In the selection section of the code, it prompts the user *
*           to enter zero to quit. This option has been changed to say    *
*           enter zero to begin retrieving the data.                      *
*           (6) Insert leading zeroes in the EventDate and EventTime so   *
*           that these two data values will always print out six positions*
*           of data.                                                      *
*           (7) Remove a print statement that was used by the programmer. *
*           (8) Have the capability to change your selections of which    *
*           parameters to retrieve data.                                  *
*           (9) This code was compiled with the ANSI C compiler which     *
*           means this this code follows the ANSI C standards.  Minor     *
*           modifications were made to make this code ANSI C.             *
*                                                                         *
* 08/17/1994  Modifications were made in the function, Print_data_info,   *
*           where the data use to only work with 32-bit numbers but now   *
*           the program is capable of working with 16-bit integers and    *
*           8-bit integers.                                               *
*           Added the capability to work with the bit flags for ozone     *
*           data.                                                         *
* 09/02/94  Added the option to quit or if entered an incorrect value, the*
*           the code would not abort.                                     *
*                                                                         *
* 11/28/1994  The program has been modified to read a new data set SAGE II*
*           Nitrogen Dioxide (NO2) Profiles.                              *
*                                                                         *
* 12/23/1994  Added the option to allow the user to ask to print out all  *
*           of the data parameters without having to enter every parameter*
*           value.                                                        *
*                                                                         *
* 05/08/1995  Added options to read SAGE II Water Vapor Profiles to code. *
*                                                                         *
* 10/31/1995  Modified dates to more current year dates.                  *
*                                                                         *
* 10/07/1996  Modified code to bring code up to HDF 3.3r4 ANSI standards. *
*                                                                         *
* 01/26/1999  Modified the code to be able to compile with the latest     *
*             version of the HDF libraries, Version 4.1r2.                *
*                                                                         *
* Contact Information:  If you have any questions, please contact:        *
*       Langley DAAC User and Data Services                               *
*       NASA Langley Research Center                                      *
*       Mail Stop 157D                                                    *
*       Hampton, VA 23681-2199                                            *
*       U.S.A.                                                            *
*                                                                         *
*       Telephone:  (757)864-8656            FAX: (757)864-8807           *
*       E-mail:     larc@eos.nasa.gov                                     *
*                                                                         *
***************************************************************************/
/* Must include for C calls in program */
#include <stdio.h>             /* C library */
#include <stdlib.h>            /* C library */
#include <string.h>            /* C library */

/* HDF requires this include file to be written into the C code */
#include "hdf.h"

/* Define global variables used in code */
#define  DFACC_read  1         /* HDF position */
#define  LISTSIZE  175
#define  MAXCHAR  132          /* Maximum number of characters in a string */
#define MAXDATA          65100 /* Max # of events (930) times Max # of data  */
                               /* values per parameter (70) */
#define MAXLABLEN          256 /* Max string label length */
#define  MAXLEN  10000         /* Maximum length of file description */
#define MAXLNG              55 /* Max number of labels */
#define MAXRANK              2 /* Max number of dimensions */
#define  NumEventPar   6       /* Number of parameter values printed at each event */


main ()
{                              /* Begin main function */

  void Greetings();            /* Declare function */
  void Assign_rpt_name();      /* Declare function */
  void Read_data_descript();   /* Declare function */
  void Test_exp();             /* Declare function */
  void Get_data_types();       /* Declare function */
  int  Print_data_info();      /* Declare function */
  void Read_data();            /* Declare function */

  int    exp,                  /* Store type of experiment */
         num_events = 0;       /* Stores the number of events */


  unsigned short int   dataitems[LISTSIZE], /* Store reference number of labels */
                       ref_num[19]; /* Stores event information */



  char   yesno[2],             /* Stores yes/no number for printing header information */
         hdfname[MAXCHAR],     /* Stores input data file name */
         info[MAXCHAR],        /* Used as a temporary string buffer */
         outfile[MAXCHAR];     /* Stores output report file name */

  FILE   *ofp;                 /* Pointer for output report file */

               /**********************************/
               /*      Main function begins      */
               /**********************************/

  (void) Greetings();

  printf("\n\n");
  printf("This is a list of all SAGE experiments.\n\n");
  printf("  1.  SAGE I Aerosol Profiles\n");
  printf("  2.  SAGE II Aerosol Profiles\n");
  printf("  3.  SAGE II Ozone Profiles\n");
  printf("  4.  SAGE II Nitrogen Dioxide Profiles\n");
  printf("  5.  SAGE II Water Vapor Profiles\n");
  printf("\n");
  printf("Enter type of experiment (1 thru 5) ... ");
  scanf("%s",info);
  exp = atoi(info);
  (void) Test_exp (exp);

  printf("\n\n");
  printf("Enter the full data path as well as the data name.\n");
  scanf("%s",info);
  strcpy(hdfname,info);

  printf("\n\n");
  printf("In your output report file, do you want to include the \n");
  printf("file description?  Enter 1 for yes and 2 for no .... ");
  scanf("%s",info);
  strcpy(yesno,info);

  /* Create an output report file name. */
  (void) Assign_rpt_name (outfile, hdfname);

  ofp = fopen (outfile, "wt");
 
  if (ofp == NULL)
  {
     printf("*********************************************\n");
     printf("* ERROR - Not able to open the output file, *\n");
     printf("*         %s.                        *\n",outfile);
     printf("*         Program has terminated.           *\n");
     printf("*********************************************\n");
     exit ( -1 );
  }

  /* Reads the data file description from HDF file and writes */
  /* it out to the output report file.                        */
  (void) Read_data_descript (hdfname, ofp, yesno);

  /* Allows the user to select the parameters to be written   */
  /* out to the output report file.                           */
  (void) Get_data_types (ofp, hdfname, dataitems, ref_num);


  /* Print selected data information and output to report file */
  num_events = Print_data_info (ofp, hdfname, dataitems, ref_num);

  printf("\n\n");
  printf("There are %d records/number of events in the HDF file.\n",num_events);
  printf("NOTE:  This will take some time to write out the report file.\n");

  /* Read selected data and output to report file */
  (void) Read_data (ofp, hdfname, dataitems, ref_num, num_events, exp);

  /* Print out End of File message onto the screen. */
  printf("\n\n");
  printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
  printf("@                                                             @\n");
  printf("@ This program has completed and has created an output report @\n");
  printf("@ file called %s in your current          @\n",outfile);
  printf("@ working directory.                                          @\n");
  printf("@                                                             @\n");
  printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
  printf("\n\n");

}   /* End main function */

/****************************************************************************
*                                                                           *
* FUNCTION:  Greetings                                                      *
*                                                                           *
* PURPOSE:   To print a banner at the beginning of the execution to inform  *
*            the users what version of this read program he or she is       *
*            working with.                                                  *
*                                                                           *
****************************************************************************/
void Greetings()
{   /* Begin Greetings function */
   printf("\n\n\n");
   printf("   *****************************************************\n");
   printf("   *                                                   *\n");
   printf("   *     SAGEs I & II HDF Read Program Version 7.0     *\n");
   printf("   *                                                   *\n");
   printf("   *                                                   *\n");
   printf("   *  This sample read program currently reads the     *\n");
   printf("   *  following data sets:                             *\n");
   printf("   *                                                   *\n");
   printf("   *             SAGE I Aerosol Profiles               *\n");
   printf("   *             SAGE II Aerosol Profiles              *\n");
   printf("   *             SAGE II Ozone Profiles                *\n");
   printf("   *             SAGE II Nitrogen Dioxide Profiles     *\n");
   printf("   *             SAGE II Water Vapor Profiles          *\n");
   printf("   *                                                   *\n");
   printf("   *                                                   *\n");
   printf("   *                 January 26, 1999                  *\n");
   printf("   *****************************************************\n");
   printf("\n\n\n");
}   /* End of Greetings function */

/****************************************************************************
*                                                                           *
* FUNCTION:  Assign_rpt_name                                                *
*                                                                           *
* PURPOSE:   Creates a report filename for the appropriate experiment.      *
*                                                                           *
****************************************************************************/
void Assign_rpt_name (outfile, hdfname)
char  *outfile, *hdfname;
{
   strcpy(outfile,hdfname);
   strcat(outfile,".rpt");

}  /*  End of function, Assign_rpt_name.  */


/****************************************************************************
*                                                                           *
* FUNCTION:  Read_data_descript                                             *
*                                                                           *
* PURPOSE:   Opens input HDF file, reads the file description, and prints   *
*            the file description to the report file if the user desires to *
*            have it printed.                                               *
*                                                                           *
****************************************************************************/
void Read_data_descript (hdfname, ofp, yesno)
char *hdfname;
FILE *ofp;
char *yesno;
{
   int dfile,
       iret;

   char id[MAXLEN],
        filedesc[MAXLEN];

   /* Open HDF input file using HDF user commands. */
   dfile = Hopen(hdfname, DFACC_read, 0);

   if (dfile == NULL)
   {
      printf("************************************************\n");
      printf("* ERROR - Not able to open the HDF input file. *\n");
      printf("*         Program has terminated.              *\n");
      printf("************************************************\n");
      exit ( -1 );
   }

   /* Get file id from HDF input file. */
   iret = DFANgetfid (dfile, id, MAXLEN, 1);
   
   if (iret == -1)
   {
      printf("************************************************\n");
      printf("* ERROR - Not able to get file id from the HDF *\n");
      printf("*         input data file.                     *\n");
      printf("*         Program has terminated.              *\n");
      printf("************************************************\n");
      exit ( -1 );
   }

   /* Get file description from HDF input file. */
   iret = DFANgetfds(dfile, filedesc, MAXLEN, 1);

   if (iret == -1)
   {
      printf("**************************************************\n");
      printf("* ERROR - Error in getting file description from *\n");
      printf("*         the HDF input data file.               *\n");
      printf("*         Program has terminated.                *\n");
      printf("**************************************************\n");
      exit ( -1 );
    }
    else
    {
      if (atoi(yesno) == 1)
      {
         fprintf(ofp,"%s\n%s\n\n","File ID: ",id);
         fprintf(ofp,"%s\n\n%s","File description is as follows:",filedesc);
         fprintf(ofp,"\n\n");
      }
    }

}  /*  End of function, Read_data_descript.  */



/*****************************************************************************
*                                                                            *
*  FUNCTION:  Test_exp                                                       *
*                                                                            *
*  PURPOSE:   This function checks to see if the experiment the user has     *
*             entered is a valid choice.  If it is not, the program exits.   *
*                                                                            *
*****************************************************************************/
void Test_exp(exp)
int exp;
{
      if (exp < 1)
      {
         printf("****************************************************\n");
         printf("*  ERROR - Numbers one thru five are valid input.  *\n");
         printf("*          Program has terminated.                 *\n");
         printf("****************************************************\n\n");
         exit ( -1 );
      }
      else if (exp > 5)
      {
         printf("****************************************************\n");
         printf("*  ERROR - Numbers one thru five are valid input.  *\n");
         printf("*          Program has terminated.                 *\n");
         printf("****************************************************\n\n");
         exit ( -1 );
      }
}  /* End of function, Test_exp */

/****************************************************************************
*                                                                           *
* FUNCTION:  Get_data_types                                                 *
*                                                                           *
* PURPOSE:   This function prints out all of the parameters within the data *
*            file (HDF) and allows the user to select which parameters he   *
*            or she wishes to see.  Only the first six parameters in the    *
*            string called EventStr will automatically be printed to the    *
*            report file.  Geometric Altitude will be printed in the event  *
*            information as well as the user being able to select it.       *
*                                                                           *
****************************************************************************/
void Get_data_types(ofp, hdfname, dataitems, ref_num)
FILE *ofp;
char *hdfname;
unsigned short int dataitems[LISTSIZE];
unsigned short int ref_num[NumEventPar];
{
   static char *EventStr = {"Event Date (yymmdd.0) Event Time (hhmmss.0) Subtangent Latitude Subtangent Longitude Event Type (0.0 = sunrise, 1.0 = sunset) Geometric Altitude "};
   static char *EventStrNO2 = {"Event Date (yymmdd.0) Event Time (hhmmss.0) Subtangent Latitude Subtangent Longitude Event Type (1.0 = sunset) Geometric Altitude "};


   int nlabels, itemnumber, startpos;
   int cnt0, cnt1, cnt2, cnt3;
   unsigned short int reflist[LISTSIZE];
   int index[LISTSIZE];
   int numchoices;
   char labellist[LISTSIZE * MAXLNG + 1];
   char datalabellist[MAXLNG][MAXLABLEN];                     /* 08/10/94 */
   int  datalabelval[MAXLNG];                                 /* 08/10/94 */
   int  datacount;                                            /* 08/10/94 */
   char yesno[2];                                             /* 08/10/94 */
   int iret, numdims, numtype;
   int32 dimsize[MAXRANK];
   char datalabel[MAXLABLEN], dataunit[MAXLABLEN], datafmt[MAXLABLEN], datacoord[3];
   char dimlab[2][40], dimunt[30], dimfmt[5];
   char all_flag[2];
 
TRYAGAIN:                                                     /* 08/10/94 */
   cnt0 = 0;
   cnt2 = 1,
   cnt3 = 0;
   startpos = 1;
   numchoices = 0;

   /* initialize dataitems array */
   for (cnt1 = 0; cnt1 < LISTSIZE; cnt1++)
   {
      dataitems[cnt1] = 65535;
      reflist[cnt1] = 0;
      index[cnt1] = 0;
   }/* end of for */
   for (cnt1 = 0; cnt1<MAXLNG; cnt1++)                        /* 08/10/94 */
      datalabelval[cnt1] = 0;


   /* Get the reference numbers and annotation labels of all */
   /* parameters in the HDF file starting at position given  */
   /* in startpos.                                           */

   nlabels = DFANlablist(hdfname, DFTAG_NDG, reflist, labellist, LISTSIZE, MAXLNG, startpos);

   /* Was there a problem with retrieving the annotation labels? */

   if (nlabels == -1)
   {
      printf("**********************************************\n");
      printf("* Error - Not able to get annotation labels. *\n");
      printf("*         Program has terminated.            *\n");
      printf("**********************************************\n");
      fprintf(ofp, "Error in getting annotation labels.");
      exit ( -1 );
   }/* end of if */

   /* Get the reference numbers for the parameters that will be */
   /* written with each event, and create a valid list of index */
   /* numbers to the parameters that the user will be permitted */
   /* to chose from.                                            */

   for (cnt1 = 0; cnt1 < nlabels; ++cnt1)
   {
      /* It is necessary to get the data labels for the parameters  */
      /* in order to determine if the parameter is a valid choice   */
      /* for the user or not.  It is also necessary to call several */
      /* other HDF functions to get the data labels.                */

      iret = DFSDreadref(hdfname, reflist[cnt1]);
      if (iret == -1)
      {
         printf("*************************************************\n");
         printf("* ERROR - Not able to go to specified reference *\n");
         printf("*         number %d.                            *\n",dataitems[cnt1]);
         printf("*         Program has terminated.               *\n");
         printf("*************************************************\n");
         exit ( -1 );
      }/* end of if */

      /* get dimensions of SDS */

      iret = DFSDgetdims(hdfname, &numdims, dimsize, MAXRANK);
      if (iret != 0)
      {
         printf("***************************************\n");
         printf("* ERROR - Not able to get dimensions. *\n");
         printf("*         Program has terminated.     *\n");
         printf("***************************************\n");
         exit ( -1 );
      }

      iret = DFSDgetdatastrs(datalabel, dataunit, datafmt, datacoord);
      if (iret != 0)
      {
         printf("********************************************\n");
         printf("* ERROR - Not able to get data attributes. *\n");
         printf("*         Program has terminated.          *\n");
         printf("********************************************\n");
         exit ( -1 );
      }/* end of if */

      /* 08/10/94  Added this line into code to store in array form the */
      /* data label so that this array will be printed onto the screen  */
      /* instead of the annotation labels.                              */
      strcpy(datalabellist[cnt1],datalabel);

      /* search EventStr for the occurrence of datalabel */
      /* EventStr contains all the datalabels that are   */
      /* not valid choices for the user to choses.       */

      if ((strstr(EventStr, datalabel) == NULL) &&
          (strstr(EventStrNO2, datalabel) == NULL))
      {
         /* The index that corresponds to this data label */
         /* is a valid choice for the user.               */

         numchoices++;
         index[numchoices - 1] = cnt1;

      }/* end of if */
      else if (strstr(EventStr, "Geometric Altitude") != NULL)
      {
         /* this parameter is printed in the event information */
         /* but must also be a choice for the user             */
         numchoices++;
         index[numchoices - 1] = cnt1;
         ref_num[cnt3] = reflist[cnt1];
         cnt3++;
      }
      else
      {
         /* The datalabel was not a valid choice for the */
         /* user and therefore must be a parameter that  */
         /* will printed with each event of a parameter. */

         ref_num[cnt3] = reflist[cnt1];
         cnt3++;

      }/* end of if */

   }/* end of for */

   /* 12/23/94  Modified the code so that the user may have the option  */
   /* to select all of the parameters in the data file without entering */
   /* every parameter number.                                           */
   printf("\n\n");
   printf("Would you like to have the program write out all of the\n");
   printf("parameters?  Enter Y for yes or N for no.  -->  ");
   scanf("%s",all_flag);

   if ((strcmp(all_flag,"Y")==0) || (strcmp(all_flag,"y")==0) )
   {
      for (cnt1=1; cnt1 <= numchoices; cnt1++)
      {
               itemnumber = index[cnt1 - 1];
               dataitems[cnt0] = reflist[itemnumber];
               datalabelval[cnt0] = itemnumber;
               cnt0++;
      }
   }
   else
   {
   /* print labels in groups of 15 to ask for users input */

   for (cnt1 = 0; cnt1 < numchoices; ++cnt1)
   {
      if (cnt2 == 1)
      {
         itemnumber = 1;
         printf(" Item Number             Label\n\n");
      }/* end of if */

      /* 08/10/94  Modified this line of code so that the data labels would */
      /* be printed onto the screen instead of the annotation labels.  The  */
      /* data labels contain more information in them compared to the       */
      /* annotation label.  This was changed at the request of the data     */
      /* producer.                                                          */
      /* printf("               %3d           %s\n", cnt1 + 1, labellist + (index[cnt1] * MAXLNG)); */
      printf("    %3d           %s\n", cnt1 + 1, datalabellist[cnt1]); 
      cnt2++;

      if (cnt2 > 15 || cnt1 == numchoices - 1)
      {
         printf("\nPlease choose the numbers of the data items you wish to output.\n");
         printf("Enter -1 to continue to next list or 0 to begin processing.\n\n");

         while (itemnumber != 0 || itemnumber != -1)
         {
            /* read the user's selection */

            scanf("%d", &itemnumber);

            /* If user's selection equals -1, then */
            /* display 15 more parameters.         */
            if (itemnumber == -1)
               break;

            /* If the user's selection equals 0, then    */
            /* the user has finished his/her selection   */
            /* and we can return to the calling routine. */

            if (itemnumber == 0)
            {
               /* At this time, the code will print out the list of parameters  */
               /* the user has selected.  At this time, the user has the option */
               /* to continue with the program or re-enter in his selection.    */
               printf("\n\n\n");
               printf("The following is a list of the parameters you have selected:\n\n");
               for (datacount = 0; datacount < cnt0; datacount++)
               {
                printf(" %d    %s\n",datalabelval[datacount]+1,datalabellist[datalabelval[datacount]]);
               }
               printf("\n\n");
               printf("Would you like to make a new selection of these parameters or\n");
               printf("would you like this program to exit the selection process and\n");
               printf("begin retrieving the data? \n");
               printf("Enter Y for yes to retrieve data or N for no make a new selection.   --> ");
               scanf("%s",yesno);

               if (strcmp(yesno,"N")==0)
                  goto TRYAGAIN;
               else if (strcmp(yesno,"n")==0)
                  goto TRYAGAIN;
               else 
                  printf("\n\n");

               dataitems[cnt0] = 0;

               return;

            }
            else

            {
               /* If the user's selection is not -1 or 0, */
               /* then they have selected a parameter and */
               /* we will add the reference number for    */
               /* that parameter to the dataitems array.  */

               itemnumber = index[itemnumber - 1];
               dataitems[cnt0] = reflist[itemnumber];
               datalabelval[cnt0] = itemnumber;
               cnt0++;

            }/* end of else */

         }/* end of while */

         cnt2 = 1;

      }/* end of if (cnt2 > 15 || cnt1 == numchoices - 1) */
   }/* end of for */
   }/* end of outside else */

   dataitems[cnt0] = 0;

   return;

}/* end of Getdatatypes */



/****************************************************************************
*                                                                           *
* FUNCTION:  Print_data_info                                                *
*                                                                           *
* PURPOSE:   This function prints out all of the label information for those*
*            parameters that the user has just selected.                    *
*                                                                           *
****************************************************************************/
int  Print_data_info(ofp, hdfname, dataitems, ref_num)
FILE *ofp;
char *hdfname;
unsigned short int dataitems[LISTSIZE];
unsigned short int ref_num[NumEventPar];
{
   int winst[MAXRANK], windims[MAXRANK], winend[MAXRANK];
   int dims[MAXRANK], ref_dims[MAXRANK];
   int i, j, k, l, iret;
   int numdims, rnumdims;
   int32 dimsize[MAXRANK], numtype;
   int index, event;
   char datalabel[MAXLABLEN], dataunit[MAXLABLEN];
   char datafmt[MAXLABLEN], datacoord[3];
   char dimlab[2][40], dimunt[30], dimfmt[5];
   float data[MAXDATA];
   float ref_data[MAXDATA];
   float max, min;
   int num_events;
   int16 max16, min16;
   int8  max8, min8;
   uint16 umax16, umin16;


   /* according to reference numbers go to next data set */

   printf("\n\nReading labels....\n");
   k = 0;
   while (dataitems[k] != 0)
   {
      iret = DFSDreadref(hdfname, dataitems[k]);
      if (iret == -1)
      {
         printf("***********************************************\n");
         printf("* ERROR - Not able to get specified reference *\n");
         printf("*         number %d.                          *\n",dataitems[k]);
         printf("***********************************************\n");
         exit ( -1 );
      }

      /* get dimensions of SDS */

      iret = DFSDgetdims(hdfname, &numdims, dimsize, MAXRANK);
      if (iret != 0)
      {
         printf("***************************************\n");
         printf("* ERROR - Not able to get dimensions. *\n");
         printf("*         Program has terminated.     *\n");
         printf("***************************************\n");
         exit ( -1 );
      }
      else
      {
         /*  08/09/94                                                           */
         /*  The data producer has asked to comment this line out.  Please feel */
         /*  free to remove these comments to print out the dimensions of the   */
         /*  parameters in the output report file.                              */
         /*  fprintf(ofp, "\n\nDimensions are %d by %d\n\n", dimsize[0], dimsize[1]); */
         num_events = dimsize[1];
      }/* end of else */

      /* get number type */

      iret = DFSDgetNT(&numtype);
      if (iret != 0)
      {
         printf("**********************************************\n");
         printf("* ERROR - Not able to get DFSDgetNT numtype. *\n");
         printf("*         Program has terminated.            *\n");
         printf("**********************************************\n");
         exit ( -1 );
      }

      /* Print message indicating there are no dimension scales */

      fprintf(ofp, "*** There are no dimension scales for this data set. ***\n\n");

                          /* set up slice dimensions */

      /* no subsetting required */
      winst[0] = 1;
      winst[1] = 1;
      windims[0] = dimsize[0];
      windims[1] = dimsize[1];
      dims[0] = windims[0];
      dims[1] = windims[1];

      /*   Print dimension attributes   */

      for (l = 1; l <= numdims; l++)
      {
         iret = DFSDgetdimstrs(l, dimlab[l - 1], dimunt, dimfmt);
         if (iret != 0)
         {
            printf("*************************************************\n");
            printf("* ERROR - Not able to get dimension attributes. *\n");          
            printf("*         Program has terminated.               *\n");
            printf("*************************************************\n");
            exit ( -1 );
         }
         else
         {
            fprintf(ofp, "%s%s\n%s%s\n%s%s\n\n", "Description : ", dimlab[l - 1],
                    "Units        : ", dimunt, "Format       : ", dimfmt);
         }
      }

      /*  get data attributes */

      iret = DFSDgetdatastrs(datalabel, dataunit, datafmt, datacoord);
      if (iret != 0)
      {
         printf("********************************************\n");
         printf("* ERROR - Not able to get data attributes. *\n");          
         printf("*         Program has terminated.          *\n");
         printf("********************************************\n");
         exit ( -1 );
      }
      else
      {
         /* Print the data attributes */

         fprintf(ofp, "Data attributes are as follows:\n\n");
         fprintf(ofp, "%s%s\n%s%s\n%s%s\n\n", "Label : ", datalabel, "Units : ",
                 dataunit, "Format: ", datafmt);
      }

      /* Get data max and min values */

      switch (numtype)
      {
         case DFNT_FLOAT32:
            iret = DFSDgetrange((void *)&max, (void *)&min);
            if (iret == -1)
            {
               printf("*******************************************\n");
               printf("* ERROR - Not able to get 32-bit data max *\n");
               printf("*         and min values.                 *\n");
               printf("*         Program has terminated.         *\n");
               printf("*******************************************\n");
               exit ( -1 );
            }
            else
            {
                 /*   print the data max and mins  */
               fprintf(ofp, "%s%.8f\n", "Data Max: ", max);
               fprintf(ofp, "%s%.8f\n\n", "Data Min: ", min);
            }
            break;
         case DFNT_UINT16:
            iret = DFSDgetrange((void *)&umax16,(void *)&umin16);
            if (iret == -1)
            {
               printf("*******************************************\n");
               printf("* ERROR - Not able to get 16-bit data max *\n");
               printf("*         and min values (unsigned).      *\n");
               printf("*         Program has terminated.         *\n");
               printf("*******************************************\n");
               exit ( -1 );
            }
            else
            {
                 /*   print the data max and mins  */
               fprintf(ofp, "%s%x\n", "Data Max: ", umax16);
               fprintf(ofp, "%s%x\n\n", "Data Min: ", umin16);
            }
            break;
         case DFNT_INT16:
            iret = DFSDgetrange((void *)&max16,(void *)&min16);
            if (iret == -1)
            {
               printf("*******************************************\n");
               printf("* ERROR - Not able to get 16-bit data max *\n");
               printf("*         and min values.                 *\n");
               printf("*         Program has terminated.         *\n");
               printf("*******************************************\n");
               exit ( -1 );
            }
            else
            {
                 /*   print the data max and mins  */
               fprintf(ofp, "%s%d\n", "Data Max: ", max16);
               fprintf(ofp, "%s%d\n\n", "Data Min: ", min16);
            }
            break;
         case DFNT_INT8:
            iret = DFSDgetrange((void *)&max16,(void *)&min16);
            if (iret == -1)
            {
               printf("******************************************\n");
               printf("* ERROR - Not able to get 8-bit data max *\n");
               printf("*         and min values.                *\n");
               printf("*         Program has terminated.        *\n");
               printf("******************************************\n");
               exit ( -1 );
            }
            else
            {
                 /*   print the data max and mins  */
               fprintf(ofp, "%s%d\n", "Data Max: ", max8);
               fprintf(ofp, "%s%d\n\n", "Data Min: ", min8);
            }
            break;
         default:
            exit ( -1 );
            break;
       }

       k++;
       fprintf(ofp, "\n\n");

   }/* end of while */

   return (num_events);
}   /* End of function, Print_data_info. */

/****************************************************************************
*                                                                           *
* FUNCTION:  Read_data                                                      *
*                                                                           *
* PURPOSE:   This function prints out all of the data for those parameters  *
*            the user has just selected.                                    *
*                                                                           *
****************************************************************************/
void Read_data(ofp, hdfname, dataitems, ref_num, num_events, exp)
FILE *ofp;
char *hdfname;
unsigned short int dataitems[LISTSIZE];
unsigned short int ref_num[NumEventPar];
int num_events;
int exp;
{
   int32 winst[MAXRANK], windims[MAXRANK], winend[MAXRANK];
   int32 dims[MAXRANK], ref_dims[MAXRANK];
   int ii, i,j, k, l, iret;
   int numdims, rnumdims;
   int32 dimsize[MAXRANK], numtype;
   int index, event,firstevent;
   char datalabel[MAXLABLEN], dataunit[MAXLABLEN];
   char datafmt[MAXLABLEN], datacoord[3];
   char dimlab[2][40], dimunt[30], dimfmt[5];
   float data[MAXDATA];
   float ref_data[MAXDATA];
   float max, min;
   char stringdate[7], stringtime[7];                  /* 08/10/94 */
   uint16 udata16[MAXDATA],uref_data16[MAXDATA],umax16,umin16;
   int16 data16[MAXDATA],ref_data16[MAXDATA],max16,min16;
   int8 data8[MAXDATA],ref_data8[MAXDATA],max8,min8;
   int16 temp;


   /* According to reference numbers go to next data set */

   printf("\n\nReading data, Please wait ...\n");

   /* print out message for data arrangement */
   fprintf(ofp, "Data is printed from left to right in event order.\n\n\n\n");

   for (ii=0; ii<num_events; ii++)
   {
       if ((ii + 1) % 50 == 0)
          printf("\n             ... and wait ...\n");

       fprintf(ofp, "\n\n*************************** EVENT NO. %d ******************************\n",ii+1);
       fprintf(ofp, "EventDate    EventTime       Lat.         Long.");
       fprintf(ofp, "    EventType    Minimum Alt.\n");
       firstevent = 1;
       k = 0;
       while (dataitems[k] != 0)
       {
          iret = DFSDreadref(hdfname, dataitems[k]);
          if (iret == -1)
          {
             fprintf(ofp,"*********************************************************\n");
             fprintf(ofp,"* ERROR - On going to specified reference number - ");
             fprintf(ofp,"%d. *\n", dataitems[k]);
             fprintf(ofp,"*         Program has terminated.                       *\n");
             fprintf(ofp,"*********************************************************\n");
             exit ( -1 );
          }

          /* get dimensions of SDS */

          iret = DFSDgetdims(hdfname, &numdims, dimsize, MAXRANK);
          if (iret != 0)
          {
             fprintf(ofp,"***************************************\n");
             fprintf(ofp,"* ERROR - Not able to get dimensions. *\n");
             fprintf(ofp,"*         Program has terminated.     *\n");
             fprintf(ofp,"***************************************\n");
             exit ( -1 );
          }

          /* get number type */

          iret = DFSDgetNT(&numtype);
          if (iret != 0)
          {
             fprintf(ofp,"****************************************\n");
             fprintf(ofp,"* ERROR - Not able to get number type. *\n");
             fprintf(ofp,"*         Program has terminated.      *\n");
             fprintf(ofp,"****************************************\n");
             exit ( -1 );
          }
    
          /* set up slice dimensions -  no subsetting required */

          winst[0] = 1;
          winst[1] = 1;
          windims[0] = dimsize[0];
          windims[1] = dimsize[1];
          dims[0] = windims[0];
          dims[1] = windims[1];

          /*  get data attributes */

          iret = DFSDgetdatastrs(datalabel, dataunit, datafmt, datacoord);
          if (iret != 0)
          {
             fprintf(ofp,"********************************************\n");
             fprintf(ofp,"* ERROR - Not able to get data attributes. *\n");
             fprintf(ofp,"*         Program has terminated.          *\n");
             fprintf(ofp,"********************************************\n");
             exit ( -1 );
          }
    
          if (numtype == DFNT_FLOAT32)
          {
             /*  get data max and min values */
             iret = DFSDgetrange((void *)&max, (void *)&min);
             if (iret == -1)
             {
                fprintf(ofp,"********************32**********************\n");
                fprintf(ofp,"* ERROR - Not able to get data max & min.  *\n");
                fprintf(ofp,"*         Program has terminated.          *\n");
                fprintf(ofp,"********************************************\n");
                exit ( -1 );
             }

             /*  get data slice */
             iret = DFSDgetslice(hdfname, winst, windims, (void *)&(data[0]), dims);
             if (iret == -1)
             {
                fprintf(ofp,"****************************************\n");
                fprintf(ofp,"* ERROR - Not able to get data slice.  *\n");
                fprintf(ofp,"*         Program has terminated.      *\n");
                fprintf(ofp,"****************************************\n");
                exit ( -1 );
             }
          }
          else if (numtype == DFNT_UINT16)
          {
             if ( (exp == 3) || (exp == 4) ) /* SAGE II Ozone or NO2 */
             {
                if (strcmp(datalabel,"Number Density Quality Bit Flag")==0)
                {
                   iret = DFSDgetslice(hdfname, winst, windims, (void *)&(udata16[0]), dims);
                   if (iret == -1)
                   {
                      fprintf(ofp,"***********************************************\n");
                      fprintf(ofp,"* ERROR - Not able to get 16-bit data slice.  *\n");
                      fprintf(ofp,"*         Program has terminated.             *\n");
                      fprintf(ofp,"***********************************************\n");
                      exit ( -1 );
                   }
                }
                else if (strcmp(datalabel,"Volumetric Mixing Ratio Quality Bit Flag")==0)
                {
                   iret = DFSDgetslice(hdfname, winst, windims, (void *)&(udata16[0]), dims);
                   if (iret == -1)
                   {
                      fprintf(ofp,"***********************************************\n");
                      fprintf(ofp,"* ERROR - Not able to get 16-bit data slice.  *\n");
                      fprintf(ofp,"*         Program has terminated.             *\n");
                      fprintf(ofp,"***********************************************\n");
                      exit ( -1 );
                   }
                }
                /*  get data max and min values */
                iret = DFSDgetrange((void *)&umax16, (void *)&umin16);
                if (iret == -1)
                {
                   fprintf(ofp,"********************16**********************\n");
                   fprintf(ofp,"* ERROR - Not able to get data max & min.  *\n");
                   fprintf(ofp,"*         Program has terminated.          *\n");
                   fprintf(ofp,"********************************************\n");
                   exit ( -1 );
                }
             }
             else if (exp == 5)  /* SAGE II H2O */
             {
                if (strcmp(datalabel,"Number Density Quality Flags")==0)
                {
                   iret = DFSDgetslice(hdfname, winst, windims, (void *)&(udata16[0]), dims);
                   if (iret == -1)
                   {
                      fprintf(ofp,"***********************************************\n");
                      fprintf(ofp,"* ERROR - Not able to get 16-bit data slice.  *\n");
                      fprintf(ofp,"*         Program has terminated.             *\n");
                      fprintf(ofp,"***********************************************\n");
                      exit ( -1 );
                   }
                }
                else if (strcmp(datalabel,"Volumetric Mixing Ratio Quality Flags")==0)
                {
                   iret = DFSDgetslice(hdfname, winst, windims, (void *)&(udata16[0]), dims);
                   if (iret == -1)
                   {
                      fprintf(ofp,"***********************************************\n");
                      fprintf(ofp,"* ERROR - Not able to get 16-bit data slice.  *\n");
                      fprintf(ofp,"*         Program has terminated.             *\n");
                      fprintf(ofp,"***********************************************\n");
                      exit ( -1 );
                   }
                }
                /*  get data max and min values */
                iret = DFSDgetrange((void *)&umax16, (void *)&umin16);
                if (iret == -1)
                {
                   fprintf(ofp,"********************16**********************\n");
                   fprintf(ofp,"* ERROR - Not able to get data max & min.  *\n");
                   fprintf(ofp,"*         Program has terminated.          *\n");
                   fprintf(ofp,"********************************************\n");
                   exit ( -1 );
                }
             }
          }
          else if (numtype == DFNT_INT16)
          {
             /*  get data max and min values */
             iret = DFSDgetrange((void *)&max16, (void *)&min16);
             if (iret == -1)
             {
                fprintf(ofp,"********************16**********************\n");
                fprintf(ofp,"* ERROR - Not able to get data max & min.  *\n");
                fprintf(ofp,"*         Program has terminated.          *\n");
                fprintf(ofp,"********************************************\n");
                exit ( -1 );
             }
             iret = DFSDgetslice(hdfname, winst, windims, (void *)&(data16[0]), dims);
             if (iret == -1)
             {
                fprintf(ofp,"***********************************************\n");
                fprintf(ofp,"* ERROR - Not able to get 16-bit data slice.  *\n");
                fprintf(ofp,"*         Program has terminated.             *\n");
                fprintf(ofp,"***********************************************\n");
                exit ( -1 );
             }
          }
          else if (numtype == DFNT_INT8)
          {
             /*  get data max and min values */
             iret = DFSDgetrange((void *)&max8, (void *)&min8);
             if (iret == -1)
             {
                fprintf(ofp,"*********************8**********************\n");
                fprintf(ofp,"* ERROR - Not able to get data max & min.  *\n");
                fprintf(ofp,"*         Program has terminated.          *\n");
                fprintf(ofp,"********************************************\n");
                exit ( -1 );
             }
             iret = DFSDgetslice(hdfname, winst, windims, (void *)&(data8[0]), dims);
             if (iret == -1)
             {
                fprintf(ofp,"**********************************************\n");
                fprintf(ofp,"* ERROR - Not able to get 8-bit data slice.  *\n");
                fprintf(ofp,"*         Program has terminated.            *\n");
                fprintf(ofp,"**********************************************\n");
                exit ( -1 );
             }
          }

          /*   print the parameters that are to be printed with each event   */

          if (firstevent == 1)
          {
             for (event = 0; event < NumEventPar; ++event)
             {
                iret = DFSDreadref(hdfname, ref_num[event]);
                if (iret == -1)
                {
                    fprintf(ofp, "Error on reading ref_num - %d\n\n", ref_num[event]);
                    exit ( -1 );
                }
                iret = DFSDgetdims(hdfname, &rnumdims, dimsize, MAXRANK);
                if (iret == -1)
                {
                   fprintf(ofp, "Error in getting ref_dims\n\n");
                }
                winst[0] = 1;
                winst[1] = 1;
                windims[0] = dimsize[0];
                windims[1] = dimsize[1];
                ref_dims[0] = windims[0];
                ref_dims[1] = windims[1];

                iret = DFSDgetslice(hdfname, winst, windims, (void *)&(ref_data[0]), ref_dims);
                if (iret == -1)
                {
                   fprintf(ofp, "Error on getting ref_data\n\n");
                   exit ( -1 );
                }

                /* Print out event information for each record */
                if (event == 0)          /* EventDate */
                   /* Will print out leading blanks */
                   fprintf(ofp, " %06.0f\t", ref_data[ii]);
                else if (event == 1)     /* EventTime */
                   /* Will print out leading blanks */
                   fprintf(ofp, "     %06.0f\t", ref_data[ii]);
                else if (event == 2)
                   fprintf(ofp, "   %6.1f\t", ref_data[ii]);
                else if (event == 3)
                   fprintf(ofp, "%6.1f\t", ref_data[ii]);
                else if (event == 4)
                {
                   if (ref_data[ii] == 0.0)
                      fprintf(ofp, "    Sunrise\t", ref_data[ii]);
                   else if (ref_data[ii] == 1.0)
                      fprintf(ofp, "    Sunset\t", ref_data[ii]);
                }
                else if (event == 5)
                   fprintf(ofp, "    %5.1f\t", ref_data[ii]);
             }  /* end of for event */
             firstevent++;
          }

          fprintf(ofp, "\n\n");

          /* Print the data values for dataitem[k] and event[i] */

          fprintf(ofp, "%s:\n",datalabel);
          for (j = 0; j < dims[0]; j++)
          {
             /* calculate the index in the data array at which   */
             /* the next value occurs, and then print that value */

             index = j * dims[1] + ii;
             if (numtype == DFNT_FLOAT32)
                fprintf(ofp, "%15.6e", data[index]);
             else if (numtype == DFNT_UINT16)
             {
                fprintf(ofp,"%15x",udata16[index]);
             }
             else if (numtype == DFNT_INT16)
             {
                fprintf(ofp, "% 15d", data16[index]);
             }
             else if (numtype == DFNT_INT8)
                fprintf(ofp, "%d", data8[index]);

             /* print 5 values per line in the report file */

             if ((j + 1) % 5 == 0)
                fprintf(ofp, "\n");

          }/* end of for */

          /*  continue while loop to get data */

          k++;
       }/* end of while */
    } /* end of for */

    return;

}/* End of function, Read_data */
