PRO xrt_batch_composite, l_idx, l_da, s_idx, s_da, index_out, data_out, $
                      despike=despike, lsat_map=lsat_map, verbose=verbose, $
                      qabort=qabort
                      
; =========================================================================
;+
; PROJECT:
;       Solar-B / XRT
;
; NAME:
;
;       XRT_BATCH_COMPOSITE
;
; CATEGORY:
;
;       Data graphics.
;
; PURPOSE:
;
;       Employs mk_xrt_composite.pro to process a batch of composite images
;       without having to write any loops.
;       See Note #1.
;
; CALLING SEQUENCE:
;
;       XRT_BATCH_COMPOSITE, l_idx, l_da, s_idx, s_da, index_out, data_out
;                         [,despike=despike] [,lsat_map=lsat_map] [,/verbose]
;
; INPUTS:
;
;       L_IDX    - [Mandatory] (structure array)
;                  This is the "index" for the long exposure images.
;                  Can be Level-0 or Level-1, as long as it matches L_DA.
;       L_DA     - [Mandatory] (number array, [Nx,Ny,Nimg])
;                  This is the data array for the long exposure images.
;                  Can be Level-0 or Level-1, as long as it matches L_IDX.
;       S_IDX    - [Mandatory] (structure array)
;                  This is the "index" for the short exposure images.
;                  Can be Level-0 or Level-1, as long as it matches S_DA.
;       S_DA     - [Mandatory] (number array, [Nx,Ny,Nimg])
;                  This is the data array for the short exposure images.
;                  Can be Level-0 or Level-1, as long as it matches S_IDX.
;
; KEYWORDS:
;
;       DESPIKE  - [Optional] (Boolean or integer) Set if 1 pass of 
;                  despike wanted to remove radiation-belt/cosmic-ray 
;                  spikes, or set to 1-3 passes of despike. (Two passes 
;                  works well even for heavy spiking.) Default = no 
;                  despiking if the keyword is not set. 
;                  (See <xrt_prep.pro> for more information.)
;       LSAT_MAP - [Optional] (Byte array) Set to a boolian map array of the 
;                  location of saturated pixels to be replaced. Use this 
;                  if the data have already been xrt_prepped and the map
;                  was generated or if xrt_prep is not to be used. Array 
;                  must be same size as images to be composited. 1 represents
;                  the pixel to be replaced.
;       /VERBOSE - [Optional] (Boolean) If set, print out extra messages.
;
; OUTPUTS:
;
;       INDEX_OUT    - [Mandatory] (structure array)
;                      This is the "index" for the composite images. It will
;                      have the same content as L_IDX (after it has been 
;                      through <xrt_prep.pro> and normalized), except that
;                      there will be an update to the HISTORY field.
;       DATA_OUT     - [Mandatory] (float array, [Nx,Ny,Nimg])
;                      This is the data array for the composite images.
;       QABORT       - [Optional] (Boolean) Indicates that the program exited
;                      gracefully without completing. (Might be useful for 
;                      calling programs.)
;                      0: Program ran to completion.
;                      1: Program aborted before completion. 
;
; EXAMPLES:
;
;       Basic usage:
;       IDL> xrt_batch_composite, l_idx, l_da, s_idx, s_da, index_out, data_out
;       IDL> tvscl, xrtdisp(data_out[*,*,0], /log)
;
;       Recommended to do despiking on Level-0 data:
;       IDL> xrt_batch_composite, l_idx, l_da, s_idx, s_da, index_out, $
;       IDL>                      data_out, despike=2
;       IDL> tvscl, xrtdisp(data_out[*,*,0], /log)
;
; COMMON BLOCKS:
;
;       none
;
; NOTES:
;
;      1) A very simple proceedure for combining a batch of long and short 
;         exposure XRT images. This procedure simply runs a loop of 
;         mk_xrt_composite.pro calls to generate an index structure array
;         and data array consistent with xrt_prep.pro and the like.
;         Through mk_xrt_composite.pro, it checks to see if the images have 
;         been xrt_prepped, and preps them if they have not been.
;         The index structure for the long image will be used for the
;         combined index structure with the history updated with the short
;         image information.
;
; 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 = 'v2011-Aug-23' ;--- (P.McCauley) Written.
progver = 'v2011-Oct-20' ;--- (S.Saar) Minor edits.  
;
;-
; =========================================================================

; Sets keywords
dspike = keyword_set(despike) 
sat_map = keyword_set(lsat_map)
verb = keyword_set(verbose)

qabort = 0B

; So inputs are not overwritten
l_idxp = l_idx
l_dap  = l_da
s_idxp = s_idx
s_dap  = s_da

; Ensures that inputs have proper dimensions and that their elements match
if (n_dimensions(l_dap) ne 3) or (n_dimensions(s_dap) ne 3) then begin
  box_message, ['Input data arrays must have 3 dimensions: [Nx,Ny,Nimg].' + $
   ' Aborting.']
  qabort = 1B
  return
endif

if (n_dimensions(l_idxp) ne 1) or (n_dimensions(s_idxp) ne 1) then begin
  box_message, ['Input structure array must have 1 dimension. Aborting.']
  qabort = 1B
  return
endif

if (n_elements(l_dap) ne n_elements(s_dap)) then begin
  box_message, ['Input data arrays must have an equal number of elements.' + $
   ' Aborting.']
  qabort = 1B
  return
endif

if (n_elements(l_idxp) ne n_elements(s_idxp)) then begin
  box_message, ['Input index structure arrays must have an equal number' + $
   ' of elements. Aborting.']
  qabort = 1B
  return
endif
  
; Determines how many images there are to process
loop_length = n_elements(l_idxp) - 1

; Image proceessing...
;
; If data has been xrt_prepped (i.e. lsat_map is set):
;
if (sat_map eq 1) then begin
  mappy=lsat_map
  if (n_elements(mappy) ne n_elements(l_dap)) then begin  
                                              ; check saturation map dimensions 
    box_message, ['Saturated pixel map array must have a number of' + $
     ' elements equal to input data arrays. Aborting.']
    qabort = 1B
    return
  endif
endif
for i=0, loop_length do begin   ; Loops for each composite image creation
   if (sat_map eq 1) then begin    ; if sat map exists (data prepped)
      mk_xrt_composite, l_idxp[i], l_dap[*,*,i], s_idxp[i], $
                    s_dap[*,*,i], c_idx, c_da, despike=despike, $
                    lsat_map=mappy[*,*,i], verbose=verbose
   endif else begin    ; if no sat map exists (data not prepped)
      mk_xrt_composite, l_idxp[i], l_dap[*,*,i], s_idxp[i], $
                    s_dap[*,*,i], c_idx, c_da, despike=despike, $
                    verbose=verbose
   endelse
   if (i eq 0) then begin
      index_bin=c_idx                              ; initializes structure array
   endif else begin
      index_bin = concat_struct(temporary(index_bin), c_idx) 
                                                      ; builds structure array
   endelse
   boost_array, data_bin, c_da                       ; builds data array
endfor

; Generates outputs
index_out = index_bin
data_out = data_bin
return

end
;
;
;
