PRO read_sage2_version6
;=================================================================================
; Program:     read_sage2_version6.pro
;
; VERSION:                   1.0                                                    
;
; PURPOSE/FUNCTION:          Open and read SAGE II INDEX and SPEC data files.       
;                            Write the values of each selected parameter[s]         
;                            to the output file.  A call to dialog_pickfile is      
;                            used to create a dialog box for filename choice.       
;                            The 'FILTER' parameter may need to be modified to        
;                            correspond to the location of the input files. 
;      
;    Name                 Type            Description
;    ----                 ----            -----------
;   filename              string      Name of the data file returned by the              
;                                     dialog_pickfile routine.                           
;   s                     string      Returns the location for the word INDEX or
;                                     SPEC found in the filename.
;   newn                  string      Substring created from the data filename    
;                                     and is used to create the output filename.         
;   typeflag              integer     Flag set to 1 or 2 depending upon whether  
;                                     the INDEX or SPEC file is to be read.              
;   print_var             array       Array that holds the selected variable      
;                                     names the user has chosen to print.                
;   goodIndices           array       Array containing the indices of the selected
;                                     data that is not overscale.
;   kcount                integer     Total number of valid selected variables.
;   selected_vars         array       Array containing all of the variables the 
;                                     user chose from the menu.
;   var_list              array       Entire list of INDEX variables to choose from.
;   kcount                integer     Total number of good variables to print.
;   var_list_two          array       Entire list of SPEC variables to choose from.
;   n_elements            array       Selected variables from the menu list.
;   out_lun               integer     Output logical unit number.
;
;
;
; ALGORITHM:                 none                                                   
;
; INVOCATION:                >idlde   [Then follow the internal prompts.]              
;                            A description of this is available in the readme file.
;
; EXTERNAL ROUTINES:         none                                                   
;
; INTERNAL ROUTINES:         make_list
;                            make_list_two
;                            GET_PRINT_OUT
;                            openthefile
;                            readstructs
;                            getstructinfo
;                            indexinfo_60d
;                            specinfo_600
;                            getquantstr
;                            openandread
;                            openinputfile
;                            index_data
;                            get_right_data
;                            find_the_units 
;
; LANGUAGE/COMPILER VERSION: IDL 5.2                                                
;
;
;  Point of Contact:   Comments or questions should be directed to:
;                      Atmospheric Sciences Data Center
;                      Mail Stop 157D                                      
;                      2 South Wright Street                               
;                      NASA Langley Research Center                        
;                      Hampton, Virginia 23681-2199                        
;                      U.S.A.                                              
;                                                               
;                      Telephone: (757)864-8656                             
;                      FAX:       (757)864-8807                             
;                      URL:http://eosweb.larc.nasa.gov
;                      E-mail Address: larc@eos.nasa.gov                         
; Updates:
; 10/05/2000 - 1.0
;                       
;                       
;                                                               
;=================================================================================

; --- dialog box containing filenames.
; --- The path parameter may be added to suit your system.
; --- Change the filter= '/path/' to the correct path to find your data files.

;---------------------------------------------------------------------
filename = dialog_pickfile(/read,filter='/fs1/CDROM_SAGEII_V6/cdrom1/DATA/*')
;---------------------------------------------------------------------
s = STRPOS(filename,'SAGE_II')
newn = STRMID(filename, s, 50)

print, " ****************  Begin reading data *********************"
; --- Have User select parameters to output to file
print, " "
print, " "
print,  " CHOOSE THE PARAMETERS TO BE SAVED"
print, " "

;---  print variables for the INDEX files
s = STRPOS(filename,'INDEX')
if(s gt 0) then begin
  typeflag = 1
;-------------------
  make_list,var_list
;-------------------
  selectTool,var_list,selected_vars
;-------------------
  print_var=var_list[selected_vars]
  print, " "
  print,'You chose the following ',n_elements(selected_vars),' parameters:'
  print,var_list[selected_vars]
  print, " "
  goodIndices = where(selected_vars ne -1, kcount)
  kcount = kcount -1
endif

;---  print variables for the SPEC files
s = STRPOS(filename,'SPEC')
if(s gt 0) then begin
  typeflag = 2
;-------------------
  make_list_two,var_list_two
;-------------------
  selectTool,var_list_two,selected_vars
;-------------------
  print_var=var_list_two[selected_vars]
  print, " "
  print,'You chose the following ',n_elements(selected_vars),' parameters:'
  print,var_list_two[selected_vars]
  print, " "
  goodIndices = where(selected_vars ne -1, kcount)
  kcount = kcount -1
endif
;--------------------

; --- open output file
openw,out_lun,newn+'_output',/get_lun
;--------------------
openthefile,filename,out_lun,print_var,kcount,typeflag
;--------------------
print, " "
print,"PROGRAM HAS RUN TO COMPLETION."
print, " "
print,"The output is on file:"   
print,newn+'_output'
print, " "
END

PRO make_list,var_list
;=================================================================================
; Routine Name: MAKE_LIST
;
; PURPOSE/FUNCTION:   This routine will set up a list of variables for the   
;                     SAGE II INDEX files.                                      
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   var_list              array       This is a list of variables available to
;                                     choose from. This array returns the
;                                     selected INDEX names. 
;=================================================================================
var_list=[$
'Num_Prof',$         
'Met_Rev_Date',$
'Driver_Rev',$
'Transmission_Rev',$
'Inversion_Rev',$
'Spectroscopy_Rev',$
'Eph_File_Name',$
'Met_File_Name',$
'Ref_File_Name',$
'Trans_File_Name',$
'Spec_File_Name',$
'FillVal',$
'Grid_Size',$
'Alt_Grid',$
'Range_Trans',$
'Range_O3',$
'Range_NO2',$
'Range_H2O',$
'Range_Ext',$
'Range_Density',$
'Reserved',$
'YYYYMMDD',$
'event_num',$
'HHMMSS',$
'Day_Frac',$
'Lat',$
'Lon',$
'Beta',$
'Duration',$
'Type_Sat',$
'Type_Tan',$
'Dropped',$
'InfVec',$
'Eph_Cre_Date',$
'Eph_Cre_Time',$
'Met_Cre_Date',$
'Met_Cre_Time',$
'Ref_Cre_Date',$
'Ref_Cre_Time',$
'TRANS_Cre_Date',$
'TRANS_Cre_Time',$
'SPECIES_Cre_Date',$
'SPECIES_Cre_Time']
return
END

PRO make_list_two,var_list_two
;=================================================================================
; Routine Name: MAKE_LIST_TWO
;
; PURPOSE/FUNCTION:   This routine will set up a list of variables for the   
;                     SAGE II SPEC (species) files.                                      
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   var_list_two          array       This is a list of variables available to
;                                     choose from. This array returns the 
;                                     selected SPEC names. Passed back.
;=================================================================================
var_list_two=[$
'Tan_Alt',$         
'Tan_Lat',$         
'Tan_Lon',$         
'NMC_Pres',$         
'NMC_Temp',$         
'NMC_Dens',$         
'NMC_Dens_Err',$         
'Trop_Height',$         
'Wavelength',$         
'O3',$         
'NO2',$         
'H2O',$         
'Ext386',$         
'Ext452',$         
'Ext525',$         
'Ext1020',$         
'Reserved',$         
'Reserved',$         
'O3_Err',$         
'NO2_Err',$         
'H2O_Err',$         
'Ext386_Err',$         
'Ext452_Err',$         
'Ext525_Err',$         
'Ext1020_Err',$         
'Reserved',$         
'Reserved',$         
'InfVec']
return
END

Pro selectTool,title,selected_vars,help=help
;=================================================================================
; Routine Name: SELECTTOOL
;
; PURPOSE/FUNCTION:   This procedure will create a GUI to display for a user to
;                     choose variables from a list of variable names.        
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   title                 string      Header on the GUI base window used to display
;                                     the selection variables. Used internally.
;   base                  widget      Widget ID of the top level widget base that
;                                     is created. Used internally.
;   void                  widget      Creates a button widget. Used internally.
;   menubase              widget      Sets up the menu bar.  Used internally.
;   subBaseB              widget      Contains the widget base and puts
;                                     buttons at the top of the subbase.  Used
;                                     internally.
;   subBase               widget      Contains a widget base which
;                                     holds the variable list.  Used internally.
;   listID                integer     Contains the widget id of the widget generating
;                                     the event. Used internally.
;   state                 structure   This structure initializes the UValue
;                                     structure.  Used internally.                       
;   n_elements            array       Selected variables from the menu list. Used
;                                     internally.
;   selected_vars         array       Array containing the values the user selected
;                                     from the menu. Returns the variables selected.
;   vars                  array       Contains the selected variables from the menu.
;                                     Passed back.
;=================================================================================
common selectTool, vars,help_string

;Create a GUI base

   base=widget_base(/column,title='Choose the variables to be read',mbar=menubase)

;Set up the menu bar

   void=cw_pdmenu(menubase,/mbar,['1\File','2\Abort Read'],/return_name)

;Create a subBase to put buttons at the top

   subBaseB=widget_base(base,column=3)
   void=widget_button(subBaseB,value='Done')
   void=widget_button(subBaseB,value='Help')
   void=widget_button(subBaseB,value='Select All')

;Create a subBase for the variable list

   subBase=widget_base(base,/row)
   listID=widget_list(subBase,value=Title,ysize=7,/multiple)

;Draw the window

   widget_control,base,/realize

;Initialize the UValue structure

   state={listID:listID, all:indgen(n_elements(title))}

   widget_control,base,set_uvalue=state

   xmanager,'selectTool',base        ;,cleanup='vtClean'

   selected_vars=vars
   print,"End of select"
   return
End

Pro selectTool_event,event
;=================================================================================
; Routine Name: SELECTTOOL_EVENT
;
; PURPOSE/FUNCTION:   This procedure manages events generated by the         
;                     selectTool GUI.                                        
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   vars                  array       Contains the selected variables from the menu.
;                                     Passed back.
;   thisType              string      This variable holds the widget event id.
;                                     Passed back.
;=================================================================================

common selectTool,vars
widget_control,event.top,get_uvalue=state

thisType=widget_info(event.id,/name)
widget_control,event.top,get_uvalue=state

if (thisType eq'LIST') then thisValue='LIST' else $
   if (thisType eq 'BUTTON') then widget_control,event.id,get_value=thisValue $
   else thisValue=event.value

case thisValue of
   'Quit':Begin
       widget_control,event.top,/destroy
       retall
       end
   'Help': begin
           print,''
           print,'      Select the variables to be saved.'
           if (!d.name eq 'X') then begin
              print,'      Holding down the Shift key and clicking an item selects the range '
              print,'      from the previously selected item to the new item. Holding down the'
              print,'      mouse button when selecting items also selects a range. Holding '
              print,'      down the Control key and clicking an item toggles that item between'
              print,'      the selected and unselected state.'
              print,''
           endif else if (!d.name eq 'WIN') or (!d.name eq 'MAC') then begin
              print,'      Holding down the Shift key and clicking an item selects the range '
              print,'      from the previously selected item to the new item. Holding down the'
              print,'      Control key and clicking an item toggles that item between the '
              print,'      selected and unselected state.'
              print,''
           endif
           end
   'LIST':
   'Done':  Begin
     widget_control,event.top,get_uvalue=state
     vars=widget_info(state.listID,/list_select)
     if (vars[0] eq -1) then begin
        print,'NOT DONE. No variables were selected.'
     endif else widget_control,event.top,/destroy
     END
    'Exit': Begin
            widget_control,event.top,/destroy
            return
            end
   'Select All':widget_control,state.listID,set_list_select=state.all

    'Abort Read': begin
                  widget_control,event.top,/destroy
                  retall
                  end
    else: print,'Unknown Event'
endcase

return
END

PRO GET_PRINT_OUT,filename,out_lun,icount,name2,value,typ,ifirst,unit,print_var $
                 ,newframe
;=================================================================================
; Routine Name: GET_PRINT_OUT
;
; PURPOSE/FUNCTION:   Prints the selected INDEX or SPEC values selected from 
;                     the input data file.                                   
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   filename              string      Name of the selected raw data file
;                                     that is passed in.
;   out_lun               integer     Variable containing the logical unit number of
;                                     the output file. Passed in.
;   icount                input       Counter for the number of records   
;                                     processed. Passed in.
;   name2                 string      Variable name for the data. It is
;                                     passed in.
;   value                 real        Data value for the selected name. 
;                                     Passed in.
;   typ                   string      The type of data being processed, INDEX or SPEC.
;                                     Passed in.
;   results               string      System time. Used internally.
;   ifirst                integer     Flag set so the header is only      
;                                     printed once. Used internally.
;   unit                  string      Contains the unit description for
;                                     each variable name printed out. Passed in.
;   print_var             array       Array containing the selected variables to
;                                     print.  Passed in.                                 
;   newframe              integer     A flag that tells the routine when a new
;                                     event number header needs to be printed.
;                                     Passed in.
;=================================================================================
  if(typ eq "INDEX") then begin
    printf,out_lun,' '
    if (ifirst eq 0) then begin
      printf,out_lun,'   ',filename
      printf,out_lun,' '
      results = SYSTIME()
      printf,out_lun,results
      printf,out_lun,' '
      printf,out_lun,'                             VALUES for ',typ
      printf,out_lun,'=============================================================================='
      ifirst = 1
    endif
      printf,out_lun,format="('Selected Variable: ',a)",name2
      printf,out_lun,format="('Parameter units = ',a)",unit
      printf,out_lun,format="('Data       =')"
      if((icount gt 11) AND (icount lt 21) OR (icount gt 24) AND (icount lt 28)) then begin
        printf,out_lun,format="(6(f10.2))",value
      endif else begin
      printf,out_lun,value
    endelse
      printf,out_lun,'------------------------------------------------------------------------------'
  endif
  if(typ eq "SPECIES") then begin
    if (ifirst eq 0) then begin
      printheadstuff,out_lun,filename
      ifirst = 1
    endif
    if (newframe eq 0) then begin
      callprintvals,out_lun,typ,icount
      newframe=1
    endif
      callprintit,out_lun,name2,unit,value
  endif
END

PRO printheadstuff,out_lun,filename
;=================================================================================
; Routine Name: PRINTHEADSTUFF
;
; PURPOSE/FUNCTION:   Prints the filename and date at the top of the output file.
;
;
;   out_lun               integer     The logical number for the input file.
;                                     Passed in.                                 
;   filename              string      Name of the selected raw data file
;                                     that is passed in.
;   results               string      The string that holds the date and time
;                                     returned from the system.  Used internally.
;=================================================================================
  printf,out_lun,' '
  printf,out_lun,'   ',filename
  printf,out_lun,' '
  results = SYSTIME()
  printf,out_lun,results
  printf,out_lun,' '
END

PRO callprintvals,out_lun,typ,icount
;=================================================================================
; Routine Name: CALLPRINTVALS
;
; PURPOSE/FUNCTION:   Prints the event and type header each time the event
;                     number changes.
;
;
;   out_lun               integer     The logical number for the output file.
;                                     Passed in.                                 
;   typ                   string      Set to the type of structure being    
;                                     processed INDEX or SPEC. Used internally.
;   icount                integer     This variable holds the number for the
;                                     event being written out. Passed in.
;=================================================================================
  printf,out_lun,'                             VALUES for ',typ
  printf,out_lun,'=============================================================================='
  printf,out_lun,format="('                            Event Number: ',i)",icount
  printf,out_lun,'------------------------------------------------------------------------------'
  printf,out_lun,' '
END

PRO callprintit,out_lun,name2,unit,value
;=================================================================================
; Routine Name: CALLPRINTIT
;
; PURPOSE/FUNCTION:   Prints the selected values from the input file.
;
;
;   out_lun               integer     The logical number for the output file.
;                                     Passed in.                                 
;   unit                  string      Contains the units for the selected
;                                     name from the structure. Passed in.
;   name2                 string      Variable name for the data. It is
;                                     passed in.
;   value                 real        Data value for the selected name. 
;                                     Passed in.
;=================================================================================
  printf,out_lun,format="('Selected Variable: ',a)",name2
  printf,out_lun,format="('Parameter units = ',a)",unit
  printf,out_lun,format="('Data       =')"
  printf,out_lun,value
  printf,out_lun,'------------------------------------------------------------------------------'
END

PRO get_number_records,inlun,nvals,vers,typ,struct
;=================================================================================
; Routine Name:GET_NUMBER_RECORDS
;
; PURPOSE/FUNCTION:   This routine gets the number of events listed on the 
;                     input file by counting the records.  The file is then
;                     rewound to the beginning.
;
;
;   inlun                 integer     The logical number for the input file.
;                                     Passed in.                                 
;   struct                structure   Contains the selected data
;                                     returned from the data structure. Passed in.
;   rec                   structure   Contains the selected data returned from the
;                                     data structure.  Used internally.
;   typ                   string      Set to the type of structure being    
;                                     processed INDEX or SPEC. Used internally.
;   vers                  string      Version number. Passed in.
;   data                  array       Selected structure records.       
;                                     Used internally.
;   nvals                 integer     This variable returns the number of events
;                                     that are found on the input file.  This
;                                     variable is passed back and used in a loop.
;=================================================================================

   getstructinfo,struct,typ,vers
   POINT_LUN,inlun,0
   while NOT EOF(inlun) DO BEGIN
     data = assoc(inlun,struct)
     rec = data(nvals)
     nvals = nvals + 1
   ENDWHILE
   POINT_LUN,inlun,0
END
PRO openthefile,filename,out_lun,print_var,kcount,typeflag
;=================================================================================
; Routine Name: OPENTHEFILE
;
; FUNCTION:           Opens the selected input file, and calls the read      
;                     structure routine.                                     
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   filename              string      Name of the selected raw data file
;                                     that is passed in.
;   out_lun               integer     Logical unit number for the output file.
;                                     Passed in.
;   print_var             array       Array containing the selected variables to
;                                     print.  Passed in.                                 
;   kcount                integer     The number of the print_var
;                                     variables to print.  Passed in.
;   typeflag              integer     Flag that determines which type of data to 
;                                     print. Passed in.
;   inlun                 integer     Logical unit number for the input file.
;                                     Used internally.
;   err                   integer     Error number returned from the open command.
;                                     Used internally.
;   error_return          integer     Error number if the open wasn't 
;                                     successful. Used internally.
;   recnum                real        Data from the structure element(s) selected.
;                                     Used internally.  
;   rec                   real        Data from the structure element(s) selected.
;                                     Used internally.  
;   vers                  string      Version number. Used internally.
;   quant                 string      Selected variable name. Used internally.
;=================================================================================
  openr,inlun,filename,/get_lun,error=err
;                           open the input file
  if (err ne 0) then begin
    error_return = err
    print,!ERR_STRING
    return
  endif
  recnum=0
  rec=0
  quant=print_var[0]
  readstructs,filename,vers=vers,quant=quant $
             ,out_lun,error_return=error_return $
             ,kcount,print_var,typeflag
END

PRO readstructs,filename,vers=vers,quant=quant $
               ,out_lun,error_return=error_return $
               ,kcount,print_var,typeflag
;=================================================================================
; Routine Name: READSTRUCTS
;
; FUNCTION:           This function calls routines that will return records  
;                     from a structure.                                      
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   filename              string      Input filename. Passed in.
;   vers                  string      Version number of the data.  
;                                     Passed back.
;   quant                 string      Contains the variable name to
;                                     return from the structure.  Passed back.
;   out_lun               integer     Logical unit number
;                                     of the output file. Passed in.
;   error_return          integer     Read error flag. Passed back.
;   kcount                integer     Total number of
;                                     variables selected. Passed in.
;   print_var             array       Array containing the variable names to be
;                                     printed.  Passed in.
;   typeflag              integer     Flag which determines which data to select.
;                                     Passed in.
;   struct                structure   Structure returns the type of data requested.
;                                     Used internally.
;   typ                   string      Type of data requested, INDEX or SPEC. 
;                                     Passed in.
;   tags                  arrays      Tag number of a record returned from the 
;                                     structure.  Passed back.
;   qnum                  integer     Index for the quant name. Passed back.
;                                     Used internally. 
;====================================================================================
;--- extract the version from the filename
  if(typeflag eq 1) then typ = "INDEX"
  if(typeflag eq 2) then typ = "SPEC"
  if not keyword_set(vers) then begin
    vers = rstrpos(filename,'SAGE_II_'+typ+'_')+strlen(typ)+16
    vers = strmid(filename,vers,4)
  endif
;------------
  getstructinfo,struct,typ,vers
;------------
  getquantstr,quant,tags,qnum,struct,filename,typ
;------------
;--- prepare to read the file
;---------------------------------------------------------------------
    openandread,filename,struct,out_lun,tags $
               ,kcount,print_var,typeflag,vers,typ
;---------------------------------------------------------------------
  return
END

PRO getstructinfo,struct,typ,vers
;=================================================================================
; Routine Name: GETSTRUCTINFO
;
; FUNCTION:           This function will pick out the structure that matches 
;                     the type and version provided.                         
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   struct                structure   Data returned from the structure.
;                                     Passed back.
;   typ                   string      Type of data requested, INDEX or SPEC.
;                                     Passed in.
;   vers                  string      Version number of the data.  
;                                     Passed back.
;   indexd                structure   Data returned from the indexinfo_60d
;                                     structure. Used internally.
;   index                 structure   Data returned from the indexinfo_60d 
;                                     structure. Used internally.
;   spec                  structure   Data returned from the specinfo_600
;                                     structure. Used internally.
;   knownversions         string      Set to the know version 6.00.     
;                                     Passed back.
;   vix                   integer     Index returned where the known     
;                                     version is equal to the version requested.         
;                                     Used internally.
;=================================================================================
;--- pick out the structure that matches the type and version provided.
  indexinfo_60d,indexd
  specinfo_600,spec600
  knownversions = ['6.00']
  vix = where(knownversions eq vers)
  if vix(0) eq -1 then begin
    print,'Version extension ',vers,' not recognized.'
    retall
  endif
;---------------------------------------------
  if (typ eq 'INDEX') then begin
    if (vers eq '6.0A' or vers eq '6.0B' or vers eq '6.0C') then begin
       struct = index
    endif else begin
      struct = indexd
    endelse
  endif
;---------------------------------------------
  if (typ eq 'SPEC') then begin
    if (vers eq '6.0A' or vers eq '6.0B' or vers eq '6.0C' or $
      vers eq '6.0D' or vers eq '6.0E') then begin
      struct = spec
    endif else begin
      struct = spec600
    endelse
  endif
;---------------------------------------------
END

PRO indexinfo_60d,indexd
;=================================================================================
; Routine Name: INDEXINFO_60D
;
; PURPOSE/FUNCTION:   This function contains the indexinfo_60d structure.    
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   indexd                structure    Data requested from the       
;                                     structure. Passed back.
;=================================================================================
; Define the header structure
; Field				   Type				Description
indexd ={INDEXINFO_60D,$
	Num_Prof:      0L,               $ ;Number of profiles(records) in these files
;Revision Info
	Met_Rev_Date:   0L, 	        $ ;LaRC Met Model Rev Date (yyyymmdd)
	Driver_Rev:        bytarr(8), 	$ ;LaRC Driver version (eg. 6.0a)
	Transmission_Rev:  bytarr(8),   $ ;LaRC Transmission version
	Inversion_Rev:     bytarr(8),   $ ;LaRC Inversion version
	Spectroscopy_Rev:  bytarr(8),   $ ;LaRC Inversion version
	Eph_File_Name:     bytarr(32),  $ ;Ephem file name
	Met_File_Name:     bytarr(32),  $ ;Met file name
	Ref_File_Name:     bytarr(32),  $ ;Refraction file name
	Trans_File_Name:   bytarr(32),  $ ;Transmission file name
	Spec_File_Name:    bytarr(32),  $ ;Species profile file name
	FillVal:           0.,          $ ;Fill value
;Altitude grid and range info
        Grid_Size:         0.,          $ ;Altitude Grid spacing (0.5km)
	Alt_Grid:          fltarr(200), $ ;Geometric Altitudes (0.5, 1.0,..., 100.0km)
	Range_Trans:       fltarr(2),   $ ;Transmission Min & Max altitudes       [0.5,100.]
	Range_O3:          fltarr(2),   $ ;Ozone Density Min & Max altitudes      [0.5,70.0]
	Range_NO2:         fltarr(2),   $ ;NO2 Density Min & Max altitudes        [0.5,50.0]
	Range_H2O:         fltarr(2),   $ ;H2O Density Min & Max altitudes        [0.5,50.0]
	Range_Ext:         fltarr(2),   $ ;Aerosol Extinction Min & Max altitudes [0.5,40.0]
	Range_Density:     fltarr(2),   $ ;Density Min & Max altitudes            [0.5,70.0]
	Reserved:          fltarr(2),   $ 
;Event Specific Info useful for data subsetting
	YYYYMMDD:          lonarr(930), $ ;Event Date (yyyymmdd) at 30km
        event_num:         lonarr(930), $ ;The event number
	HHMMSS:            lonarr(930), $ ;Event Time (hhmmss) at 30km
	Day_Frac:          fltarr(930), $ ;Time of Year (ddd.fraction)
	Lat:               fltarr(930), $ ;Subtangent Latitude at 30km (-90 to 90)
	Lon:               fltarr(930), $ ;Subtangent Longitude at 30km (-180 to 180)
	Beta:              fltarr(930), $ ;Spacecraft Beta angle (degrees)
	Duration:          fltarr(930), $ ;Duration of event (seconds)
	Type_Sat:          intarr(930), $ ;Event Type, Instrument (0=sr, 1=ss)
	Type_Tan:          intarr(930), $ ; Event Type, Local (0=sr,1=ss)
;Process Tracking
;Flag info
        Dropped:           lonarr(930), $ ;Dropped-event flag
        InfVec:            lonarr(930),  $ ;Bit flags relating to processing
;Ephemeris
        Eph_Cre_Date:      lonarr(930), $ ;Record creation date (yyyymmdd)
	Eph_Cre_Time:      lonarr(930), $ ;Record creation time (hhmmss)
;Met
	Met_Cre_Date:      lonarr(930), $ ;Record creation date (yyyymmdd)
	Met_Cre_Time:      lonarr(930), $ ;Record creation time (hhmmss)
;Refraction
	Ref_Cre_Date:      lonarr(930), $ ;Record creation date (yyyymmdd)
	Ref_Cre_Time:      lonarr(930), $ ;Record creation time (hhmmss)
;Transmission
	TRANS_Cre_Date:    lonarr(930), $ ;Record creation date (yyyymmdd)
	TRANS_Cre_Time:    lonarr(930), $ ;Record creation time (hhmmss)
;Inversion
	SPECIES_Cre_Date:  lonarr(930), $ ;Record creation date (yyyymmdd)
	SPECIES_Cre_Time:  lonarr(930)  } ;Record creation time (hhmmss)
end

PRO specinfo_600,spec600
;=================================================================================
; Routine Name: SPECINFO_600
;
; PURPOSE/FUNCTION:   This function contains the indexinfo_60d structure.    
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   spec600               structure   Contains the requested data records.       
;                                     Passed back.
;
;=================================================================================
spec600 = {SPECIES_INFO_600,$
;       Field            Type         Description
        Tan_Alt:         fltarr(8),$;   Subtangent Altitudes (km)
        Tan_Lat:         fltarr(8),$;   Subtangent Latitudes  @ Tan_Alt (deg)
        Tan_Lon:         fltarr(8),$;   Subtangent Longitudes @ Tan_Alt (deg)
        NMC_Pres:        fltarr(140),$; Gridded Pressure profile (mb)
        NMC_Temp:        fltarr(140),$; Gridded Temperature profile (K)
        NMC_Dens:        fltarr(140),$; Gridded Density profile (cm^(-3))
        NMC_Dens_Err:    intarr(140),$; Error in NMC_Dens (%*1000)
        Trop_Height:     0.,$;          NMC Tropopause Height (km)
        Wavelength:      fltarr(7),$;   Wavelength of each channel (nm)
        O3:              fltarr(140),$; O3  Density profile 0-70Km (cm^(-3))
        NO2:             fltarr(100),$; NO2 Density profile 0-50Km (cm^(-3))
        H2O:             fltarr(100),$; H2O Volume Mixing Ratio 0-50Km (ppp)
        Ext386:          fltarr(80),$;  386 nm Extinction   0-40Km (1/km)
        Ext452:          fltarr(80),$;  452 nm Extinction   0-40Km (1/km)
        Ext525:          fltarr(80),$;  525 nm Extinction   0-40Km (1/km)
        Ext1020:         fltarr(80),$;  1019nm Extinction   0-40Km (1/km)
        Density:         fltarr(140),$; Calculated Density  0-70Km (cm^(-3))
        Reserved:        fltarr(80),$;  Reserved for future version
        O3_Err:          intarr(140),$; Error in  O3 density profile (%*100)
        NO2_Err:         intarr(100),$; Error in NO2 density profile (%*100)
        H2O_Err:         intarr(100),$; Error in H2O mixing ratio (%*100)
        Ext386_Err:      intarr(80),$;  Error in  386nm Extinction (%*100)
        Ext452_Err:      intarr(80),$;  Error in  452nm Extinction (%*100)
        Ext525_Err:      intarr(80),$;  Error in  525nm Extinction (%*100)
        Ext1020_Err:     intarr(80),$;  Error in 1019nm Extinction (%*100)
        Density_Err:     intarr(140),$; Error in Density (%*100)
        Reserved1:       intarr(80),$;  Reserved for a future version
        InfVec:          intarr(140) }; Reserved for a future version
END

PRO getquantstr,quant,tags,qnum,struct,filename,typ
;=================================================================================
; Routine Name: GETQUANTSTR
;
; PURPOSE/FUNCTION:   Returns a tag and a name requested.                    
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   quant                 string      Contains a parameter name to request from   
;                                     the structure. Passed back.
;   tags                  arrays      Contains the tag number of a record         
;                                     returned from the structure.  Passed back.
;   ix                    integer     Index where the tag number finds   
;                                     the data. Used internally.
;   qnum                  integer     Index for the quant name. Passed back.
;   struct                structure   Data returned from the structure. 
;                                     Passed in.
;   filename              string      Input filename. Passed in.
;                                     
;=================================================================================
    quant = strupcase(quant)
    tags = tag_names(struct)
    ix = where(tags eq quant)
    if ix(0) eq -1 then begin
        print,quant,': Tag name not recognized for this structure.'
        return
    endif else begin
        qnum = ix(0)
    endelse
END

PRO openandread,filename,struct,out_lun,tags $
               ,kcount,print_var,typeflag,vers,typ
;=================================================================================
; Routine Name: OPENANDREAD
;
; PURPOSE/FUNCTION:   Opens and reads the filename and determines which       
;                     structure to read.                                     
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   ifirst                integer     Flag that is passed to the print routine.    
;                                     Used internally.
;   inlun                 integer     Logical unit number for
;                                     the input file. Used internally.
;   filename              string      Contains the selected input
;                                     file. Passed in.
;   struct                structure   Contains the selected data
;                                     returned from the data structure. Passed in.
;   data                  array       Selected structure records.       
;                                     Used internally.
;   rec                   structure   Contains the data from the structure
;                                     element(s) selected. Used internally.  
;   recnum                integer     This variable counts the number of records
;                                     i.e event numbers read from the input file.
;                                     Used internally.
;   numrecs               integer     This variable holds the number of records
;                                     for the species file being processed. Used internally.
;   nvals                 integer     This variable contains the total number of
;                                     events found on the speciers file.  Used internally.
;   count                 integer     Contains the number of records
;                                     processed and printed. Used internally.
;   typeflag              integer     Flag set to 1 or 2 depending upon whether  
;                                     the INDEX or SPEC file is to be read. Passed in.
;   kcount                integer     Contains the total number of
;                                     selected variables that are valid. Passed in.
;   name                  string      Name returned from the print_var array it  
;                                     is passed to the print routine. Used internally.
;   ix                    integer     Contains the index from the
;                                     structure of the variable name. Used internally.
;   tags                  array       Tag number of a record
;                                     returned from the structure.  Passed in.
;   print_var             array       Array that contains the selected variable      
;                                     names the user has chosen to print. Passed in.
;   typeflag              integer     Flag set to 1 or 2 depending upon whether  
;                                     the INDEX or SPEC file is to be read. Passed in.
;   quant                 string      Selected variable name. Used internally.
;   value                 real        Contains the data value for the
;                                     variable name selected. Used internally.
;   typ                   string      Set to the type of structure being    
;                                     processed INDEX or SPEC. Used internally.
;   out_lun               integer     Contains the logical unit number
;                                     used for the output file. Passed in.
;   unit                  string      Contains the units for the selected
;                                     name from the structure. Used internally.
;=================================================================================
  count = 0
  ifirst = 0
  nvals = 0
  numrecs = 0
  if(typeflag eq 1) then begin
    for k = 0 ,kcount do begin
      openinputfile,inlun,filename
      recnum = 0
      rec_num_read=0
      kk = 0
      count = 0
      while NOT EOF(inlun) DO BEGIN
        rec_num_read = rec_num_read + 1
        data = assoc(inlun,struct)
        rec = data(recnum)
        recnum = recnum + 1
                            ;swap the data if it is not a DEC or Windows machine
        if (!version.os ne 'OSF' and !version.os ne 'Win32') then begin
          rec = swap_endian(rec)
        endif

        index_data,k,name2,value,typ,print_var,tags,ix,rec,typeflag,unit
        if(kk eq 0) then begin
          GET_PRINT_OUT,filename,out_lun,count,name2,value,typ,ifirst,unit,print_var $
                       ,newframe
          kk = 1
        endif
      ENDWHILE
      FREE_LUN, inlun
    endfor
  endif

  if(typeflag eq 2) then begin
    openinputfile,inlun,filename
    get_number_records,inlun,nvals,vers,typ,struct
  endif
  for i = 0 ,nvals-1 do begin
    newframe = 0
    numrecs = numrecs + 1
    for k = 0 ,kcount do begin
      data = assoc(inlun,struct)
      rec = data(i)
                          ;swap the data if it is not a DEC or Windows machine
      if (!version.os ne 'OSF' and !version.os ne 'Win32') then begin
        rec = swap_endian(rec)
      endif
      typ = "SPECIES"
      get_right_data,print_var,k,tags,ix,quant,rec,name2,value
      find_the_units,unit,typeflag,ix
      GET_PRINT_OUT,filename,out_lun,numrecs,name2,value,typ,ifirst,unit,print_var $
                   ,newframe
      newframe = 1
      ifirst = 1
    endfor
  endfor
              ;close the input/output files
  close,inlun
  close,out_lun
END

PRO openinputfile,inlun,filename
;=================================================================================
; Routine Name: OPENINPUTFILE
;
; PURPOSE/FUNCTION:   This routine will open the input file and check
;                     to see if the open was successful. If not an
;                     error message is printed, and the program stopped.
;
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   inlun               integer       This variable contains the logical
;                                     unit number assigned to the input
;                                     file name.  Passed in.
;   filename            string        Name of the data file returned by the
;                                     dialog_pickfile routine.  Passed in.
;   err                 integer       Error number returned from the open command.
;                                     Used internally.
;=================================================================================
;open the input file
  openr,inlun,filename,/get_lun,error=err
  if (err ne 0) then begin
    print,!ERR_STRING
    stop
  endif
END

PRO index_data,k,name2,value,typ,print_var,tags,ix,rec,typeflag,unit
;=================================================================================
; Routine Name: INDEX_DATA
;
; PURPOSE/FUNCTION:   This routine will find the correct data values from
;                     the structure rec stored on the INDEX file.  The 
;                     index of the tag is found by matching the selected 
;                     name with the tag name gotten from the input file.
;                     The data values are then retrieved and the units
;                     selected for this tag and both are returned to the
;                     calling routine so they can be passed to the print
;                     function GET_PRINT_OUT.
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;   k                   integer       This variable is a loop counter for
;                                     indexing the print_var array. Passed in.
;   name                string        Name returned from the print_var array it
;                                     is used to match the tag name. Used internally.
;   name2               string        This variable holds the name of the
;                                     variable as it appears on the input file.
;                                     This variable is used to print the name
;                                     to the output.  Passed back. 
;  value                real          This array contains the data values returned
;                                     from the structure rec.  Passed back.
;  typ                  string        This variable holds the type of data being
;                                     processed, INDEX or SPECIES.  Passed back.
;  print_var            array         Array that holds the selected variable
;                                     names the user has chosen to print.
;                                     Passed in.
;  tags                 array         Tag number of a record returned from the
;                                     structure.  Passed back.
;  ix                   integer       Index where the tag number finds
;                                     the data. Used internally.
;  quant                array         This array holds the returned values selected
;                                     from the structure rec. Used internally.
;  rec                  real          Data from the structure element(s) selected.
;                                     Used internally.
;  typeflag             integer       Flag that determines which type of data to
;                                     print. Passed in.
;  unit                 string        Contains the units for the selected
;                                     name from the structure. Passed back.
;=================================================================================

  name = strupcase(print_var[k])
  name2 = print_var[k]
  ix = where(tags eq name)
  quant = rec.(ix(0))
  value = (quant)
  if(name eq "DRIVER_REV")       then value = string(quant)
  if(name eq "TRANSMISSION_REV") then value = string(quant)
  if(name eq "INVERSION_REV")    then value = string(quant)
  if(name eq "SPECTROSCOPY_REV") then value = string(quant)
  if(name eq "EPH_FILE_NAME")    then value = string(quant)
  if(name eq "MET_FILE_NAME")    then value = string(quant)
  if(name eq "REF_FILE_NAME")    then value = string(quant)
  if(name eq "TRANS_FILE_NAME")  then value = string(quant)
  if(name eq "SPEC_FILE_NAME")   then value = string(quant)
  find_the_units,unit,typeflag,ix
  typ = "INDEX"
END

PRO get_right_data,print_var,k,tags,ix,quant,rec,name2,value
;=================================================================================
; Routine Name: GET_RIGHT_DATA
;
; PURPOSE/FUNCTION:   This function was written to break up the openandread
;                     function which calls it.  It finds the right selected
;                     SPECIES data values and returns them to be printed.
;
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;    name                 string         This variable contains the variable
;                                        selected by the user which is contained
;                                        in the array print_var. The name is
;                                        matched with the tag name found on the
;                                        input file. The data vales found for the
;                                        index of this name are then returned.
;                                        Used internally.
;   print_var             array          Array that holds the selected variable
;                                        names the user has chosen to print.
;                                        Used internally.
;   k                     integer        This variable is a loop counter used to
;                                        index the print_var array. Passed in.
;   tags                  array          Tag number of a record returned from the
;                                        rec structure.  Used internally.
;   quant                 array          This array holds the returned selected
;                                        data values returned from the rec structure.
;                                        Used internally.
;   rec                   structure      Structure returns the type of data requested.
;                                        Used internally.
;   ix                    integer        Index where the tag number finds
;                                        the data. Passed back.
;   qnum                  integer        Index for the tags name. Used internally.
;   name2                 string         This variable holds the name of the
;                                        variable as it appears on the input file.
;                                        This variable is used to print the name
;                                        to the output.  Passed back.
;   value                 array          Data value for the selected name. Passed back.
;
;=================================================================================
    name = strupcase(print_var[k])
    name2 = print_var[k]
    ix = where(tags eq name)
    qnum = ix(0)
    quant = rec.(qnum)
    value = (quant)
END

PRO find_the_units,unit,typeflag,ix
;=================================================================================
; Routine Name: FIND_THE_UNITS
;
; PURPOSE/FUNCTION:   This function generates the units for the variables    
;                     being printed out.                                     
; Variables:
;    Name                 Type            Description
;    ----                 ----            -----------
;    unit                 string         Contains the units name.
;                                        Passed back.
;    typeflag             integer        Flag to identify which data
;                                        INDEX or SPEC to do. Passed in.
;    ix                   integer        Contains the index from the
;                                        structure of the variable name. Passed in.
;
;=================================================================================
  if (typeflag eq 1) then begin
      if(ix(0) eq 0) then unit = "records"
      if(ix(0) eq 1) then unit = "yyyymmdd"
      if(ix(0) eq 2) then unit = "version"
      if(ix(0) eq 3) then unit = "version"
      if(ix(0) eq 4) then unit = "version"
      if(ix(0) eq 5) then unit = "version"
      if(ix(0) eq 6) then unit = "filename"
      if(ix(0) eq 7) then unit = "filename"
      if(ix(0) eq 8) then unit = "filename"
      if(ix(0) eq 9) then unit = "filename"
      if(ix(0) eq 10) then unit = "filename"
      if(ix(0) eq 11) then unit = "N/A"
      if(ix(0) eq 12) then unit = "km"
      if(ix(0) eq 13) then unit = "km"
      if(ix(0) eq 14) then unit = "km"
      if(ix(0) eq 15) then unit = "km"
      if(ix(0) eq 16) then unit = "km"
      if(ix(0) eq 17) then unit = "km"
      if(ix(0) eq 18) then unit = "km"
      if(ix(0) eq 19) then unit = "km"
      if(ix(0) eq 20) then unit = "reserved"
      if(ix(0) eq 21) then unit = "Event Date at 30km"
      if(ix(0) eq 22) then unit = "N/A"
      if(ix(0) eq 23) then unit = "Event Time at 30km"
      if(ix(0) eq 24) then unit = "Day fraction"
      if(ix(0) eq 25) then unit = "Degrees"
      if(ix(0) eq 26) then unit = "Degrees"
      if(ix(0) eq 27) then unit = "Degrees"
      if(ix(0) eq 28) then unit = "Seconds"
      if(ix(0) eq 29) then unit = "N/A"
      if(ix(0) eq 30) then unit = "N/A"
      if(ix(0) eq 31) then unit = "flag"
      if(ix(0) eq 32) then unit = "flag"
      if(ix(0) eq 33) then unit = "yyyymmdd"
      if(ix(0) eq 34) then unit = "hhmmss"
      if(ix(0) eq 35) then unit = "yyyymmdd"
      if(ix(0) eq 36) then unit = "hhmmss"
      if(ix(0) eq 37) then unit = "yyyymmdd"
      if(ix(0) eq 38) then unit = "hhmmss"
      if(ix(0) eq 39) then unit = "yyyymmdd"
      if(ix(0) eq 40) then unit = "hhmmss"
      if(ix(0) eq 41) then unit = "yyyymmdd"
      if(ix(0) eq 42) then unit = "hhmmss"
  endif
  if (typeflag eq 2) then begin
      if(ix(0) eq 0) then unit = "km"
      if(ix(0) eq 1) then unit = "degrees"
      if(ix(0) eq 2) then unit = "degrees"
      if(ix(0) eq 3) then unit = "mb"
      if(ix(0) eq 4) then unit = "K"
      if(ix(0) eq 5) then unit = "molecules/cm^3"
      if(ix(0) eq 6) then unit = "percent x 100"
      if(ix(0) eq 7) then unit = "km"
      if(ix(0) eq 8) then unit = "nm"
      if(ix(0) eq 9) then unit = "cm-3"
      if(ix(0) eq 10) then unit = "cm-3"
      if(ix(0) eq 11) then unit = "cm-3"
      if(ix(0) eq 12) then unit = '1/km'
      if(ix(0) eq 13) then unit = '1/km'
      if(ix(0) eq 14) then unit = '1/km'
      if(ix(0) eq 15) then unit = '1/km'
      if(ix(0) eq 16) then unit = "reserved"
      if(ix(0) eq 17) then unit = "reserved"
      if(ix(0) eq 17) then unit = "percent x 100"
      if(ix(0) eq 19) then unit = "percent x 100"
      if(ix(0) eq 20) then unit = "percent x 100"
      if(ix(0) eq 21) then unit = "percent x 100"
      if(ix(0) eq 22) then unit = "percent x 100"
      if(ix(0) eq 23) then unit = "percent x 100"
      if(ix(0) eq 24) then unit = "percent x 100"
      if(ix(0) eq 25) then unit = "reserved"
      if(ix(0) eq 26) then unit = "reserved"
      if(ix(0) eq 27) then unit = "flag"
  endif
END