
PRO aia_prep, input1, input2, oindex, odata, do_test=do_test, $
  n_img_max=n_img_max, $
  cutout=cutout, use_ref=use_ref, index_ref=index_ref, ds=ds, $
  no_pnt_update=no_pnt_update, $
  no_uncomp_delete=no_uncomp_delete, $
  nearest=nearest, interp=interp, cubic=cubic, normalize=normalize, $
  do_write_fits=do_write_fits, outdir=outdir, outfile=outfile, $
  verbose=verbose, run_time=run_time, $
  progver_main=progver_main, prognam_main=prognam_main, $
  qstop=qstop, _extra=_extra

;+
; NAME:
;   AIA_PREP
; PURPOSE:
;   Perform image registration (rotation, translation, scaling) of Level 1 AIA images, and update
;   the header information.
; CATEGORY:
;   Image alignment
; SAMPLE CALLS:
;   Inputing iindex and idata: 
;     IDL> AIA_PREP, iindex, idata, oindex, odata
;   Inputing infil (iindex and idata are optionally returned as internal variables)
;     IDL> AIA_PREP, infil, [0,1,2], oindex, odata
;   Same, but align to coordinates specified by INDEX_REF
;     IDL> AIA_PREP, infil, [0,1,2], oindex, odata, index_ref=index_ref
;   This time, align to first image:
;     IDL> AIA_PREP, infil, [0,1,2], oindex, odata, /cutout
;   Write out registered date, updated header to FITS file:
;     IDL> AIA_PREP, iindex, idata, /do_write_fits, outdir=outdir
; INPUTS:
;   There are 2 basic usages for inputing the image and header data into AIA_PREP:
;   Case 1: References FITS file name on disk:
;           input1 - String array list of AIA FITS files
;           input2 - List of indices of FITS files to read 
;   Case 2. References index structure and data array in memory
;           (index, data already read from FITS file using, for example, READ_SDO.PRO):
;           input1 - index structure
;           input2 - data array
; OUTPUTS (OPTIONAL):
;   oindex - The updated index structure of the input image
;   odata  - Registered output image.
; KEYWORDS:
;   NO_MPO_UPDATE - If set, force use of header values for roll and scale.  By default, the latest
;                   MPO record is accessed for these.
;   DS - If passed, use this JSOC MPO data series (default is 'aia.master_pointing3h')
;   USE_REF - If set then align all images to a reference index (if INDEX_REF is not supplied then
;             use the first index of the array as the reference index).
;             NOTE - If USE_REF is not set and if INDEX_REF is not supplied, then all images will
;             be aligned to sun center.
;   CUTOUT - Same effect as USE_REF above.
;   INDEX_REF - Reference index for alignment coordinates.
;   DO_WRITE_FITS - If set, write the registered image and updated header structure to disk
;   NEAREST - If set, use nearest neighbor interpolatipon
;   INTERP - If set, use bilinear interpolation
;   CUBIC - If set, use cubic convolution interpolation ith the specified value (in the range [-1,0]
;           as the interpolation parameter.  Cubic interpolation with this parameter equal -0.5
;           is the default.
;   NORMALIZE - If set, and image is AIA, then do exposure normalization.
; HISTORY:
;   2010 (circa), Created ab initio - GLS (slater@lmsal.com)
;   2010-12-07 - GLS - Corrected call to break_file - GLS
;   2011-02-10 - GLS - 1. Corrected sign error on roll (Thanks to Ralph Seguin)
;                      2. Corrections to tags CRPIX(1,2), CDELT(1,2, and CROT2A were not being 
;                         propagated to output header structure (OINDEX).  This was fixed
;                         (Thanks to Benjamin Mampaey)
;   2011-02-28 - GLS - 1. Added missing half pixel to output CRPIX1/2
;                      2. Defined LVL_NUM keyword to be 1.5 (should it be 1.51 to differentiate from
;                         real time?)
;                      3. Added _EXTRA in call for keyword inheritance
;                      4. Made UNCOMP_DELETE the default in call to READ_SDO.
;   2011-03-02 - GLS - 1. Corrected references to NAXIS1/2 in case of compressed file headers
;                      2. Changed default interpolation for ROT function from nearest neighbor to
;                         damped cubic.
;   2011-04-07 - GLS - Corrected 1 pixel error (both axes) in pivot point for ROT function due to
;                      discrepancy between FITS standard pixel numbering for CRPIX1,2 (starting from 1)
;                      and IDL array index referencing (starting from 0).  Thanks to Alberto Vasquez.
;   2011-04-08 - GLS - Added '/pivot' to ROT call for 'cutout' images.  Thanks to Marc DeRosa.
;   2011-04-20 - GLS - Checked for existence of tags 'RSUN_OBS', 'RSUN', and 'LVL_NUM' before attempting
;                      to update them, in order for code to work on HMI images.
;   2011-05-10 - GLS - Removed incorrect logic to correct for binning.
;   2011-05-18 - GLS - Corrected multiple errors in naming convention for output FITS files in HMI case
;   2011-05-19 - GLS - Added updating of header tags:
;                        DATAMIN, DATAMAX, DATAMEDN, DATAMEAN, DATARMS, DATASKEW, DATAKURT
;   2011-05-20 - GLS - Changed from inserting OINDEX0 into pre-defined OINDEX array back to concatenation
;                        cause I couldn't figger out a bonehead error.
;   2011-06-08 - GLS - Corrected error in usage of OUTFILE parameter.
;   2011-07-13 - GLS - Corrected errors in processing of 'cutout' images.
;   2011-12-19 - GLS - Corrected CRPIX error in HMI cutouts.
;   2011-12-20 - GLS - Further correction of CRPIX errors.
;   2012-07-26 - GLS - Inserted special handling of single file case to remove redundant read_sdo call
;                      identified by Marc DeRosa.
;   2012-08-12 - GLS - 1. Added Venus Transit-derived CDELT and CROTA corrections for older files.
;                      2. Added keyword NO_ASTROMETRY to inhibit application of 2012 Venus transit (and
;                         perhaps other event) pointing updates to pre_transit/event files.
;                      3. Replaced keyword CUTOUT with keyword CUTOUT_CENTER and made it function as
;                         keyword USE_REF.
;   2012-09-10 - GLS - Changed the deafult for handling scale/roll updates.  Now by default the latest
;                      MPO record for every image header is read and used for roll and scale values.
;                      User may force use of header values by setting USE_HDR_PNT flag.  Alternatively,
;                      user may pass MPO record number to use via MPO_REC_NUM keyword (see above).
;                      The NO_ASTROMETRY keyword is eliminated.
;   2012-10-30 - GLS - Major re-design.  Broke into functional pieces leaving AIA_PREP.PRO as just the
;                      front end.
;   2012-11-15 - GLS - Added missing default for N_NOT_EXIST_MAX , and modified call to AIA_REG .
;                      Thanks to Giuliana de Toma, Trae Winter, David Shelton for bug report.
;   2013-01-07 - GLS - Added T_REF and MPO_REC_NUM keywords.
;   2013-04-20 - GLS - Added NORMALIZE keyword.
;   2013-05-20 - GLS - Corrected bug in handling of cutouts.
;   2013-06-27 - GLS - Further debugs...(sigh)...
;   2013-07-22 - GLS, Alessandro Cilla - Corrected bugs associated with inputing files instead of
;                                        INDEX and DATA variables.
;   2019-04-10 - GLS - Added keyword 'ds' for specifying JSOC MPO data series.  Default is:
;                      'aia.master_pointing3h'
;-

; Define prognam, progver variables
prognam = 'AIA_PREP.PRO'
prognam_main = prognam

progver = 'V5.10' ; 2013-06-27 (GLS)
progver_main = progver

if keyword_set(verbose) then print, 'Running ', prognam, ' ', progver

; Start runtime clock running:
t0 = systime(1)
t1 = t0	; Keep track of running time

; Define parameters:
if ~exist(n_img_max) then n_img_max = 100

; Set miscellaneous variables, flags, etc:
use_ref = ( keyword_set(use_ref) or keyword_set(cutout) or exist(index_ref) )
cutout  = ( keyword_set(use_ref) or keyword_set(cutout) or exist(index_ref) )

; --------------------------------------------------
; Begin input identifcation and verification section
; --------------------------------------------------

; Case of insufficient inputs:
if n_params() lt 2 then begin
   print, ' Input error: Minimum input parameters is 2 (file list and index list).  Returning.'
   return
endif

; Case of file list/index list inputs:
if size(input1, /tname) eq 'STRING' then begin
   input_mode = 'file_list'

   ss_infil = input2
   if ss_infil[0] eq -1 then ss_infil = indgen(n_elements(input1))

; Return if any files are not found:
   exist_arr = file_exist(input1[ss_infil])
   if min(exist_arr) eq 0 then begin
      print, ' Input error: Not all files in file list found.  Returning.'
      return
   endif

   n_img = n_elements(ss_infil)
   infil_arr = input1[ss_infil]
endif

; Case of index/data inputs:
if size(input1, /tname) eq 'STRUCT' then begin
   input_mode = 'index_data'

   n_img = n_elements(input1)
endif

; ------------------------------------------------
; End input identifcation and verification section
; ------------------------------------------------

; -----------------------------------------------
; Begin imposed restrictions and advisory section
; -----------------------------------------------

if n_params() ge 4 then begin

   if n_img gt n_img_max then begin
      print, " User is requesting an output cube for " + strtrim(n_img,2) + $
             " input images.  This may exceed system memory."
      print, " Suggest writing output to disk using '/do_write_fits' parameter,"
      print, " and leaving off the 'odata' parameter,"
      print, " or limiting input file total to less than " + strtrim(n_img_max,2) + "."
      print, " Returning without processing."
      return
   endif else begin
      if keyword_set(do_write_fits) then begin
         print, ' User is requesting that processed images be written to files,'
         print, ' and that an output cube also be returned.'
         print, ' Suggest leaving off output cube parameter.'
      endif
   endelse

endif

; ---------------------------------------------
; End imposed restrictions and advisory section
; ---------------------------------------------

; Call the front end registration routine:

aia_reg, input1, input2, oindex, odata, input_mode=input_mode, $
         index_ref=index_ref, ds=ds, $
         no_pnt_update=no_pnt_update, $
         no_uncomp_delete=no_uncomp_delete, $
         nearest=nearest, interp=interp, cubic=cubic, normalize=normalize, $
         do_write_fits=do_write_fits, outdir=outdir, outfile=outfile, $
         use_dummy_fits=use_dummy_fits, verbose=verbose, run_time=run_time, $
         progver_main=progver_main, prognam_main=prognam_main, $
         qstop=qstop, _extra=_extra

if keyword_set(qstop) then stop,' Stopping on request.'

end

