; $Id: $SSW/proba2/swap/idl/prep/p2sw_ffcorr.pro#1 $
;
; Copyright (c) Trinity College Dublin. All rights reserved.
;+
; NAME:
;	P2SW_FFCORR
;
; PURPOSE:
;	This function applies instrument flat-field correction to 
;       PROBA2/SWAP images.
;
; CATEGORY:
;	PROBA2/SWAP calibration.
;
; CALLING SEQUENCE:
; 
;	Result = P2SW_FFCORR( Index, Image [, CALDIR=caldir, VERSION=version, $
;    	    	    	    	RUNID=runid, /VERBOSE, /LMAT, _EXTRA=ex ])
;
; INPUTS:
;	Index:	FITS header in structure format for PROBA2/SWAP image 
;               to be processed.
;
;	Image:	PROBA2/SWAP image to be processed.
;
; OPTIONAL INPUTS:
;    	CALDIR:  File system pathway to PROBA2/SWAP calibration files. 
;    	    	 DEFAULT: local SSWIDL folder ('$SSW/proba2/swap/caldb').
;
;	VERSION: Master P2SW_PREP code version number for LMAT logging 
;   	    	 and HISTORY tag entries. DEFAULT: null string ('').
;
;    	RUNID:	 Unique processing run identifier for P2SC pipeline 
;   	    	 operations. Used only if LMAT is set. DEFAULT: 0L.
;
; KEYWORD PARAMETERS:
;	VERBOSE: Set this keyword to print run-status information to 
;                standard output
;
;	LMAT:    Set this keyword to enable default reporting mode for 
;                P2SC pipeline operations. Not for use via SSW.
;
; OUTPUTS:
;	This function returns the input image corrected for instrument 
;       defects and optical variations. Input Index structure is 
;   	updated during processing - e.g., HISTORY appended.
;
; PROCEDURE:
;	Input image is divided by the closest-in-time instrument flat 
;       field supplied in the SSW-distributed caldb directory or a 
;   	user-defined directory (optional input CALDIR).
;
; MODIFICATION HISTORY:
; 	Written by:	D. Shaun Bloomfield, 24-Jan-2009.
;	Apr 2009	Added IDL-format description.
;	Jun 2009	Added ROB calls to send2lmat.pro for logging.
;   	    	    	Moved FITS history updating into sub-routines.
;   	    	    	Added option to supply calibration file dir.
;   	Jul 2009    	Added handling of sub-fielded images.
;	Aug 2009    	Added rebinning of native resolution 
;   	    	    	  calibration files for rebinned images.
;   	May 2010    	Finalized IDL-format description.
;       Apr 2012        Fixed error that could cause flat-field
;   	    	    	  to be incorrectly int scaled. (dbs)
;-

FUNCTION p2sw_ffcorr, index, image, $
    	    	    	caldir=caldir, version=version, runid=runid, $
			verbose=verbose, lmat=lmat, _extra=ex

    prognam = 'p2sw_ffcorr.pro'
    delim = get_delim()

    ;---  Check keyword inputs and set keyword-dependencies
    IF KEYWORD_SET(caldir) THEN caldir = caldir ELSE caldir = STRCOMPRESS(GETENV('SSW'), /remove_all) + '/proba2/swap/caldb'
    IF KEYWORD_SET(version) THEN version = version ELSE version = ''
    IF KEYWORD_SET(runid) THEN runid = LONG(runid) ELSE runid = 0
    verbose = KEYWORD_SET(verbose)
    lmat = KEYWORD_SET(lmat)
    
    ;---  Check for APS detector capture mode
    mode = STRLOWCASE( index.cap_mode )
    
    ;---  Check for most recent flat-field response correction
    flat_files = FILE_SEARCH( caldir+'/swap_flat'+mode+'_????????_??????.fits', COUNT=flat_cnt )
    
    image1 = image
    IF (flat_cnt GT 0) THEN BEGIN
    	
    	flat_tdiff = ANYTIM( index.DATE_OBS ) - $
	    	     ANYTIM( FILE2TIME( flat_files ) )
	flat_older = WHERE( flat_tdiff GT 0., n_flat_older )
    	IF (n_flat_older GT 0) THEN BEGIN
    	    flat_valid = flat_files[ ( REVERSE(flat_older) )[0] ]
    	    flat_used = ( REVERSE( STRSPLIT( flat_valid, delim, /EXTRACT ) ) )[0]
    	ENDIF ELSE BEGIN
    	    flat_valid = flat_files[0]
    	    flat_used = ( REVERSE( STRSPLIT( flat_valid, delim, /EXTRACT ) ) )[0]
    	    
    	    err_num = 4218L
    	    err_msg = 'No '+STRUPCASE(mode)+' flat field FITS files older than image - using '+flat_used
    	    IF ~(lmat) THEN BEGIN
    	    	IF (verbose) THEN MESSAGE, '** '+err_msg+' **', /CONTINUE
    	    ENDIF ELSE SEND2LMAT, 'SWBSDG', version, runid, err_msg, err_num, prognam+', line: ', '/p2sc/temp/swbsdg'
	    
    	ENDELSE
	
	;---  Read in flat-field response image
    	MREADFITS, flat_valid, flat_ind, flat_tmp, /SILENT, _EXTRA=ex
	;---  Embed detector sub-field region of interest in array of 1's
	;---  Ensures that out-of-sub-field pixels remain uncorrected (i.e., divided by unity)
	flat_img = FLTARR( index.naxis1, index.naxis2 )+1
    	;---  Check whether or not 2x2 binning was applied onboard
    	IF ( STRMID( STRUPCASE( index.rebin ), 0, 2 ) EQ 'ON' ) THEN BEGIN
	    sub_xr = 1+index.last_col-index.firstcol
	    sub_yr = 1+index.last_row-index.firstrow
	    flat_img[ index.firstcol-1:index.last_col-1, index.firstrow-1:index.last_row-1 ] = $
	    	REBIN( REBIN( flat_tmp[ index.firstcol-1:index.last_col-1, index.firstrow-1:index.last_row-1 ], $
		    sub_xr/2, sub_yr/2 ), sub_xr, sub_yr, /SAMPLE )
	ENDIF ELSE flat_img[ index.firstcol-1:index.last_col-1, index.firstrow-1:index.last_row-1 ] = $
	    	    flat_tmp[ index.firstcol-1:index.last_col-1, index.firstrow-1:index.last_row-1 ]
	    
	
	;---  Divide image by flat-field response
        image1 /= flat_img
	
    	;---  Set HISTORY update text
;    	tagval = STRUPCASE(mode)+' flat-field response correction applied using '+flat_used
    	tagval = 'Flat-field: '+flat_used
	;---  Report if requested
    	IF (verbose) THEN MESSAGE, 'HISTORY record updated:  '+tagval, /CONTINUE
    	;---  Add update text into HISTORY field of index structure
    	UPDATE_HISTORY, index, tagval, CALLER='P2SW_FFCORR '+version
	
    ;---  If no flat-field response files then report ERROR
    ENDIF ELSE BEGIN
    	
    	err_num = 4217L
    	err_msg = 'No '+STRUPCASE(mode)+' flat field FITS files found in '+caldir
    	IF ~(lmat) THEN BEGIN
           MESSAGE, '** '+err_msg+' **', /CONTINUE
	ENDIF ELSE SEND2LMAT, 'SWBSDG', version, runid, err_msg, err_num, prognam+', line: ', '/p2sc/temp/swbsdg'
	
	RETURN, err_msg
	
    ENDELSE
    
    RETURN, image1
    
END
