FUNCTION xrt_eff_area_slmd_fctm, lambda, fw1, fw2, time, $
         cal = cal, $
         index=index, $
         aperture=aperture, prefilter=prefilter, $
         mirror1=mirror1, mirror2=mirror2, $
         filter1=filter1, filter2=filter2, ccdqe=ccdqe, $
         contamination_thickness=contamination_thickness, $
         info = info, message = message, $
         contam_out=contam_out, $
         frac_open=frac_open, fctm_fact=fctm_fact 

; =========================================================================
;+
; PROJECT:
;
;       Solar-B / XRT 
;
; NAME:
;       
;       XRT_EFF_AREA (with FRAC_OPEN keyword for stray light mod. and
;                     with FCTAM_FACT keyword for modified contamination 
;                          layer on analysis filters)
;
; CATEGORY:
;       
;       XRT RESPONSE
;
; PURPOSE:
;       
;       Get the effective area of XRT filters [cm^2]
;       with a wavelength range from 1 to 400 [A].
;
; CALLING SEQUENCE:
;
;       result = XRT_EFF_AREA(lambda, fw1, fw2, time)
;       
; INPUTS:
;       
;       LAMBDA    - (float array) Wave length [A] which you want to get the effective area.
;       FW1       - (long) Filter No. on filter wheel 1.
;       FW2       - (long) Filter No. on filter wheel 2.
;       TIME      - (string) Time when you want to calcurate the XRT effective area,
;                   because XRT effective area influenced by contamination is a function of time.
;                   This time is used to derive the thickness of contaminant.
;                   If you directly give the contamination thickness with CONTAMINATION_THICKNESS
;                   keyword, you should omit this TIME input.
;
; KEYWORDS:
;       
;       CAL        - [Optional input] If set as "cal = 1", the effective area is calculated based on the calibration in Narukage et al. (2011).
;                                     If set as "cal = 2", the effective area is calculated based on the calibration in Narukage et al. (2013).
;                                     Default is "cal = 2" to use the latest calibration result of Narukage et al. (2013).
;       INDEX      - [Optional input] (structure) If set, you can omit the inputs of FW1, FW2 and TIME.
;       CONTAMINATION_THICKNESS - [Optional input] (float)
;                    You can directly give the contamination thickness.
;                    When you use this keyword, you should omit the input of TIME.
;       FRAC_OPEN  - (float) fraction of pre-filter opening (0.0: no opening -- 1.0: fully open)
;       FCTAM_FACT - [Optional] filter contamination enhancement factor (default value=1.0)
;       /INFO      - [Optional] (Boolean) If set, information is shown.
;
; OUTPUTS:
;       
;       return    - (3-dim float array, [lambda, fw1, fw2]) XRT effective area [cm^2].
;       APERTURE   - [Optional output] (float) Aperture area [cm^2] will be returned.
;       PREFILTER  - [Optional output] (float array, [lambda]) Efficiency of pre-filter will be returned.
;       MIRROR1    - [Optional output] (float array, [lambda]) Efficiency of mirror1 will be returned.
;       MIRROR2    - [Optional output] (float array, [lambda]) Efficiency of mirror2 will be returned.
;       CCDQE      - [Optional output] (float array, [lambda]) Efficiency of CCD will be returned.
;       FILTER1    - [Optional output] (float array, [lambda]) Efficiency of analysis filter on FW1 will be returned.
;       FILTER2    - [Optional output] (float array, [lambda]) Efficiency of analysis filter on FW2 will be returned.
;       CONTAM_OUT - [Optional output] (double array, [lambda]) Contamination wavelength dependendy
;
; EXAMPLES:
;      
;       Get effective area of Al-poly filter at 11-Mar-2007 00:55:00 from 1 to 400 A with 0.1 A resolution:
;       IDL> lambda = findgen(3991)/10. + 1.
;       IDL> eff_area = xrt_eff_area(lambda, 1, 0, '11-Mar-2007 00:55:00')
;
; COMMON BLOCKS:
;
;       none 
;
; NOTES:
;
;       filter on filter wheel 1
;         0: open
;         1: thin-Al-poly
;         2: C-poly
;         3: thin-Be
;         4: med-Be
;         5: med-Al
;
;       filter on filter wheel 2
;         0: open
;         1: thin-Al-mesh
;         2: Ti-poly
;         3: G-band (optical)
;         4: thick-Al
;         5: thick-Be
;
;       The detail of calibrated effective area of the Hinode/XRT is described in
;         Narukage et al. 2011, Solar Phys., 269, 169.
;         http://adsabs.harvard.edu/doi/10.1007/s11207-010-9685-2
;       and
;         Narukage et al. 2013, Solar Phys., in press
;         http://adsabs.harvard.edu/doi/10.1007/s11207-013-0368-7
;       These two papers are the reference papers of this program.
;
; CONTACT:
;
;       Comments, feedback, and bug reports regarding this routine may be 
;       directed to this email address: 
;                noriyuki.narukage ~at~ nao.ac.jp
;       
; MODIFICATION HISTORY:
;
progver = 'v2007-May-17' ;--- (N.Narukage (ISAS/JAXA)) Written.
progver = 'v2009-Jul-27' ;--- (N.Narukage (NAOJ)) Updated to consider the contamination on focal-plane analysis filters and CCD.
progver = 'v2011-Feb-17' ;--- (N.Narukage (NAOJ)) Added the information on the reference paper.
progver = 'v2013-Nov-04' ;--- (N.Narukage (NAOJ)) Updated to use the calibration result of Narukage et al. (2013).
;                                                 Added the keyword of "cal" to select the calibration result.
;                                                 Added the warning for a pinhole on the entrance filter opened around 2012-05-09 18:03:52.
;                                                 And modified for the message from the program.
progver = 'v2013-Nov-15' ;--- (N.Narukage (NAOJ)) Bug fix.
;         'v2015-Sep-17' ;--- A.Takeda (MSU) modified to calculate with pre-filter open fraction.
;         'v2020-Jul-01' ;--- A.Takeda (MSU) modified to output as a keyword the wavelength dependency of CCD contamination layer.
;         'v2021-Feb-24' ;--- A.Takeda (MSU) modified contamination layer thickness on analysis filters.
;         'v2023-Aug-14' ;--- A.Takeda (MSU) added print-out of assumed open frac and filter contam factor.
;
;-
; =========================================================================

; --- setting for message -------------------------------------------------

  if not keyword_set(message) then message = ['XRT_EFF_AREA_SLMOD']

; --- read filter config data ---------------------------------------------

  config = xrt_config(cal = cal)

; --- process of option ---------------------------------------------------

  if keyword_set(index) then begin
    time = anytim(index.date_obs, /ecs)
    fw1 = index.ec_fw1
    fw2 = index.ec_fw2
  endif

  if n_elements(fw1) ge 2 or n_elements(fw2) ge 2 or n_elements(time) ge 2 then begin
    fw1  = fw1[0]
    fw2  = fw2[0]
    time = time[0]

    message = [message, '']
    message = [message, '*****  WARNING from XRT_EFF_AREA.PRO  *************************************']
    message = [message, 'The inputed pair of "FW1, FW2 & TIME" or INDEX should not be array.']
    message = [message, 'Then the case of first elements of inputted array is only processed.']
    message = [message, '*************************************  WARNING from XRT_EFF_AREA.PRO  *****']
  endif

; --- calculate eff area --------------------------------------------------

  eff_area = fltarr(n_elements(lambda))
  filter1  = fltarr(n_elements(lambda))
  filter2  = fltarr(n_elements(lambda))

  aperture  = config.aperture.aperture
  prefilter = ( INTERPOL(config.prefilter.TRANSMISSION, config.prefilter.WAVELENGTH, lambda) ) < 1
  mirror1   = ( INTERPOL(config.mirror1.REFLECTION    , config.mirror1.WAVELENGTH  , lambda) ) < 1
  mirror2   = ( INTERPOL(config.mirror2.REFLECTION    , config.mirror2.WAVELENGTH  , lambda) ) < 1
  ccdqe     = ( 10.^INTERPOL(alog10(config.ccd.QE)                , alog10(config.ccd.WAVELENGTH)      , alog10(lambda)) ) < 1.
  
;  if n_elements(contamination_thickness) eq 0 then contamination_thickness = xrt_time2contam(fw1, fw2, time, message = message) > 0.
;---------- modified and added by AkT (24-feb-2021) ---------------
;        add contamination on each filter for testing purpose
  if n_elements(contamination_thickness) eq 0 then $
     contamination_thickness = xrt_time2contam(fw1, fw2, time, ccd=ccd, filter=filter) > 0.
  if not keyword_set(fctm_fact) then fctm_fact=1.0
  filter = filter * fctm_fact
  print,'*** Filter contamnation factor assumed: ',fctm_fact
  contamination_thickness = ccd + filter
;------------------------------------------------------------------    

  _contaminant='DEHP'
  contamination = xrt_calc_att(_contaminant, contamination_thickness, lambda)
;
;------ added by AkT (1-jul-2020) -------------------------------
contam_out=contamination      ; to output wavelength dependancy
;----------------------------------------------------------------    
;
  if keyword_set(time) then temp = ' at ' + anytim(time, /ecs) else temp = ''

  if keyword_set(info) then begin
    print
    print, 'contamination thickness on '+config.filter1[fw1].name+' (FW1), '+config.filter2[fw2].name+' (FW2) & CCD : ' + strtrim(string(contamination_thickness, format='(i)'), 2) + 'A' + temp
    print
  endif

  if total(message eq '-----  NOTE from XRT_EFF_AREA.PRO  ----------------------------------------') eq 0 then begin

    message = [message, '']
    message = [message, '-----  NOTE from XRT_EFF_AREA.PRO  ----------------------------------------']

    if cal eq 1 then begin
      message = [message, 'This result is based on the old calibration (cal1) result']
      message = [message, 'performed by Narukage et al., Solar Phys. 269, 169–236, (2011).']
      message = [message, 'http://adsabs.harvard.edu/doi/10.1007/s11207-010-9685-2']

	endif

    if cal eq 2 then begin
      message = [message, 'This result is based on the latest calibration (cal2) result']
      message = [message, 'performed by Narukage et al., Solar Phys. (2013) in press.']
      message = [message, 'http://adsabs.harvard.edu/doi/10.1007/s11207-013-0368-7']

	endif

	message = [message, '----------------------------------------  NOTE from XRT_EFF_AREA.PRO  -----']

  endif

  if fw2 ne 3 then begin
    filter1  = ( INTERPOL(config.filter1[fw1].TRANSMISSION, config.filter1[fw1].WAVELENGTH, lambda) ) < 1
    filter2  = ( INTERPOL(config.filter2[fw2].TRANSMISSION, config.filter2[fw2].WAVELENGTH, lambda) ) < 1

    eff_area_0 = aperture * prefilter * mirror1 * mirror2 * filter1 * filter2 * ccdqe * contamination
    eff_area_nopf = aperture * mirror1 * mirror2 * filter1 * filter2 * ccdqe * contamination
  endif else eff_area[*] = 0.

  n = where(lambda gt 400)

  if n[0] ne -1 then eff_area[n] = 0.


; --- warning for a pinhole on the entrance filter ----------------------------

  if keyword_set(time) then begin
    if (anytim(time) ge anytim('2012/05/09 18:03:52')) then begin

      message = [message, '']
      message = [message, '*****  WARNING from XRT_EFF_AREA.PRO  *************************************']
      message = [message, 'This result is not reliable after 2012-05-09 18:03:52']
      message = [message, 'because of a calibration shift due to a pinhole on the entrance filter.']
      message = [message, '*************************************  WARNING from XRT_EFF_AREA.PRO  *****']

    endif
  endif


; --- show message ------------------------------------------------------------

  if n_elements(message) ge 2 then begin
    if message[0] eq 'XRT_EFF_AREA' then hprint, [message[1:*], '']
  endif

;******* mix of eff_area functions w/wo pre-filter *******************
;  frac_open = 0.45
if not keyword_set(frac_open) then frac_open=0.00
print,'*** Fraction of Prefilter open area assumed: ',frac_open
eff_area = frac_open * eff_area_nopf + (1-frac_open)* eff_area_0
pref_mod= frac_open + (1-frac_open) * prefilter
;
prefilter=pref_mod   ; return modified prefilter efficiency
;********************************************************************
;
  return, eff_area

END
