pro sxt_prep, input1, input2, index_out, data_out, unc_data, satpix, $
	;
	;------------------------- Calibration parameters
	nocorrections=nocorrections, $
	dc_scalar=dc_scalar, dc_interpolate=dc_interpolate, $
        dc_orbit_correct=dc_orbit_correct, $
        no_dc_orbit_correct=no_dc_orbit_correct, $
	upper_only=upper_only, $
	sfd_corr=sfd_corr, $
	rest_low8=rest_low8, $
	;
	;------------------------- Alignment parameters
	register=register, fast=fast, $
	ref_image=ref_image, $
	helio=helio, date_helio=date_helio, $
	suncoord=suncoord, $
	ccdcoord=ccdcoord, $
	outres=outres, outsize=outsize, $
	st_en_lin = st_en_lin, $
	fill_gap=fill_gap, trim_edge=trim_edge, $
	noroll=noroll, roll_do=roll_do, $
	cubic=cubic, interp=interp, $
        oride_pnt_chk=oride_pnt_chk, $
	;
	;------------------------- Secondary processing parameters
	exp_normalize=exp_normalize, normalize=normalize, $
	sum=sum, $
	vignette_cor=vignette_cor, $
	despike_thresh=despike_thresh, width=width, $
	sigma_filt=sigma_filt, n_sigma=n_sigma, sigma_iterate=sigma_iterate, $
	;
	;------------------------- Miscellaneous
	float=float, $
	force_read=force_read, outfile=outfil, append=append, $
	allow_duplicates=allow_duplicates, $
	new_sdc_db=new_sdc_db, new_sfc_db=new_sfc_db, $
	error=error, $
	run_time=run_time, $
	override=override, $
	qdebug=qdebug, qstop=qstop, qmstop=qmstop, q2stop=q2stop, help=help
;+
;NAME:
;	sxt_prep
;SAMPLE CALLING SEQUENCE:
;	sxt_prep, input1, input2, index_out, data_out
;	sxt_prep, index, data, index_out, data_out
;	sxt_prep, infil, dset_arr, index_out, data_out, unc_data, satpix, $
;			helio=[-9.8,-20.3], date_helio='14-JUN-92  02:37:41')
;	sxt_prep, index, data, index_out, data_out, /helio, ref_image=10)
;	sxt_prep, index, data, index_out, data_out, ref_image=spr_index(0))
;	sxt_prep, index, data, index_out, data_out, /roll
;	sxt_prep, index, data, index_out, data_out, new_sdc_db='/1p/acton/new_db'
;PURPOSE:
;	This is a general purpose routine to prepare the SXT data for
;	analysis.  The steps performed are:
;		1. Flag the saturated pixels
;		2. Decompress the data
;		3. Subtract the dark current
;		4. Subtract the pin hole leak
;		5. Remove the spikes from the images
;		6. Apply the vignette correction
;		7. Align the images and build the observing region.  The
;		   routine can extract subportions out of FFI images
;		8. Fill in the horizontal gaps in the observing region
;		9. Exposure normalize
;	It does not do the following items which the earlier version of
;	SXT_PREP did do:
;		*. Temporal interpolation
;
;	Image to image registration is only performed if one of the following
;	keywords is used:
;		REGISTER
;		SUNCOORD
;		HELIO
;		CCDCOORD
;	Use only ONE of the following at one time (SUNCOORD, HELIO, CCDCOORD)
;INPUT:
;		  ** There are two methods for calling SXT_PREP **
;	input1	- A. The index structure for each of the input images
;		  B. The names of the input files
;	input2	- A. The input data array
;		  B. The dataset numbers to extract and process
;OUTPUTS:
;	data_out - The output data array
;	index_out- The index structure for each output image
;OPTIONAL OUTPUTS:
;       unc_data- The uncertainty array for each image.  These are NON-
;                 STATISTICAL errors and are caused by decompression errors
;                 in the data, background and straylight images (where
;                 applicable).  NO statistical errors are included.
;		  See the routine SXT_DN_UNC to add in the photon statistics.
;
;		  There are at least three non-statistical errors:
;                       d_comp  = decompression error (sxt_decomp)
;                       d_dark  = dark subtraction error (dark_sub)
;                       d_reg   = Error from registration (align_prep)
;				  (which will be included in the future)
;                 sxt_prep returns sqrt(d_comp^2+d_dark^2+d_reg^2).
;	satpix	- The saturated pixel map for the data extracted.  It is
;		  a boolean data array with non-zero values for pixels which
;		  were saturated in the original image.
;OPTIONAL KEYWORD INPUTS:
;		-------------------- Calibration Parameters --------------------
;	dc_scalar- If set, then a simple scalar value is used for dark current 
;		  subtraction. Default is to take the image closest in exposure.
;	dc_interpolate - If set, then perform interpolation on the dark frame
;		  images to get a better backround subtraction.  Deafult is to
;		  take the image closest in exposure.
;       dc_orbit_correct - If set, apply SDC Orbital Variation Correction
;	upper_only - If set, only flag +1 pixels above (in a column) the
;		  saturated area (not the -1 pixels) [see call to sxt_satpix].
;	sfd_corr - If set, then the input image is an SFD image.  Use the
;		  SFD decompression, perform the registration, and recompress
;		  using the SFD compression.
;	rest_low8 - If set, then call the routines to restore low-8 data.  
;		  You must pass in low-8 along with compressed data.  You
;		  will get restored images AND simple single compressed 
;		  images as the output.
;	
;		-------------------- Alignment Parameters --------------------
;	register - If set, then perform the registration and correct only for
;		the S/C jitter.  See the /FAST option if you do not want
;		to have sub-pixel registration performed.
;	fast	- If set, then perform the registration in "FAST" mode which
;		is simple full pixel shifts instead of POLY2D.
;
;	ref_image - A single roadmap or index structure which will be used 
;		to define the sun or heliocentric coordinates for alignment.  
;		It can be the image number (subscript) of the images being
;		extracted which should be used (not the absolute dataset 
;		number within the images listed in "infil") 
;
;	helio - the reference latitude and longitude for the alignment.
;		This should be the position of the active region at some 
;		time, preferably near the time it crossed closest to the 
;		center of the disk.  If a sub-image is to be extracted, 
;		HELIO specifies the center of the sub-image.
;			helio(0) = longitude E/W (E is negative)
;			helio(1) = latitude N/S (S is negative)
;		It can be a non-zero scalar value if REF_IMAGE is passed in.
;		In this case, the heliocentric coordinates are derived
;		from "REF_IMAGE".
;		DO NOT USE WITH SUNCOORD AND CCDCOORD.
;	date_helio - the reference date/time for the heliocentric input.
;
;	suncoord - The coordinates of the center of the portion to extract
;		   in angular arcseconds relative to sun center.
;			suncoord(0) = E-W coordinate (E is negative)
;			suncoord(1) = N-S coordinate (S is negative)
;		   DO NOT USE WITH HELIO AND CCDCOORD.
;
;       ccdcoord - The FRE (full resolution CCD pixel equivalent) of the
;                  center of the portion to extract
;		   DO NOT USE WITH SUNCOORD AND HELIO
;
;	outres- The resolution of the output image (0=FR, 1=HR, 2=QR).
;		If not set, and the input is not all FFI, then convert all 
;		to full res.  If all FFI, then set outres to the highest
;		resolution of the input images (typically half resolution)  
;		Only relevant if registering the images.
;	outsize- The dimention of the ouptut image [#col, #lin]
;		If it is a scalar value, it will make the #lin = #col
;		If not set, it will make it the largest size of the input
;		field of views.  If PFI and FFI are mixed, it will take
;		the largest PFI.
;
;	fill_gap - A gap can exist between two PFI strips for a single
;		   observing region because of a change in S/C pointing.
;		   If this variable is set, then the gap between the PFI
;		   strips is filled by interpolating the lines above and below
;	trim_edge - Used with /FILL_GAP.  If set, then replace the edge 
;		  line of pixels as well as the gaps.  Will set /FILL_GAP 
;		  if /TRIM_EDG is set.
;	noroll	- If set, then do not perform roll corrections.  Currently the
;		  default
;	roll_do	- If set, then perform the corrections for the roll offset
;       interp  - If set, roll correction uses bilinear interpolation
;                 (See Description in IDL poly_2D documentation header)
;	cubic   - If set, roll correction uses cubic convolution interpolation
;                 (See Description in IDL poly_2D documentation header)
;       oride_pnt_chk - If set, then do not compare the ATT/GET_SUNCENTER
;                 results to the commanded values to see that they are
;                 truly valid points.  This is useful for times when the
;                 commanded pointing history file is not updated properly
;                 or for real time applications when the commanded pointing
;                 history is not updated yet.
;       align_unc  - The uncertainties in alignment coordinates, a pair of
;                 (x,y) in FR pixels. If set to any scalar, this will use
;                 TEST_POLY to determine these values.  TEST_POLY fits the 
;		  corner coordinates obtained from ALIGN_PREP to a polynomial 
;		  of degree bewteen 1 to 10, and estimates the mean uncertainty 
;		  from the fluctuations of the pointing coordinates around the 
;		  smoothed values. 
;			*** ALIGN_UNC is not available right now ***
;                 
;
;		-------------------- Secondary Processing Parameters ----------
;	sum	- Sum over SUM X SUM pixels.  It must be a scalar value.
;	exp_normalize - If set, normalize the count rates in the output image
;		  to DN/sec/full_res_pixels.
;	normalize- Same as EXP_NORM
;	
;	vignette - If set, then apply the correction for the vignette
;		  loss in signal off axis.  The function SXT_OFF_AXIS
;		  is called to peform the correction.  For certain applications
;		  it is recommended to use /FLOAT with this /VIGNETTE option.
;
;		-------------------- Image Filtering Parameters ----------
;	despike_thresh - Call DE_SPIKER to remove spikes from the image.  
;		  This step is done before sub-pixel registration.
;		  The value set on the call is passed into the function
;		  DE_SPIKER as "threshold" (the first parameter)
;	width	- If DESPIKE_THRESH is set, then pass this value through
;		  to DE_SPIKER.  If SIGMA_FILT is set, then pass this value
;		  through to the SIGMA_FILTER function.
;	sigma_filt - Call the SIGMA_FILTER function with SIGMA_FILT as
;		  the "box_width" variable.
;	n_sigma	- If SIGMA_FILT is set, then pass this value through to
;		  the function SIGMA_FILTER
;	sigma_iterate - If SIGMA_FILT is set, then pass this value through 
;		  to the function SIGMA_FILTER as keyword input "iterate"
;
;		-------------------- Miscellaneous Parameters ----------
;	float	-  If set, then make the output floating point (REAL*4)
;	force_read - If set, read all datasets at once even if input was 
;		  specified with INFIL/DSET.  This is available because doing 
;		  LEAK_SUB on all images at once if the input is PFI is more 
;		  efficient
;	outfil	- If specified, the data will not be passed back in INDEX_OUT and
;		  DATA_OUT.  Instead, it will be saved in an SDA file with the
;		  name specified by this parameter. 
;		  If "uncert" and "satpix" are included in the procedure call,
;		  they will be saved with the same file name with a "_unc"
;		  and a "_sat" appended to the file name.
;	qdebug	- If set, display some diagnostic messages
;	qstop	- If set, stop execution inside this subroutine (for debugging)
;	nocorrections- This keyword is intended for debugging purposes and should
;		  not be used.  If set, then LEAK_SUB is not called.  LEAK_SUB
;		  will automatically not be called if the input data is of
;		  non-byte type.
;	help	- If set, then display the help file /ys/sxt/doc/sxt_prep.txt
;	allow_duplicates  - If set, then do not do the serial number check to
;		  combine observing region PFIs into one image (ie: if the same
;		  image comes in twice in the input, make it show up twice
;		  in the output)
;	new_sdc_db - Optionally pass the the directory where an alternate
;		  dark current database reside.  RECOMMENDED FOR EXPERTS ONLY.
;		  See the routine SET_NEW_DB for details.  SXT_PREP resets
;		  to the official database directory before returning
;	new_sfc_db - Same as "new_sdc_db" except for leak database
;OPTIONAL KEYWORD OUTPUTS:
;	error	- Error information.  
;			0 - No errors
;			1 - "index" and "data" input parameters are undefined
;			2 - "index" and "data" data types are incorrect
;	run_time - The number of minutes that SXT_PREP took
;	st_en_lin - The start/end line number where each PFI strip is inserted 
;		    into the output array.  It is 2 x # PFI Strips x # output 
;		    images.
;METHOD
;	When running YODAT, the user should NOT have the observing regions
;	assembled.  This routine will perform dark subtraction on each 
;	individual exposure and will align each PFI strip independently.
;
;	-------------------- Calibration Options --------------------
;	Decompression, dark_sub, leak_sub
;
;	-------------------- Alignment Option --------------------
;	To align the images.  User can specify
;		(1) heliocentric coordinates for a given time/date
;		    (corrects for solar differential rotation and S/C drift)
;		(2) the fixed coordinates relative to sun center in arcmin
;		    (corrects for S/C drift)
;		(3) simple CCD coordinates (probably only used when
;		    assembling observing regions, but want to do background
;		    subtraction first) (would not take out S/C drift)
;	The images are all changed to full resolution, and the signal is
;	scaled accordingly (an image converted from HR to FR has the signal
;	divided by 4 because there are 4 times more pixels now.  The total
;	signal is preserved)
;
;	NOTE: When using the registration options (/REG, /HELIO, SUNCOORD)
;	  sub-pixel registration will be performed using POLY2D.  This could
;	  cause the image to appear to be smeared.  For example, if there is
;	  a single pixel bright spot (solar flare or dark spike).  If there
;	  is a 0.5 pixel east/west shift to register it to other images, half 
;	  of the pixel intensity is left in the original pixel and half is 
;	  moved to the adjacent pixel.
;RESTRICTIONS:
;
;HISTORY:
;	Written 16-Aug-93 by M.Morrison using and merging:
;		ALIGN_PFI (which used  Metcalf ALIGN_AR as starting point)
;		SXT_PREP (JRL 20-Apr-93 version)
;V1.03	   Aug-93 (MDM)
;V1.04	31-Aug-93 (MDM) - Various patches
;			- Added RUN_TIME option
;V1.05	 3-Sep-93 (MDM) - Adjusted the documentation header some
;			- Changed the alignment code to always use ALIGN1IMG
;			  for all combinations of PFI/FFI
;			- Renamed keyword EXP_NORM to EXP_NORMALIZE
;	 8-Sep-93 (SLF) - add append keyword (for sav_sda call)
;V1.06	15-Sep-93 (MDM) - Added print statement on what version of SXT_PREP
;			  is being run
;			- Changed so that the sat pixel registration is
;			  done properly (sub pixel, sub-DN problem)
;			- Made the "uncert" data output type byte
;	16-Sep-93 (MDM)	- Added NORM_FACT switch to ALIGN1IMG call for
;			  satpix and uncert data.
;V1.07	22-Sep-93 (MDM) - Corrected error in the /NORM option (it was not
;			  working at all)
;			- Corrected error in the /FILL_GAP option
;V1.08	 1-Oct-93 (MDM) - Minor modification to recognize when registration
;			  is requested.
;V1.09	 6-Oct-93 (MDM) - Modified so that when not using the /REGISTER option
;			  the output size is determined in originally summed
;			  pixels (not Full res pixels)
;V1.10	11-Oct-93 (MDM) - Corrected for the case where an OR is assembled but
;			  /REGISTER is not used.  It was not saving the corner
;			  or new shape properly.
;V1.11	13-Oct-93 (MDM) - Enabled DC_INTERPOLATE and DC_SCALAR options
;V1.12	15-Oct-93 (MDM) - Corrected for problem when registering the BYTE
;			  uncertainty array
;	15-Nov-93 (MDM) - Modified the header information 
;V1.13	18-Nov-93 (MDM) - Patched an error in EXT_SUBIMG3 which was resulting in
;			  poorly aligned images.  Problem was in rounding off
;			  between integers and reals
;	19-Nov-93 (MDM) - Modified to make the output data type BYTE when using
;			  the /SFD_CORR option
;V1.14	24-Nov-93 (MDM) - Corrected error with OR assembly.  The problem was
;			  with EXT_SUBIMG3.  Added the /TRIM option inside
;			  the ALIGN1IMG call.
;			- Modified to record the actual percent of data present
;			  when doing the observing region assembly.
;V1.15	30-Nov-93 (MDM) - Renamed from SXT_PREP2 to SXT_PREP (Jim's original
;			  SXT_PREP is renamed to SXT_PREP0)
;	 1-Dec-93 (MDM) - Added /QMSTOP option (stop within the per image loop)
;V1.16	 3-Dec-93 (MDM) - Modified so that when MOD_RES is called with an SFD
;			  image, the signal is not changed.
;			  Added "norm_fact=qsfd" to ALIGN1IMG call because the 
;			  signal level of SFD images are all normalized to 
;			  DN/sec/HR pixels
;V1.17	 6-Dec-93 (MDM) - Protected against different index version numbers
;			  when inserting into the INDEX_OUT array.
;V1.18	 9-Dec-93 (MDM) - Modified so that when all input is FFI and /HELIO
;			  option, and outsize is not specified, then default
;			  to 128x128.
;			- Modified "automatic forced reading" (which happens
;			  if the input is a file, all SPR) so that it does not
;			  occur if the amount of data is over 4 megabytes.
;V1.19	10-Dec-93 (MDM) - Added /Q2STOP
;			- Corrected V1.14 mod to properly record the actual 
;			  percent of data present when doing the observing 
;			  region assembly.
;V1.20	 4-Jan-94 (MDM) - **** IMPORTANT MODIFICATIONS ****
;			- Adjust the optical images to be aligned to the
;			  x-ray images
;			- Incorporated the S/C roll into the correction
;V1.21	 5-Jan-94 (MDM) - Made the default not to perform the roll correction
;			- Modifed roll correction to make the sun center the
;			  pivot location instead of a fixed point
;V1.22	14-Jan-94 (MDM) - Modified to do the roll correction outside of
;			  ALIGN1IMG and to do it after all OR parts are
;			  put together.
;V1.23	17-Jan-94 (MDM) - Corrected roll option to only be done if asked for
;V1.24	31-Jan-94 (MDM) - Corrected some of the /FILL_GAP capabilities
;			- Added /TRIM_EDGE option
;V1.25	 8-Feb-94 (MDM) - Corrected selection of the alignment location
;			  Previously, the location took into account the
;			  SXT roll, even if the roll correction was not
;			  being selected.  It resulted in images not quite
;			  filling the output data cube (there was a gap on
;			  the edge with zero data).  The coordinates being
;			  saved were correct though.
;V1.26	21-Feb-94 (MDM) - Added /ORIDE_PNT_CHK to optionally not compare the
;                         ATT/GET_SUNCENTER results to the commanded values to see
;                         that they are truly valid points
;V1.27	22-Feb-94 (SLF/MDM) - Reincorporated SLF changes of 15-Feb-94 which
;			  added /INTERP and /CUBIC keywords and function
;	22-Feb-94 (MDM) - Added /FAST options for simple pixel registration
;V1.28	25-Feb-94 (MDM) - Added check to see what the resolutions are when
;			  using the /NOCORR option.  It returns if they are
;			  not all the same resolution, and sets OUTRES if
;			  they are all the same resolution.
;V1.29	 8-Mar-94 (MDM) - Added logging of the fact that roll corrections
;			  were applied
;V1.30	30-Mar-94 (MDM) - Modified to get the shape using GT_SHAPE with
;			  the /OBS_REGION switch instead of using GT_SHAPE_CMD
;			- Added information on "uncert" and "satpix" to the
;			  header.
;V1.31	31-Mar-94 (MDM) - Adjusted logic so that you could do a roll correction
;			  without doing a registration correction
;			- The 14-Jan-94 mod caused the roll correction logging
;			  to not be done properly.  It was fixed.
;			- Log the roll value in .SUN_CENTER even if registration
;			  was not done
;V1.32	20-Jun-94 (MDM) - Modified so that registration is done if /ROLL is set
;	25-Jul-94 (MDM) - Modified the header document
;			- Added check that only one of SUNCOORD, CCDCOORD and 
;			  HELIO are used in the call.
;V1.33	19-Sep-94 (MDM) - Corrected an error which was causing the images to be
;			  shifted by 0.5 pixels when the ref_image option was 
;			  being used.  Image to image registration is not 
;			  affected and the absolute coordinate is not affected 
;			  (it recorded the value 0.5 pixels off of what was 
;			  really wanted).  SXT_PREP was doing sub-pixel shifts 
;			  when not wanted which was causing the image to be 
;			  smeared unncessarily.
;			- Added header information (about sub-pixel image smear)
;	14-Nov-94 (MDM) - Modified to set /REGISTER when CCDCOORD is passed in.
;	15-Dec-94 (MDM) - Updated header information (discouraged use of
;			  the /NOCORRECTIONS keyword)
;       12-Feb-95 (JMM) - Added uncertainties obtained from LEAK_SUB/DARK_SUB
;V1.40	27-Feb-95 (MDM) - Put McTiernan additions on-line
;V1.41	 6-Mar-95 (MDM) - Made UNC_DATA floating if /NORM is set
;V1.50	20-Mar-95 (MDM) - Added /VIGNETTE switch
;			- Added /DESPIKE_THRESH switch
;			- Added /SIGMA and /WIDTH switch
;			- Made /DC_INTERPOLATE the Default *************
;			- Added /FLOAT switch
;			- Changed to make OUTRES equal to the highest
;			  resolution of the input if OUTRES is not specified
;			  and OUTSIZ is not specified
;			- Added /HELP switch
;V1.51	20-Mar-95 (MDM) - Pass the /FLOAT switch to LEAK_SUB
;	22-Mar-95 (MDM) - Fixed typo /DC_INTREPOLATE versus /DC_INTERPOLATE
;V1.52	23-Mar-95 (MDM) - Added /REST_LOW8 option to retore low-8 data.
;	10-Apr-95 (MDM) - Added documentation header information (on UNC_DATA)
;	11-Apr-95 (MDM) - Added typout=2 for low8 with /nocorr
;	19-Apr-95 (MDM) - Modified the documenation header (on UNC_DATA)
;V1.53	18-May-95 (MDM) - Added /ALLOW_DUPLICATES keyword
;			- Added NEW_SDC_DB and NEW_SFC_DB keywords
;V1.54	22-Jun-95 (MDM) - Trap and dis-allow /ROLL_DO with CCDCOORD
;V1.55	 1-Sep-95 (MDM) - Fixed the UNC_DATA rotated results be saved in 
;			  "udata0" temporarily instead of directly into 
;			  "unc_data" array so that OUTFIL option works properly
;V1.56   1-Feb-98 (SLF) - add DC_ORBIT_CORRECT and NO_DC_ORBIT_CORRECT (->leak_sub)
;V1.57  19-Feb-98 (SLF) - make 1-feb change work for file input option
;V1.58  20-Nov-98 (DMcK)- put in odd/even test of outsize, in Alignment 
;			  section, in derivation of xc,yc. Intended to 
;			  make patch of 19-Sep-94 work for all values of
;			  OUTSIZE.
;-
;
progverno = 1.580*1000  ; new version
print, '           *****   SXT_PREP  Ver 1.58  20-Nov-98   *****
;
if (keyword_set(help)) then begin	;MDM added 20-Mar-95
    help_file = concat_dir('$DIR_SXT_DOC', 'sxt_prep.txt')
    if (file_exist(help_file)) then begin
	help = rd_tfile(help_file)
	prstr, help
    end else begin
	print, 'The help file: ' + help_file + ' is not available.  Sorry...'
    end
    print, 'Returning...
    return
end
;
;------------------------------------------------------------------------------
;		Variable initialization and help information
;------------------------------------------------------------------------------
;
if (keyword_set(helio)+keyword_set(suncoord)+keyword_set(ccdcoord) ge 2) then begin	;MDM added 25-Jul-94
    print, 'SXT_PREP: More than one of the following keywords was used'
    print, '                 SUNCOORD, HELIO, CCDCOORD
    print, 'Returning ...
    tbeep, 3
    return
end
;
append=keyword_set(append)

start_time = systime(1)
run_time = 0.
error = 0
data_out = 0
index_out = 0
sat_limit = [235, 255, 255]                     ; Full, half, quarter resolution
;
his_index, /enable
quncert = n_params() ge 5
qsatpix = n_params() ge 6
qoutfil = n_elements(outfil) ne 0
qroll	= keyword_set(roll_do) or keyword_set(interp) or keyword_set(cubic)
if (keyword_set(noroll)) then qroll = 0
qreg    = keyword_set(register) or keyword_set(helio) or keyword_set(suncoord) or $
		keyword_set(ref_image) or keyword_set(fast) or keyword_set(qroll) or keyword_set(ccdcoord)
qcor	= 1-keyword_set(nocorrections)
qsfd	= keyword_set(sfd_corr)
qnorm   = keyword_set(exp_normalize) or keyword_set(normalize)
qsum	= keyword_set(sum)
qfill_gap = keyword_set(fill_gap) or keyword_set(trim_edge)
if (qsfd) then qcor = 0		;don't do normal corrections if doing SFD corrections
qvig    = keyword_set(vignette_cor)
qdespike= keyword_set(despike_thresh)
qsig_filt=keyword_set(sigma_filt)
qlow8	= keyword_set(rest_low8)
if (qroll) and (keyword_set(ccdcoord)) then begin	;MDM added 22-Jun-95
    print, 'SXT_PREP: Sorry, you cannot apply roll correction with CCDCOORD option.
    print, '          Continuing without applying roll correction
    qroll = 0
end
;
if (qcor and (n_elements(dc_interpolate) eq 0) and (not keyword_set(dc_scalar))) then begin	;MDM added 20-Mar-95
    print, '--------------------------------------------------------------'
    print, '  The /DC_INTERPOLATE option is strongly recommended          '
    print, '  SXT_PREP is setting this option automatically               '
    print, '  Use "DC_INTERPOLATE=0 to disable dark current interpolation '
    print, '--------------------------------------------------------------'
    dc_interpolate = 1
end
;
if (keyword_set(oride_pnt_chk)) then set_logenv, 'YS_ORIDE_PNT_CHK', '1'
;
if (n_params() LT 2) then begin
    print, 'SXT_PREP Sample Calling Sequences:
    print, '	sxt_prep, input1, input2, index_out, data_out
    print, '	sxt_prep, index, data, index_out, data_out
    print, '	sxt_prep, infil, dset_arr, index_out, data_out, $
    print, '		helio=[-9.8,-20.3], date_helio=''14-JUN-92  02:37:41'')
    print, '	sxt_prep, index, data, index_out, data_out, $
    print, '		/helio, ref_image=index(0))
    print, '	sxt_prep, index, data, index_out, data_out, ref_image=spr_index(0))
end
;
ARCSEC_PER_PIX = gt_pix_size()
;
;------------------------------------------------------------------------------
;		Figure out how the input images are specified
;------------------------------------------------------------------------------
;
if ((n_elements(input1) eq 0) or (n_elements(input2) eq 0) ) then begin
    message, 'First two parameters Undefined.  Must be INDEX,DATA or INFIL,DSET_ARR', /info
    error = 1
    return
end
;
typ_in = -99
siz = size(input1)	& typ1 = siz( siz(0)+1 )
siz = size(input2)	& typ2 = siz( siz(0)+1 )
;
case typ1 of
    7:  begin		;string type
	    qread = 1
	    quse_input2 = 0
	    infil = input1
	    dset_arr = input2
	    dset = mk_dset_str(infil, dset_arr)
	    rd_xda, infil, dset, index, /nodata		;read the index for all input images
	end
    8: begin		;structure type
	    qread = 0
	    quse_input2 = 1
	    index = input1
	end
    else: begin
	    message, 'Error in input data types', /info
	    message, 'First two parameters must be INDEX,DATA or INFIL,DSET_ARR', /info
	    error = 2
	    return
	  end
endcase
;
if (typ2 ge 6) then begin	;complex, string, or structure
    message, 'Error in input data types', /info
    message, 'First two parameters must be INDEX,DATA or INFIL,DSET_ARR', /info
    error = 2
    return
end
;
;------------------------------------------------------------------------------
;		Check to see if all resolutions are the same if using /NOCORRECTIONS (MDM added 25-Feb-94)
;------------------------------------------------------------------------------
;
if (keyword_set(nocorrections)) then begin
    resarr = gt_res(index)
    if (min(resarr) ne max(resarr)) then begin
	print, 'SXT_PREP: Sorry, all input images must be the same resolution
	print, '          when using the /NOCORRECTIONS option'
	;MOD_RES crashes otherwise - fix there if you are going to remove this requirement
	return
    end
    outres = min(resarr)
end

;------------------------------------------------------------------------------
;		Figure out the mixture of FFI and PFI
;------------------------------------------------------------------------------
;
n = n_elements(index)
;pfi_ffi = gt_pfi_ffi(index, /true_ffi)		;returns 1 for true FFI, 0 for PFI/OR/Extracted PFI
pfi_ffi = gt_pfi_ffi(index)			;returns 1 for FFI
ss_pfi = where(pfi_ffi eq 0, npfi)
ss_ffi = where(pfi_ffi eq 1, nffi)
fcode = (npfi ne 0) + (nffi ne 0)*2		;1 = PFI only
						;2 = FFI only
						;3 = PFI/FFI mixed
if (keyword_set(qdebug)) then print, 'FCODE = ', fcode

;------------------------------------------------------------------------------
;		Figure out the output resolution (MDM added 20-Mar-95)
;------------------------------------------------------------------------------

if (n_elements(outres) eq 0) then begin
    if (n_elements(outsize) eq 0) and (fcode eq 2) then outres = min(gt_res(index)) $
						   else outres = 0
end

;------------------------------------------------------------------------------
;		Figure out the output image size
;------------------------------------------------------------------------------
;
case n_elements(outsize) of
    0: begin
	    ;call something like mk_mosaic to get size		- TODO

	    if (fcode eq 3) then ss = ss_pfi else ss = lindgen(n)

	    if (qreg) then begin
		nx = max(gt_shape(index(ss), /x, /obs_reg) * 2^gt_res(index(ss))) / 2^outres
		ny = max(gt_shape(index(ss), /y, /obs_reg) * 2^gt_res(index(ss))) / 2^outres
		if ((fcode eq 2) and keyword_set(helio)) then begin	;MDM added 9-Dec-93
		    nx = 128 < max(gt_shape(index(ss), /x, /obs_reg) * 2^gt_res(index(ss))) / 2^outres	;MDM added < conditional 25-Feb-94
		    ny = 128 < max(gt_shape(index(ss), /y, /obs_reg) * 2^gt_res(index(ss))) / 2^outres
		end
	    end else begin
		nx = max(gt_shape(index(ss), /x, /obs_reg))
		ny = max(gt_shape(index(ss), /y, /obs_reg))
	    end
	end
    1: begin
	    nx = outsize
	    ny = outsize
	end
    else: begin
	    nx = outsize(0)
	    ny = outsize(1)
	end
endcase
;
;------------------------------------------------------------------------------
;		Define the output variables
;------------------------------------------------------------------------------
;
if (keyword_set(new_sdc_db)) then set_new_db, new_sdc_db		;MDM added 18-May-95
if (keyword_set(new_sfc_db)) then set_new_db, new_sfc_db, /leak
;
ss = uniqo(index.sxt.serial_num)
ser_map = index(ss).sxt.serial_num
if (keyword_set(allow_duplicates)) then begin
    ser_map = lindgen(n_elements(index))		;MDM added 18-May-95
    ss = lindgen(n_elements(index))
end
nout = n_elements(ser_map)
if (qoutfil) then nout = 1
;
index_out = index(ss)	;just defining the output array
his_index, index_out	;append on the .HIS structure
;
typout = 1      ;default is byte type out
if (qread eq 0) then begin
    siz = size(input2)
    typ_in = siz( siz(0)+1 )
    typout = typ_in
    if (typout gt 1) and (not qlow8) then begin
	tbeep
	message, 'Input data is non-Byte type.  ', /info
	message, 'DECOMP/DARK_SUB/LEAK_SUB will not be called', /info
	if (quncert) then message, 'Uncertainty array will not be created', /info
	if (qsatpix) then message, 'Saturated pixel array will not be created', /info
	qcor = 0
	quncert = 0
	qsatpix = 0
    end
end
if (not keyword_set(nocorrections)) then typout = typout>2     ;decompressed = integer*2 type
if (qlow8) then typout = 2
if (qnorm) then typout = 4
if (keyword_set(float)) then typout = 4				;MDM 20-Mar-95
if (qsfd) then typout = 1	;MDM added 19-Nov-93
;
data_out = make_array(nx, ny, nout, type=typout)
if (quncert) then unc_data = make_array(nx, ny, nout, type=2)	;always int
if (qsatpix) then satpix   = make_array(nx, ny, nout, type=1)	;always byte
if (quncert and qnorm) then unc_data = float(unc_data)		;MDM added 6-Mar-95
;
nstrip = max( gt_or_expnum(index) )
st_en_lin = intarr(2, nstrip, nout)	;start/end line number where each PFI strip is inserted into the output array
;
;------------------------------------------------------------------------------
;		Initialization of the alignment information
;------------------------------------------------------------------------------
;
if (qreg) then begin
    align_prep, index, xx, yy, sc, code, $
	        ref_image=ref_image, $
	        helio=helio, date_helio=date_helio, $
	        suncoord=suncoord, $
		ccdcoord=ccdcoord, $
		qroll=qroll, $
		roll=roll_arr, $
                qdebug=qdebug, qstop=qstop
end else begin
    if (qroll) then roll_arr = get_roll(index)			;MDM added 31-Mar-94
end

;------------------------------------------------------------------------------
;		Optionally read all datasets even if input is INFIL/DSET
;------------------------------------------------------------------------------
;
nbytes = total(gt_shape(index,/x) * long(gt_shape(index,/y)))/1e+6		;MDM 9-Dec-93 - force read only if < 4 meg
if ((qread) and (fcode eq 1) and (nbytes lt 4)) then force_read = 1		;MDM 19-Aug-93
if (keyword_set(force_read)) then begin
    print, 'Reading all selected data from the input SPR files'
    rd_xda, infil, dset, index, data, roadmap
    qread = 0
    quse_input2 = 0
end
;
;------------------------------------------------------------------------------
;		Optionally restore low-8 data 
;------------------------------------------------------------------------------
;
if (qlow8) then begin
    ss88 = where(gt_comp(index) eq 0, nn88)
    if (nn88 eq 0) then begin
	print, 'SXT_PREP: You asked for restoring low-8, but did not 
	print, '          pass in a compressed image.  Please retry.
	print, '          Returning.........
	return
    end
    ;
    if (qread eq 1) then begin
	print, 'SXT_PREP: You asked for restoring low-8, but did not 
	print, '          pass in data.  You cannot use INFIL option 
	print, '          Returning.........
	return
    end
    ;
    if (quse_input2) then begin
	data = rest_low8_cube(index, input2)
	quse_input2 = 0
    end else begin
	data = rest_low8_cube(index, data)
    end
end
;
;------------------------------------------------------------------------------
;		If reading outside the loop, optionally call LEAK_SUB
;------------------------------------------------------------------------------
;
if (qread eq 0) then begin
    if (quse_input2) then begin
	if (quncert) then udata = sxt_decomp(input2, /uncert) else udata = 0 	;jmm, 18-Jan-95 
	if (qsatpix) then sdata = sxt_satpix(index, input2, sat_limit=sat_limit, upper_only=upper_only)
        if (qcor) then begin    ;jmm, 12-feb-95
           udata_out = quncert  ;this must be set for LEAK_SUB to pass out uncertainties
	   data = leak_sub(index, input2, index_out_qr, dc_interpolate = dc_interpolate, $
			dc_scalar = dc_scalar, udata_in = udata, udata_out = udata_out, $
			float=float, force_darksub=qlow8, orbit_correct=dc_orbit_correct)
           if (quncert) then udata = udata_out ;jmm, 12-feb-95, reset udata to the DARK_SUB value
        end
    end else begin
	if (quncert) then udata = sxt_decomp(data, /uncert) else udata = 0 ;jmm, 18-Jan-95
	if (qsatpix) then sdata = sxt_satpix(index, data, sat_limit=sat_limit, upper_only=upper_only)
        if (qcor) then begin    ;jmm, 12-feb-95
           udata_out = quncert  ;this must be set for LEAK_SUB to pass out uncertainties
           data = leak_sub(index, data, index_out_qr, dc_interpolate = dc_interpolate, $
			dc_scalar = dc_scalar, udata_in = udata, udata_out = udata_out, $
			float=float, force_darksub=qlow8, orbit_correct=dc_orbit_correct)
           if (quncert) then udata = udata_out ;jmm, 12-feb-95, reset udata to the DARK_SUB value

        end
    end
    if (qcor) then quse_input2 = 0
end
;
;------------------------------------------------------------------------------
;		Begin looping through each input image
;------------------------------------------------------------------------------
;
qfirst_out = 1
last_ser_num = -999
for iimg=0,n_elements(index)-1 do begin
    if (qread) then begin
	if (keyword_set(qdebug)) then print, 'Reading dataset # ', iimg
	rd_xda, infil, dset(iimg), index0, data0, roadmap
	siz = size(data0)
	typ_in = siz( siz(0)+1 )
	index_out0 = index0
    end else begin
	index0 = index(iimg)
	if (quse_input2) then data0 = input2(*,*,iimg) $
			else data0 = data(*,*,iimg)
	index_out0 = index0
	if (qcor) then index_out0 = index_out_qr(iimg)		;index out in this case is what is returned from LEAK_SUB
    end

    if (keyword_set(qdebug)) then print, 'Now processing ', fmt_tim(index0)
    ser_num = index0.sxt.serial_num
    if (keyword_set(allow_duplicates)) then ser_num = iimg	;MDM added 18-May-95
    iout = where(ser_map eq ser_num)
    iout = iout(0)	;make it scalar
    if (qoutfil) then iout = 0

    num_or = index_out0.sxt.shape_cmd(1) / index_out0.sxt.shape_sav(1)	;MDM added 24-Nov-93 (there has to be a better way!!)
									;^^ is the number of observing regions

    siz = size(data0)
    nx_data = siz(1)
    ny_data = siz(2)
    nx_in = gt_shape(index0, /x)
    ny_in = gt_shape(index0, /y)
    xxx1 = (nx_in-1) < (nx_data-1)      ;trim for the case of a smaller image imbedded in a larger data cube
    yyy1 = (ny_in-1) < (ny_data-1)
    data0 = temporary(data0(0:xxx1, 0:yyy1))    ;need "<(ny_data-1)" because gt_shape is or shape, and data0 could be pfi strip

    ;--------------------------------------------------------------------------------
    ;			Data decompression and background subtaction
    ;--------------------------------------------------------------------------------

    if (qread) then begin		;if not read, then already did leak_sub up above
	if (quncert) then udata0 = sxt_decomp(data0, /uncert) else udata0=0
	if (qsatpix) then sdata0 = sxt_satpix(index0, data0, sat_limit=sat_limit, upper_only=upper_only)
        if (qcor) then begin    ;jmm, 12-feb-95
           udata_out = quncert  ;this must be set for LEAK_SUB to pass out uncertainties
           data0 = leak_sub(index_out0, temporary(data0), save = (iimg NE N_ELEMENTS(index)-1) , $
                            /update_index, dc_interpolate = dc_interpolate, dc_scalar = dc_scalar, $
                            udata_in = udata0, udata_out = udata_out, $
			  float=float, orbit_correct=dc_orbit_correct)
           if (quncert) then udata0 = udata_out ;jmm, 12-feb-95, reset udata0 to LEAK_SUB value
        end
    end else begin
	if (quncert) then udata0 = udata(0:xxx1, 0:yyy1, iimg)
	if (qsatpix) then sdata0 = sdata(0:xxx1, 0:yyy1, iimg)
    end	

    ;--------------------------------------------------------------------------------
    ;			Optionally Correct for Vignetting and despike
    ;--------------------------------------------------------------------------------

    if (qdespike) then begin				;MDM added 20-Mar-95	
	data0 = de_spiker(data0, despike_thresh, width=width)
	his_index, index_out0, 0, 'q_extra', 1
	his_index, index_out0, 0, 'extra1', despike_thresh
    end

    if (qsig_filt) then begin				;MDM added 20-Mar-95
	cmd = 'data0 = sigma_filter(data0, sigma_filt, n_sigma=n_sigma, ' + $
				'iterate=sigma_iterate, /all_pixels)'
	stat = execute(cmd)
	his_index, index_out0, 0, 'q_extra', 2
	his_index, index_out0, 0, 'extra1', sigma_filt
    end

    if (qvig) then begin				;MDM added 20-Mar-95
	data0 = sxt_off_axis(index_out0, data0, /update_index)
    end

    if (qreg) then begin
	if (qsfd) then begin		;do SFD decompression
	    if (keyword_set(qdebug)) then print, 'SFD decompression'
	    data0 = sfd_decomp( temporary(data0) )
	    typ_in = 4			;it is decompressed now
	end

	;------------------------- Update the index record (do before ALIGN1IMG so have sun center location for pivot point)

	if (n_elements(helio) ne 0) then his_index, index_out0, 0, 'q_sun_rot', progverno
	if (n_elements(sc) ne 0) then his_index, index_out0, 0, 'sun_center', [sc(*,iimg), roll_arr(iimg)]

	;--------------------------------------------------------------------------------
	;			Extract and align the data
	;--------------------------------------------------------------------------------

	;;xc = xx(iimg) - nx/2*2^outres		;x corner address
	;;yc = yy(iimg) - ny/2*2^outres
	;xc = xx(iimg) - (nx-1)/2.*2^outres	;x corner address of what
	;yc = yy(iimg) - (ny-1)/2.*2^outres     ;we want - changed 
						;19-Sep-94 by MDM
	oddeven=nx mod 2		; added 20-Nov-98 by DMcK
	xc = xx(iimg) - (nx-(1-oddeven))/2.*2^outres
	oddeven=ny mod 2
	yc = yy(iimg) - (ny-(1-oddeven))/2.*2^outres

	index_save = index_out0
        align1img, index_out0, data0, xc, yc, nx, ny, ox0, oy0, outres, fast = fast, $
          qcor = qcor, typout = typout, typ_in = typ_in, qdebug = qdebug, oy = oy, override = override, norm_fact = qsfd
        ;^^ "norm_fact=qsfd" added because the signal level of SFD images are all normalized to DN/sec/HR pixels
        index_junk = index_save
        ;;udata0 = fix(udata0)	- use the /override option and stay in byte type the whole way
        if (quncert) then align1img, index_junk, udata0, xc, yc, nx, ny, ox0, oy0, outres, fast = fast, $
             qcor = qcor, typout = typout, typ_in = typ_in, qdebug = qdebug, oy = oy, /override, norm_fact = 2

        index_junk = index_save
	if (qsatpix) then begin
	    sdata0 = sdata0 * 100		;Added 15-Sept-93
	    align1img, index_junk, sdata0, xc, yc, nx, ny, ox0, oy0, outres, fast=fast, $
	    	    qcor=qcor, typout=typout, typ_in=typ_in, qdebug=qdebug, oy=oy, override=override, norm_fact=1
	    sdata0 = byte( sdata0/100. + 0.99)	;more than 1% of a saturated pixel moves will cause the 1% pixel to be flagged as
						;saturated
	end

	st_en_lin(*, gt_or_expnum(index0)-1, iout) = oy

	;------------------------- 

	if (keyword_set(qmstop)) then stop
	;------------------------- 

	if (qsfd) then begin
            if (keyword_set(qdebug)) then print, 'SFD compression'
            data0 = alog10( temporary(data0) >1. )
            data0 = bytscl( temporary(data0), max=6., min=0., top=255)
	end
    end else begin	;---------------------------------------- No registration case - still need to assemble observing region
	ox0 = 0
	oy0 = (gt_or_expnum(index0)-1)*64

	index_out0.sxt.shape_sav = gt_shape(index0, /obs_region)		;save the updated shape
	if (his_exist(index_out0)) then index_out0.his.corner_sav(1) = index_out0.his.corner_sav(1) - (gt_or_expnum(index0)-1)*64 $
				else index_out0.sxt.corner_sav(1) = index_out0.sxt.corner_sav(1) - (gt_or_expnum(index0)-1)*64
    end

    ;--------------------------------------------------------------------------------
    ;			Optionally Normalize the data
    ;--------------------------------------------------------------------------------

    if (qnorm) then begin
	data0 = exp_norm(data0, index_out0, 0.)
	junk_index = index(iimg)
	if (quncert) then udata0 = fix( exp_norm(udata0, junk_index, 0.0) + 0.5)
    end


    ;-------------------- Save the data into the index array

    if (ser_num ne last_ser_num) then begin		;only update the history record for the first occurance of a strip
	percentd = float(index_out0.sxt.percentd)/num_or + 0.5 		;initialize percentd variable (round up)
	index_out0b = str_copy_tags(index_out(0), index_out0)
	index_out(iout) = index_out0b
    end else begin
	percentd = percentd + float(index_out0.sxt.percentd)/num_or
    end

    ;-------------------- Save the data into the output cube

    if (keyword_set(qdebug)) then print, 'Image being inserted into: ox0, oy0, iout', ox0, oy0, iout
    if ((ox0 lt nx-1) and (oy0 le ny-1)) then begin
	data_out(ox0, oy0, iout) = data0
	if (quncert) then unc_data(ox0, oy0, iout) = udata0
	if (qsatpix) then satpix(ox0, oy0, iout) = sdata0
    end

    next_ser_num = -999
    if (iimg ne n_elements(index)-1) then next_ser_num = index(iimg+1).sxt.serial_num
    qfinished = next_ser_num ne ser_num		;if next image is a different OR, then we are finished with this one

    if (qfinished) then begin 
	index_out(iout).sxt.percentd = byte(percentd)<255

	;--------------------------------------------------------------------------------
	;			Optionally Roll the Image (MDM added/moved 14-Jan-94)
	;--------------------------------------------------------------------------------
	if (qroll) then begin
	    roll = roll_arr(iimg)
	    xpiv = -gt_corner(index_out(iout), /from_sc, /x)              ;invert the sign
	    ypiv = -gt_corner(index_out(iout), /from_sc, /y)
	    data0 = data_out(*,*,iout)	
	    if (quncert) then udata0 = unc_data(*, *, iout)
	    if (qsatpix) then sdata0 = satpix(*, *, iout)
	    ;
	    data_out(0,0,iout) = rot(data0, -roll, 1, xpiv, ypiv, missing=0, /pivot, cubic=cubic, interp=interp)
	    if (quncert) then begin
		;MDM made the rotated results be saved in "udata0" instead of directly into "unc_data" so that OUTFIL option works
		udata0 = rot(udata0, -roll, 1, xpiv, ypiv, missing=0, /pivot, cubic=cubic, interp=interp)
		unc_data(0, 0, iout) = udata0
	    end
	    if (qsatpix) then begin
		sdata0 = temporary(sdata0) * 100
		sdata0 = rot(temporary(sdata0), -roll, 1, xpiv, ypiv, missing=0, /pivot, cubic=cubic, interp=interp)
		sdata0 = byte( temporary(sdata0)/100. + 0.99)
		;more than 1% of a saturated pixel moves will cause the 1% pixel to be flagged as saturated
		satpix(0, 0, iout) = sdata0
	    end
	    ;
	    vals = [0,0,roll]
	    if (n_elements(sc) ne 0) then vals = [sc(*,iimg), roll_arr(iimg)]
	    his_index, index_out, iout, 'sun_center', vals
	    his_index, index_out, iout, 'q_roll_corr', progverno		;MDM added 8-Mar-94 - corrected 31-Mar-94
	end

	;--------------------------------------------------------------------------------
	;			Optionally Fill the gap in the OR assembly
	;--------------------------------------------------------------------------------
	if (qfill_gap) then begin
	    interp_or, data_out, st_en_lin, iout, iout, trim_edge=trim_edge, qdebug=qdebug
	    if (quncert) then interp_or, unc_data, st_en_lin, iout, iout, trim_edge=trim_edge
	    if (qsatpix) then interp_or, satpix, st_en_lin, iout, iout, trim_edge=trim_edge
	end

	;--------------------------------------------------------------------------------
	;			Write the data out 
	;--------------------------------------------------------------------------------
	;
	if (qoutfil) then begin
	    if (qfinished) then begin
		sav_sda, outfil, index_out(iout), data_out, append=(1-qfirst_out) or append
		if (quncert) then sav_sda, outfil+'_unc', index_out(iout), udata0, append=(1-qfirst_out)
		if (qsatpix) then sav_sda, outfil+'_sat', index_out(iout), sdata0, append=(1-qfirst_out)
		qfirst_out = 0
		data_out = make_array(nx, ny, nout, type=typout)	;needed to zero out the data array
	    end
	end

	if (keyword_set(q2stop)) then stop
    end
    last_ser_num = ser_num
end
;
end_time = systime(1)
run_time = (end_time-start_time)/60.
print, 'SXT_PREP took: ', run_time, ' minutes to process your request'

if (keyword_set(new_sdc_db)) then set_new_db, /reset		;MDM added 18-May-95
if (keyword_set(new_sfc_db)) then set_new_db, /reset, /leak

if (keyword_set(oride_pnt_chk)) then set_logenv, 'YS_ORIDE_PNT_CHK', ''
if (keyword_set(qstop)) then stop
end

