FUNCTION make_xrt_filt_contam, input1, channels, intype=intype, $
                               verbose=verbose, quiet=quiet,  $
                               qabort=qabort, qstop=qstop

; =========================================================================
;+
; PROJECT:
;       Solar-B / XRT 
;
; NAME:
;       
;       MAKE_XRT_FILT_CONTAM
;
; CATEGORY:
;       
;       Instrument response
;
; PURPOSE:
;
;       Produce the filter contamination transmission functions for a set of
;       XRT x-ray channels. Takes thicknesses as input, or index arrays or
;       image times that are converted to thicknesses. This program is a 
;       subroutine of <make_xrt_ea.pro>--- interface convenience was not a 
;       design goal.
;
; CALLING SEQUENCE:
;
;       Result = MAKE_XRT_FILT_CONTAM( input1, channels [,intype=intype] 
;                            [,/verbose] [,/quiet] [,qabort=qabort] [,/qstop] )
;
; INPUTS:
;
;       INPUT1      - [Mandatory] index structure array, (default);
;                              OR pair of thicknesses [CCD,filter1+2];
;                                               (two element float array);
;                              OR time of observation  (string)
;                     To calculate the contamination transmission, a pair of
;                     layer thicknesses must be provided (in Angstroms).
;                     The default mode is to assume that INPUT1 is an
;                     index structure, from which the filter and time
;                     information to calculate thickensses can be extracted.
;                     Alternately, a pair of layer thicknesses [CCD,filter1+2]
;                     or a time may be provided.  Times must be
;                     provided in a string format that SSWIDL will recognize.
;                     If thicknesses or times are provided, INTYPE must
;                     be set to 1 or 2 respectively (see INTYPE below).
;       CHANNELS    - [Mandatory] (structure array,
;                                  {XRT_chn_config_vNNNN} [Nthicknesses])
;                     This is an array of structures of type
;                     "XRT_chn_config" and with a structure name
;                     of the form {XRT_chn_config_vNNNN}. For a
;                     more complete description of this complicated
;                     structure, see the XRT Analysis Guide. The
;                     base set of channels is provided in the XRT SSWIDL
;                     tree by a file with a pathname like this:
;       $SSW_XRT/idl/response/channels/xrt_channels_vNNNN.geny
;                     That file is automatically found, read, and passed
;                     to <make_xrt_ea.pro> if <make_xrt_wave_resp.pro>
;                     is used as the interface, as intended.
;
; KEYWORDS:
;
;        INTYPE - [Optional] (integer scalar) This keyword is set to:
;                  = 0: INPUT1 is an index structure (Default)
;                  = 1: INPUT1 is a 2 element vector of paired thicknesses
;                       [CCD, filter1+2] (in Angstroms).
;                  = 2: INPUT1 is a time of an XRT image
;                       (<anytim2utc.pro> format).
;                  [Mandatory] if input is thicknesses or image times.
;       /VERBOSE - [Optional] (Boolean) If set, print out extra
;                  information. Overrides "/quiet" (see Note #1).
;       /QUIET   - [Optional] (Boolean) If set, suppress messages
;                  (see Note #1).
;       /QSTOP   - [Optional] (Boolean) For debugging.
;
;
; OUTPUTS:
;
;       Return   - [Mandatory] (structure array,
;       (FCONTAM)                {XRT_filt_contam_vNNNN} [Nthicknesses])
;                  This structure contains data and information
;                  about the filter contamination layer for a given
;                  thickness. The thickness varies with time between
;                  filter bakeouts and acts like an extra absorption layer,
;                  so the transmission factor must be included when
;                  calculating the effective area for each XRT
;                  channel for any given image or point in time.
;
;                  Here is a listing of the fields of the "XRT_filt_contam"
;                  structure. Descriptions are provided further
;                  down.:
;
;                  FCONTAM {XRT_filt_contam_vNNNN}
;                  - TYPE            (string scalar)
;                  - FCTM_STR_VERSION (string scalar)
;                  - FCTM_STR_DESCR   (string scalar)
;                  - FILTER1          (string scalar)
;                  - FILTER2          (string scalar)
;                  - NAME            (string scalar)
;                  - LONG_NAME       (string scalar)
;                  - MATERIAL        (string scalar)
;                  - DENS            (float scalar)
;                  - DENS_UNITS      (string scalar)
;                  - THICK           (float scalar)
;                  - THICK_UNITS     (string scalar)
;                  - THICK_TIME      (string scalar)
;                  - WAVE            (float array, [Nwave])
;                  - WAVE_UNITS      (string scalar)
;                  - TRANS           (float array, [Nwave])
;                  - LENGTH          (long scalar)
;                  - DATA_FILES      (string array, [5])
;                  - HISTORY         (string array, [3])
;                  - COMMENTS        (string array, [5])
;
;                  Here are descriptions of the fields in the
;                  "XRT_contam" structure.:
;
;                  TYPE: (string scalar)
;                      [Default value = 'XRT_filt_contam'.]
;                      This is the generic name of the structure
;                      that contains the contamination functions
;                      and information. The version of the structure
;                      definition might evolve, but the TYPE should
;                      remain constant. See FCTM_STR_VERSION. The
;                      value is initialized at creation. This field
;                      should NOT be changed.
;                 FCTM_STR_VERSION: (string scalar)
;                      [The default value = 'XRT_filt_contam_vNNNN',
;                      where NNNN is a 4-digit number.]
;                      This is the version number of the "XRT_filt_contam"
;                      structure definition. In addition to being
;                      recorded in this field, this is also the
;                      "unique structure name" in the IDL sense.
;                      The value is initialized at creation. This
;                      field should NOT be changed.
;                 FCTM_STR_DESCR: (string scalar)
;                      This is a sentence or two that describes the
;                      purpose of this structure type. This field
;                      should NOT be changed.
;                 FILTER1: (string scalar)
;                      This is the name of the FW1 filter used
;                      in the calculation.  
;                 FILTER2: (string scalar)
;                      This is the name of the FW2 filter used
;                      in the calculation.  
;                  NAME: (string scalar)
;                      This is a name for this contamination layer
;                      thickness. This string should concisely
;                      identify the contamination layer (although
;                      it may not be unique). Some programs may
;                      refer to this string, so its usage should
;                      be regularized. (Compare to LONG_NAME.) This
;                      field MAY be changed, but the default is
;                      recommended.
;                  LONG_NAME: (string scalar)
;                      This is a longer string for the name for
;                      this contamination layer thickness. This
;                      field should not be referred to by software;
;                      it is intended to provide a more informative
;                      description for humans.  This field MAY be
;                      changed, but the default is recommended.
;                  MATERIAL: (string scalar)
;                      Name of substance or chemical compound forming
;                      the contamination layer. (NAME may or may
;                      not specify the substance's identity. MATERIAL
;                      should always specify the substance's
;                      identity.) 
;                  DENS: (float scalar)
;                      Density of the contamination material named
;                      in the MATERIAL tag, and that was used to
;                      calculate the transmission function. The
;                      value must be consistent with the units named
;                      in DENS_UNITS. 
;                  DENS_UNITS: (string scalar)
;                      Units of the value in the DENS tag. The units
;                      must be 'g cm^-3' (so that other programs
;                      can reliably interpret DENS). 
;                  THICK: (float scalar)
;                      Thickness of the contamination material named
;                      in the MATERIAL tag, and that was used to
;                      calculate the transmission function. The
;                      value must be consistent with the units named
;                      in THICK_UNITS. 
;                  THICK_UNITS: (string scalar)
;                      Units of the value in the THICK tag. The
;                      units must be 'Angstroms' (so that other
;                      programs can reliably interpret THICK). 
;                  THICK_TIME: (string scalar)
;                      This is the mission time for which the
;                      contamination thickness (tag THICK) was
;                      calculated, as specified by INPUT1 and keyword
;                      INTYPE=0. It is possible that the thickness
;                      was asserted independent of a mission time
;                      (using INPUT1 and INTYPE=1), in which case
;                      the THICK_TIME tag may have an empty string
;                      value (''). The value should be in a string
;                      time format recognized by SSWIDL.
;                  WAVE: (float array, [Nwave])
;                      The wavelength abscissa of the transmission
;                      function (see TRANS) for the specified
;                      thickness of the contamination layer. The
;                      values must make a montonically increasing
;                      sequence of floating point numbers, starting
;                      from the first address of the array. If the
;                      sequence is shorter than the length of this
;                      array, then all addresses after the sequence
;                      ends should have a value of zero. The sequence
;                      length is recorded in the LENGTH tag. The
;                      values must be consistent with the units
;                      named in WAVE_UNITS.
;                  WAVE_UNITS: (string scalar)
;                      Units of the value in the WAVE tag. The units
;                      must be 'Angstroms' (so that other programs
;                      can reliably interpret WAVE).
;                  TRANS: (float array, [Nwave])
;                      The dimensionless transmission as a function
;                      of wavelength for the specified thickness
;                      of the contamination layer. The values must
;                      make a sequence of floating point numbers,
;                      starting from the first address of the array,
;                      and should correspond in position to values
;                      of WAVE. If the sequence is shorter than the
;                      length of this array, then all addresses
;                      after the sequence ends should have a value
;                      of zero. The sequence length is recorded in
;                      the LENGTH tag.
;                  LENGTH: (long scalar) 
;                      The length of the paired sequences of WAVE
;                      and TRANS, indicating how much of those
;                      arrays contains useful information. E.g.:
;                      IDL> len = contam[0].length
;                      IDL> plot, contam[0].wave[0:len-1], $
;                      IDL>       contam[0].trans[0:len-1]
;                  DATA_FILES: (string array, [5])
;                      This is a list of filenames of reference
;                      data that were used in the specification of
;                      the contamination. It is primarily intended
;                      for listing any files that might be important
;                      for reference purposes.  This field should
;                      NOT be changed, but empty strings may be
;                      added to.
;                  HISTORY: (string array, [3])
;                      This text array is for XRT programs to record
;                      any instance in which they have modified the
;                      content of the "XRT_filt_contam" type of structure
;                      for this particular contamination description.
;                      On creation, a line is added for the creation
;                      of the "XRT_filt_contam" structure in
;                      <make_xrt_filt_contam.pro>.  An entry string is
;                      composed of (a) a program name, (b) the
;                      program's version/date, (c) colon separator,
;                      (d) Timestamp (in parentheses) of when the
;                      program completed the described action, and
;                      (e) a summation of what the program created
;                      or modified in the "XRT_filt_contam" structure.
;                      Values are inserted starting at the lowest
;                      address of this array. Remaining unused
;                      addresses are filled with the empty string.
;                      Filled strings should NOT be overwritten.
;                      Users should use the COMMENTS field to add
;                      their own notations to this structure.
;                  COMMENTS: (string array, [5])
;                      A tag for adding notations regarding this
;                      specific contamination layer and thickness.
;                      Users and programs are encouraged to put
;                      content in the lower addresses, and assign
;                      empty strings {''} to the higher, unused
;                      addresses.
;
;       QABORT      - [Optional] (Boolean) Indicates whether the program
;                     exited gracefully without completing. (Might be
;                     useful for calling programs.)
;                     0: Program ran to completion.
;                     1: Program aborted before completion.
;
; EXAMPLES:
;
;       This program is a subroutine of <make_xrt_ea.pro>.
;
; COMMON BLOCKS:
;
;       none
;
; NOTES:
;
;       1) There are three levels of verbosity.
;          a) "verbose" = highest priority. All errors and messages are
;                         displayed. ("if q_vb")
;          b) "quiet" = lower priority. No errors or messages are
;                       displayed. ("if q_qt")
;          c) neither = lowest priority. All errors and some messages are
;                       displayed. ("if not q_qt")
;
;
; CONTACT:
;
;       Comments, feedback, and bug reports regarding this routine may be
;       directed to this email address:
;                xrt_manager ~at~ head.cfa.harvard.edu
;
; MODIFICATION HISTORY:
;
progver = 'v2009-Nov-20' ;--- (S.Saar) Written, based largely on
;                             <make_xrt_contam.pro> 
;
;-
; =========================================================================


; === Initial setup ==============================

  ;=== Set Booleans which control print statements.
  ;=== Keyword "verbose" overrules "quiet".
  q_vb = keyword_set(verbose)
  q_qt = keyword_set(quiet) and (q_vb eq 0)


  ;=== Initialize program constants.
  prognam = 'MAKE_XRT_FILT_CONTAM'
  prognul = '               '


  ;=== Announce version of program.
  if q_vb then box_message, prognam+': Running ' + progver + '.'
  if q_vb then print, prognam+': Performing initial setup...'


  ;=== Set some keyword Booleans.
  qtype = keyword_set(intype)
  qstop    = keyword_set(qstop)
  qabort   = 0B
 
  if qtype eq 0 then intype=0    ; default is index

  ;=== Some basic program values.
  if intype eq 1 then c=2 else c=1
  nthicks = n_elements(input1)/c
  nch = n_elements(channels)
  ps=path_sep()
  contam_dir = get_logenv('$SSW_XRT') + ps + 'idl' + ps + 'response' $
               + ps + 'contam' + ps



  ;; In this next bit, we define some structure templates
  ;; that will be used further on.

  ;=== Define the {XRT_filt_contam} stucture.
  fctm_str_version = 'XRT_FILT_CONTAM_V0001'
  fctm_str = create_struct(name=fctm_str_version,                     $
                        'type', 'XRT_FILT_CONTAM',                       $
             'fctm_str_version', fctm_str_version,                    $
               'fctm_str_descr', 'Provides description of a filter '  $
                                + 'contamination layer for an XRT ' $
                                + 'channel.',                       $
                     'filter1', '',                                 $
                     'filter2', '',                                 $
                        'name', 'DEHP',                             $
                   'long_name', 'Bis(2-ethylhexyl)phthalate filter'  $
                                + ' contamination layer',           $
                    'material', 'DEHP',                             $
                        'dens', 0.0,                                $
                  'dens_units', 'g cm^-3',                          $
                       'thick', 0.0,                                $
                 'thick_units', 'Angstroms',                        $
                  'thick_time', '',                                 $
                        'wave', fltarr(5000),                       $
                  'wave_units', 'Angstroms',                        $
                       'trans', fltarr(5000),                       $
                      'length', 0L,                                 $
                  'data_files', strarr(5),                          $
                     'history', strarr(3),                          $
                    'comments', strarr(5)                            )


  if q_vb then print, prognam+': Performing initial setup... OK'


; === Check inputs ===============================

  if q_vb then print, prognam+': Checking inputs...'

  ;=== Check that some input has been given.
  if (n_params() ne 2) then begin
    if (not q_qt) then box_message,                                $
        [prognam+': There should be exactly two input parameters:', $
         prognul+'  INPUT1 and CHANNELS. See program header. Aborting...' ]
    qabort = 1B
    return, 0
  endif

;stop
  ;=== Check type of INPUT1.
  ;; If INPUT1 is an array of thicknesses...
  case 1 of 
     (intype eq 0): begin    ; abort if input1 not a structure
        if datatype(input1[0]) ne 'STC' then begin
           if (not q_qt) then box_message,                   $
              [prognam+': INPUT1 must be a structure if INTYPE=0 ', $
               prognul+'or undefined.  See program header. Aborting...'     ]
           qabort = 1B
           return, 0
        endif 
     end
     (intype eq 1): begin    ;; If INPUT1 is not a number array, then abort.
        if (is_number(input1[0]) eq 0B) then begin
           if (not q_qt) then box_message,                                 $
              [prognam+': INPUT1 is not a number array, ',                $
               prognul+'  inconsistent with input keyword INTYPE=1.', $
               prognul+'  See program header. Aborting...'                 ]
           qabort = 1B
           return, 0
        endif
     end
     else: begin   ;; Else if INPUT1 is (assumed) an array of times...
        ;; If INPUT1 is not a string array, then abort.
        if (datatype(input1[0]) ne 'STR') then begin
          if (not q_qt) then box_message,                                 $
              [prognam+': INPUT1 is not a string array, ',                $
               prognul+'  inconsistent with input keyword INTYPE=2.', $
               prognul+'  See program header. Aborting...'                 ]
          qabort = 1B
          return, 0
        endif

    ;; Standardize times to CCSDS format.
    ;; If entry format is unrecognizable to SSWIDL, 
    ;; then the output will be in internal structure format 
    ;; instead of being in string format.
        times = anytim2utc(input1, /ccsds)
        if (datatype(times) ne 'STR') then begin
          if (not q_qt) then box_message,                             $
              [prognam+': INPUT1 does not contain times in a format', $
               prognul+'  recognizable by <anytim2utc.pro>.',         $
               prognul+'  See program header. Aborting...'             ]
          qabort = 1B
          return, 0
        endif
     end
  endcase


  if q_vb then print, prognam+': Checking inputs... OK'


; === Get thicknesses, if necessary. =============

  if q_vb then print, prognam+': Checking contamination thicknesses...'

  case 1 of 
     (intype eq 0):  begin  ; input is index
        thicks=fltarr(nthicks)
        fthicks=thicks 
        for j=0,nthicks-1 do begin 
           thicks(j)=xrt_time2contam(index=input1(j),filter=fthickj)
           fthicks(j)=fthickj
        endfor
        filt1=input1.ec_fw1_
        filt2=input1.ec_fw2_
        times=input1.date_obs
        cthicks=thicks-fthicks
     end
     (intype eq 1):  begin  ;  input is thicks 
         ;; If thicknesses input, then set empty times...
        thicks = total(input1,1)    ; sum individual thicknesses
        fthicks=reform(input1(1,*))
        cthicks=reform(input1(0,*))
        filt1=channels.fp_filter1.name 
        filt2=channels.fp_filter2.name
        times=strarr(nthicks)   ; *** new add
     end
     else: begin     ; input was times
        thicks=fltarr(nch)
        fthicks=thicks 
        for j=0,nch-1 do begin
           xrt_chan2fw, channels[j], fw1, fw2
           thicks(j)=xrt_time2contam(fw1,fw2,input1(0),filter=fthickj)
           fthicks(j)=fthickj
        endfor
        cthicks=thicks - fthicks
        filt1=channels.fp_filter1.name
        filt2=channels.fp_filter2.name 
     end       
  endcase

  ;; Else if times input, then solve thicknesses...
;    thicks = xrt_time2contam(0,0,times,)
;  endelse

  if q_vb then print, prognam+': Checking contamination thicknesses... OK'


; === Initialize the output structure array. =================

  if q_vb then print, prognam+': Initializing output array...'

  ;=== Prepare the {XRT_filt_contam_ref} structure array.
  fcontam = replicate(fctm_str, nthicks)

  fcontam.long_name  = fcontam.long_name + '; thickness = ' $
                      + strcompress(fthicks,/rem) + ' ' +  $
                      fcontam.thick_units
  fcontam.filter1    = filt1
  fcontam.filter2    = filt2
  fcontam.thick      = fthicks
  fcontam.thick_time = times

  if q_vb then print, prognam+': Initializing output array... OK'


; === Calculate contamination transmissions. =================

  if q_vb then print, prognam+': Calculating the transmissions...'

  ;; Just solve each thickness once.  (all are typically different...)
  thick_list = fthicks[uniq(fthicks, sort(fthicks))]
;  thick_list=fthicks
  n_list = n_elements(thick_list)

  ;; Set some variable names for <multifilt.pro>.
  densities = 1
  n_files   = 1  

  for i_list = 0,(n_list-1) do begin

    if q_vb then print, prognam+': Working on ' +                $
                        strcompress(i_list+1,/rem) + ' of ' +    $
                        strcompress(n_list,/rem) + ' thicknesses.'

    ss1 = where(fthicks eq thick_list[i_list], count1)

    multifilt, wave, trans, 'DEHP', fthicks[ss1[0]], 1.0, $
               densities=densities, n_files=n_files, caldir=contam_dir
    len = n_elements(wave)
    numfiles = n_elements(n_files)

    ;; Load results of <multifilt.pro> into FCONTAM.
    ;; Use matrix tricks to avoid loops.
    fcontam[ss1].dens   = densities[0]
    fcontam[ss1].length = len
    fcontam[ss1].wave[0:len-1]  = wave    # (intarr(count1)+1)
    fcontam[ss1].trans[0:len-1] = trans   # (intarr(count1)+1)
    for ii = 0,(numfiles-1) do fcontam[ss1].data_files[ii] = n_files[ii]

  endfor  ;;  (i_list, loop over thick_list)

  if q_vb then print, prognam+': Calculating the transmissions... OK'



; === Finish =====================================

  get_utc, utc, /stime
  hist_string = prognam+' '+progver+': ('+utc+' UTC) Generated {'        $
                + fcontam.type+'} structure with name "' + fcontam.name+'".'
  fcontam.history[0] = hist_string

  if q_vb then box_message, prognam+': ... Finished.'

  if qstop then stop

  return, fcontam


END ;======================================================================
