;+
; NAME:
;       iris_back2_func()
;
; PURPOSE:
;       A function to calculate a "limb-darkening" function based on
;       Zernike polynomials that were fit to IRIS calibration mosaics.
;       The Zernikes are assembled from two sources: static 400-terms
;       in a .geny file (one polynomial per FW position) and a 5-term
;       component that is fitted to each background calibration.
;
;       For use in iris_prep_get_back2.
;
; CALLING SEQUENCE:
;       i_fact = iris_back2_func(index, bg_head, zdata)
;
; INPUTS:
;       index = index structure of image to calculate background level for
;
;       bg_head : fits index structure of calibration file
;       zdata   : structure with static Zernike polynomial terms
;                 as found in $SSWDB/iris/data/fuvback_zernike_*.geny
;                 
; KEYWORD INPUTS:
;       /notch : causes program to return intensity scale factor for notch
;                as found in ZN instead of ZC keywords in calibration file.
;
; OUTPUTS:
;       i_fact = intensity scale factor for CCD background image.
;                Properly scaled for exposure time, but NOT for binning!
;
; KEYWORD OUTPUTS:
;       blevel = typical intensity value for which scale factor applies.
;                Values are different with, w/out /notch and allow different
;                intensity scaling for low and high background portions of
;                CCD background image (see iris_prep_get_back2.pro)
;
; COMMON BLOCKS:
;       None
;
; PROCEDURES USED:
;       zernike_frin
;
; RESTRICTIONS:
;       Only a single index at a time!
;
; MODIFICATION HISTORY:
;       2024-06-26 JPW
;       2024-07-02 JPW added /notch and blevel keywords
;-

function iris_back2_func, index, bh, zdat, blevel=blev, notch=notch

; relevant pointing information
x0   = index.crval3    ; Version 2 background requires crval3 NOT xcen!
y0   = index.crval2    ; Version 2 background requires crval2 NOT ycen!
roll = index.sat_rot   ; roll angle from solar north

;rotate coordinates so they are w.r.t roll
x = x0*cos(roll/!radeg) - y0*sin(roll/!radeg)
y = x0*sin(roll/!radeg) + y0*cos(roll/!radeg)

; get the proper Zernikes for this filter wheel position
case index[0].ifwpos of
   31 : begin
          z400 = zdat.zc31
          zc = [bh.zc31_0,bh.zc31_1,bh.zc31_2,bh.zc31_3,bh.zc31_4]
          zn = [bh.zn31_0,bh.zn31_1,bh.zn31_2,bh.zn31_3,bh.zn31_4]
          bc = bh.bc31
          bn = bh.bn31
        end
   61 : begin
          z400 = zdat.zc61
          zc = [bh.zc61_0,bh.zc61_1,bh.zc61_2,bh.zc61_3,bh.zc61_4]
          zn = [bh.zn61_0,bh.zn61_1,bh.zn61_2,bh.zn61_3,bh.zn61_4]
          bc = bh.bc61
          bn = bh.bn61
        end
   91 : begin
          z400 = zdat.zc91
          zc = [bh.zc91_0,bh.zc91_1,bh.zc91_2,bh.zc91_3,bh.zc91_4]
          zn = [bh.zn91_0,bh.zn91_1,bh.zn91_2,bh.zn91_3,bh.zn91_4]
          bc = bh.bc91
          bn = bh.bn91
        end
  121 : begin
          z400 = zdat.zc121
          zc = [bh.zc121_0,bh.zc121_1,bh.zc121_2,bh.zc121_3,bh.zc121_4]
          zn = [bh.zn121_0,bh.zn121_1,bh.zn121_2,bh.zn121_3,bh.zn121_4]
          bc = bh.bc121
          bn = bh.bn121
        end
 else : begin
          print,'No FUV background available for this FW position'
          blev = 1.
          return,0.0
        end
endcase

if keyword_set(notch) then begin
   z5   = zn
   blev = bn
endif else begin
   z5   = zc
   blev = bc
endelse

; adjust static Zernikes (z400) with 5-parameter fit to background cal
z400      *= z5[4]        ; z5[4] is scale factor for z400
z400[0:3] += z5[0:3]      ; z5[0:3] are adjustments for (scaled) z400[0:3]

; derive pointing normalized to rsun_obs*zdat.rnorm in polar coordinates
r = sqrt(x*x + y*y) / (index.rsun_obs*zdat.rnorm)
p = atan(-x,y)

; calculate Zernike terms for given pointing and derive model scale factor
zz = zernike_frin(r,p,nl=zdat.nlmax)  ; 400 Zernike terms at r,p
zz = reform(zz,1,n_elements(zz))
iscal = zz # z400                     ; scale factor for background image

; apply exposure time
iscal *= index.exptime

return, iscal[0]

end
