function IRIS_PREP_GET_BACK2, index, version, bg_dir=sswdata, history=hist

;+
; NAME:
;       iris_prep_get_back2()
;
; PURPOSE:
;       A function to estimate the FUV spectrograph stray light
;       background image.  A normalized background image is loaded and
;       scaled based on the telescope pointing, exposure time, and binning.
;
;       This function uses the updated (Version 2) calibration:
;       The background image in the calibration files is now derived from
;       multiple background calibrations.
;       The pointing-dependency of the background count rate is estimated
;       using Zernike polynomials that were fitted to a range of calibration
;       mosaics (one polynomial per filter, located in $SSWDB).
;       Temporal changes of the background are estimated using a 5-parameter
;       polynomial adjustment fitted to individual background calibrations.
;       If a calibration after DATE_OBS is available, a linear interpolation
;       is performed between the nearest calibrations before & after DATE_OBS.
;
; CALLING SEQUENCE:
;       image = iris_prep_get_back2(index)
;
; INPUTS:
;       index - An IRIS FUV spectrograph image index structure for
;               level 1 or 1.5 data.
;
; KEYWORD INPUTS:
;       bg_dir = string. Directory containing background data,
;                        Default: '$SSWDB/iris/data'
;
; OUTPUTS:
;       Returns an array containing the estimate of the stray light image. 
;
; OPTIONAL OUTPUTS:
;       version	- A string of the form 2AYYYYMMDD_HHMMSS
;	          (saved as a LONG in the FITS keyword IPRPBVER by iris_prep)
;                 The leading digit "2" means FUV background cal. version 2
;                 If only one cal. available (typically before T_OBS):
;                 -> A=0 and YYYYMMDD_HHMMSS=date of the calibration used.
;                 If cals. available before and after T_OBS
;                 -> A=1 and YYYYMMDD_HHMMSS=date from T_OBS
;
; KEYWORD OUTPUTS:
;       history = string. History line for iris_prep
;
; COMMON BLOCKS:
;       IRIS_PREP_BACK_CB2
;
; PROCEDURES USED:
;       IRIS_BACK2_FUNC, which calls ZERNIKE_FRIN
;
; COMMENTS:
;       Function must be given one index at a time, images should be
;       dark subtracted, but not yet flat fielded.
;
; EXAMPLES:
;          IDL> image = iris_get_back(index)
;
; MODIFICATION HISTORY:
;       Started 2013-Nov-14 by Sarah A. Jaeggli, Montana State University
;		Minor SSW tweaks 2013-Dec-03 by P. Boerner, LMSAL
;		Moved from iris_get_back to iris_prep_get_back 2013-Dec-13 PB
;       2022-08-10 RPT changing calibration files location
;       2024-06-26 JPW Major background calibration update (back -> back2)
;       2024-07-02 JPW Added additional sets of 5-param Zernikes to adjust for
;                      spatial variation of the intensity in the "notch"
;       2024-08-27 JPW changed output in "version" and added "history" keyword
;       2024-09-03 RPT tightened the 'linear interpolation' history
;       string to fit.
;       2025-08-22 RPT in the non inter case (data time is after most
;       recent FUV BG file), also adjusting the HISTORY snippet to
;       fit. 
;-

common IRIS_PREP_BACK_CB2, bg_img1, bg_head1, ver_str1, bg_img2, bg_head2, ver_str2, $
                           all_ver_str, all_ver_tai, zdata

; Check if index is a structure
if N_TAGS(index) eq 0 then begin
	print, 'This is not a header structure, exiting...'
	return, 0
endif

;check if image is FUV
if index[0].img_path ne 'FUV' then begin
	print, 'This is not FUV data, exiting...'
	return, 0
endif

; Calibration data directory
if n_elements(sswdata) ne 1 then $
   sswdata = CONCAT_DIR('$SSWDB','iris/data')

;binning
ybin=float(index[0].sumspat)
xbin=float(index[0].sumsptrl)

; absolute time of observation
taiobs= ANYTIM2TAI(index[0].t_obs)

; Check to see if the common block is populated; if not, load the list of
; available background files
if N_ELEMENTS(all_ver_str) eq 0 then begin
	backfiles = FILE_SEARCH(CONCAT_DIR(sswdata, '*FUV_background2*.fits'))
	if backfiles[0] eq '' then begin
		PRINT, 'IRIS_PREP_GET_BACK2: No background file found!'
		RETURN, FLTARR(4144/xbin, 1096/ybin)
	endif
	all_ver_str = STRMID(FILE_BASENAME(backfiles), 0, 15)
        ; eliminate duplicate dates:
        all_ver_str = all_ver_str[uniq(all_ver_str)]
	all_ver_tai = ANYTIM2TAI(FILE2TIME(all_ver_str))
	ver_str1 = '00000000_000000'
	ver_str2 = '00000000_000000'
endif

; Check to see whether the proper background image(s) are loaded; if not, load them
; Updated background uses two images, if available, one before, one after taiobs
taidiff = taiobs - all_ver_tai
w1 = WHERE(taidiff ge 0d0,n1)   ; all cals before taiobs
if n1 gt 0 then i_addr1 = w1[WHERE(taidiff[w1] eq min(taidiff[w1]))]
w2 = WHERE(taidiff lt 0d0,n2)   ; all cals after taiobs
if n2 gt 0 then i_addr2 = w2[WHERE(taidiff[w2] eq max(taidiff[w2]))]

if n1 gt 0 and n2 gt 0 then twocal=1 else twocal=0   ; set flag if cals before & after
if n1 eq 0 then i_addr1=i_addr2                      ; if only cal after, make it cal_1

; check if cal_1 is loaded
use_ver = all_ver_str[i_addr1[0]]
if ver_str1 ne use_ver then begin
	bg_file = file_search(CONCAT_DIR(sswdata, use_ver + '_FUV_background2*.fits'))
        bg_file = bg_file[n_elements(bg_file)-1]     ; should be latest if more than one
	MREADFITS, bg_file, bg_head1, bg_img1
	ver_str1 = use_ver
endif
; if twocal set, check whether cal_2 is loaded
if twocal then begin
  use_ver = all_ver_str[i_addr2[0]]
  if ver_str2 ne use_ver then begin
	bg_file = file_search(CONCAT_DIR(sswdata, use_ver + '_FUV_background2*.fits'))
        bg_file = bg_file[n_elements(bg_file)-1]     ; should be latest if more than one
	MREADFITS, bg_file, bg_head2, bg_img2
	ver_str2 = use_ver
  endif
endif

; check to see if static Zernike polynomials are loaded in zdata, if not, load them
if size(zdata,/type) ne 8 then begin
   zfil = bg_head1.zer_file
   zfil = CONCAT_DIR(sswdata,zfil)
   if file_test(zfil) then restgenx,zdata,file=zfil $
   else begin
      PRINT, 'IRIS_PREP_GET_BACK2: file '+zfil+' not found!'
      RETURN, FLTARR(4144/xbin, 1096/ybin)
   endelse
endif

; scale first background
cfac = IRIS_BACK2_FUNC(index[0],bg_head1,zdata,blev=clev)        ; scale info reg. area
nfac = IRIS_BACK2_FUNC(index[0],bg_head1,zdata,blev=nlev,/notch) ; scale info notch area
afac = (clev*cfac-nlev*nfac)/(clev-nlev)                         ; scalefact. above nlev
; scale background with two different slopes: nfac at lower intensities, afac at higher
back1 = (bg_img1<nlev)*nfac + ((bg_img1>nlev)-nlev)*afac

if twocal then begin
   ; scale second background
   cfac = IRIS_BACK2_FUNC(index[0],bg_head2,zdata,blev=clev)
   nfac = IRIS_BACK2_FUNC(index[0],bg_head2,zdata,blev=nlev,/notch)
   afac = (clev*cfac-nlev*nfac)/(clev-nlev)
   ; scale background with two different slopes at lower and higher intensities
   back2 = (bg_img2<nlev)*nfac + ((bg_img2>nlev)-nlev)*afac

   ; linearly interpolate between two background images
   tdif1 = abs(ANYTIM2TAI(bg_head1.date_obs) - taiobs)
   tdif2 = abs(ANYTIM2TAI(bg_head2.date_obs) - taiobs)
   back  = back1*(tdif2/(tdif1+tdif2)) + back2*(tdif1/(tdif1+tdif2))  ; linear comb.
   version = '21'+time2file(index[0].t_obs,/sec)
   hist = 'FUV backgr. V2 subtracted, lin.i.p. betw. ' $
          +strmid(ver_str1,0,8)+' & '+strmid(ver_str2,0,8)
endif else begin
   ; just use nearest cal
   back = back1
   version = '20'+ver_str1
   hist = 'FUV background V2 subtracted, using cal. at '+ver_str1
   ;hist = 'FUV background version 2 subtracted, using cal. at '+ver_str1
endelse

;account for binning
nx = (size(bg_img1))[1]
ny = (size(bg_img1))[2]
back = rebin(back, nx/xbin, ny/ybin, /SAMPLE)*xbin*ybin

return, back

end
