function sxt_off_axis, index, data, index_out, 				$
		update_index=update_index, vignette_only=vignette_only,	$
		force_energy=force_energy, qstop=qstop
;+
; NAME:
;   sxt_off_axis
; PURPOSE:
;   Correct an SXT image for the X-ray vignette function.
;   Corrected_image = image / Vignette_function
; CALLING SEQUENCE:
;   data_out = sxt_off_axis(index, data, index_out)
;   data_out = sxt_off_axis(index, data, /update_index)
; INPUTS:
;   index	- The index structure for each image
;   data	- The data array (NX x NY x N)
; OUTPUTS:
;   data_out	- The Vignette-corrected image
;   index_out	- The updated index struture (history records appended)
; OPTIONAL KEYWORD INPUTS:
;   update_index- Update the input Index.
;   vignette_only- If set, return the vignette function.
;   force_energy- Two energy solutions are available.  The low-energy
;		  result will by default be applied to all filters except
;		  the Al12 and Be119 filters, which will have the high-
;		  energy result.  Set force_energy=1 to force low-energy
;				  Set force_energy=2 to force high-energy
; OPTIONAL KEYWORD OUTPUTS:
; RESTRICTIONS:
;   This should only be run on background-subtracted data.
; METHOD:
;   Call sxt_vignette to compute the appropriate vignette function.
;   Note:  The calling order to sxt_vignette could use further optimization 
;          to avoid calling sxt_vignette unnecessarily.
; DISCLAIMER:
;   This routine will correct SXT images using either the WSMR1 calibration
;   data for low-energy filters (from Al-K and C-K data) or high-energy
;   (from Al-L data).  These corrections are only approximate and may not be
;   the most appropriate way to treat this problem.  Try IDL> help_vignette to
;   get an idea of the size of the correction.
;
; MODIFICATION HISTORY:
; V1.0   11-jan-94, J. R. Lemen LPARL, Written
;	 20-mar-95, JRL   Commented out an unnecessary call to message
;-

progverno = 1.00*1000

sz = size(index) & typ = sz(1+sz(0))
if typ ne 8 then begin
   message,'Index must be an SXT index structure',/cont
   return,-1
endif

if (n_elements(data) eq 0) and not keyword_set(vignette_only) then begin
   message,'Must supply either data or /vignette_only'
   return,-1
endif

sz = size(data) & typ = sz(1+sz(0))
if typ eq 1 then begin
   message,'You must decompress and background subtract first',/cont
   return,-1
endif

; Set up the output variables
nimg = n_elements(index)
index_out = index
if n_elements(data) ne 0 then begin
  data_out = data			; Will return the same size/type
  nx = n_elements(data(*,0,0))
  ny = n_elements(data(0,*,0))
endif else begin
  nx = max(gt_shape(index,/x))
  ny = max(gt_shape(index,/y))
  data_out = fltarr(nx,ny,nimg)
  typ = 4
endelse
if typ lt 4 then roundup = 0.5 else roundup = 0 

; ------ Determine the optimal order of the images to do the Vignette correction
;*** TBD:  Further optimization needed here.  Use dark_sub as an example.

filtb = gt_filtb(index)
ss1 = where((filtb eq 4) or (filtb eq 5),nhigh)
ss2 = where((filtb ne 4) and (filtb ne 5),nlow)

if (nhigh gt 0) and (nlow gt 0) then ss = [ss1,ss2] else $
	if nhigh gt 0 then ss = ss1 else ss = ss2


; ------ Now Correct each image in the input data cube

prev_case = replicate(-1,6)			; Initialize
qhist = his_exist(index)
energy_str = ['???','Low-energy','High-energy']

for iimg=0,Nimg-1 do begin
    i = ss(iimg)		; do the correction in the optimal order
				;-  to minimize calls to sxt_vignette

    this_case = intarr(6)
    if (gt_filtb(index(i)) eq 4) or (gt_filtb(index(i)) eq 5) then 	$
		this_case(0) = 2 else this_case(0) = 1
    this_case([1,2]) = gt_corner(index(i),/orig)
    this_case([3,4]) = gt_shape(index(i))
    this_case(5)     = gt_res(index(i))

    if (min(this_case-prev_case) ne 0) or (max(this_case-prev_case) ne 0) then begin
	vignette = sxt_vignette(index(i),force_energy)
;	message,'Calling sxt_vignette:  '+energy_str(this_case(0)),/info
    endif

    if keyword_set(vignette_only) then begin
        data_out(0,0,i) = vignette + roundup 
    endif else begin

	doit = 1
	if qhist then begin
	   if index(i).his.qflat_field ne 0 then begin
	      message,string('index(',strtrim(i,2),') has already been Vignette corrected'),/info
	      doit = 0
	   endif
	endif 
	if doit then begin
	  if (n_elements(vignette(*,0)) ne nx) or 	$
	    (n_elements(vignette(0,*)) ne ny) then begin
	    temp = make_array(nx,ny,value=1.)
            temp(0,0) = vignette & vignette = temp & delvarx,temp
	  endif
          data_out(0,0,i) = data(*,*,i) / vignette + roundup
          his_index, index_out, i, 'qflat_field', progverno
	  his_index, index_out, i, 'flat_tech', this_case(0)	; Put in the energy
	endif							; doit
    endelse
    prev_case = this_case
endfor

if keyword_set(qstop) then stop
if keyword_set(update_index) then index = index_out
return, data_out
end
