; $Id: $SSW/proba2/swap/idl/prep/p2sw_pixrep.pro#1 $
;
; Copyright (c) Trinity College Dublin. All rights reserved.
;+
; NAME:
;	P2SW_PIXREP
;
; PURPOSE:
;	This function reinstates onboard cosmic ray replaced pixels and 
;   	saturated pixels in PROBA2/SWAP images.
;
; CATEGORY:
;	PROBA2/SWAP calibration.
;
; CALLING SEQUENCE:
; 
;	Result = P2SW_PIXREP( Index, Image, Fname [, CALDIR=caldir, $
;    	    	    	    	VERSION=version, RUNID=runid, /NO_PIXLIST, $
;    	    	    	    	/NO_SATREP, /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.
;
;	Fname:	FITS Filename of 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.
;
;    	RUNID:	 Unique processing run identifier for P2SC pipeline 
;   	    	 operations. Used only if LMAT is set.
;
; KEYWORD PARAMETERS:
;	NO_PIXLIST: Set this keyword to skip possible application of  
;                   pixel replacement from FITS extension table.
;
;       NO_SATREP:  Set this keyword to skip replacement of pixels above
;                   predetermined saturation levels.
;
;	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 with the missing pixels 
;       contained in the input image FITS extension replaced by their 
;       local 3x3 pixel median value. Pixels identified as saturated 
;   	are replaced with 4400 using the closest-in-time saturation 
;   	map correction FITS file supplied in the SSW-distributed caldb 
;   	directory. Correction is not applied if image was binned 2x2
;   	onboard. Input Index structure is updated during processing
;   	- e.g., HISTORY appended.
;
; PROCEDURE:
;	Input images have their FITS file checked for the existence 
;       of an extension containing a list of missing pixels which are 
;       replaced by their local 3x3 pixel median values. A further 
;   	saturated pixel replacement is carried out using the 
;       closest-in-time observing mode specific saturation FITS file 
;       supplied in the SSW-distributed caldb directory or a 
;   	user-defined directory (optional input CALDIR). Pixels are 
;       identified as being within the saturation regime if their 
;       values lie above 0.95 x (saturation frame value) with these 
;       pixels being replaced by 4400.
;
; 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.
;   	    	    	Added optional call to check for missing pixel 
;   	    	    	  list in FITS extension.
;       Oct 2009        Changed handling of pixel list FITS extension.
;   	Mar 2010    	Fixed filename call for FITS extension reading.
;   	    	    	Fixed handling of NO_PIXLIST keyword.
;   	May 2010    	Finalized IDL-format description.
;       Apr 2013        Added optional call to skip saturation replacement (dbs)
;-

FUNCTION p2sw_pixrep, index, image, fname, $
                      caldir=caldir, version=version, runid=runid, $
                      no_pixlist=no_pixlist, verbose=verbose, $
                      no_satrep = no_satrep, lmat=lmat, _extra=ex

    prognam = 'p2sw_pixrep.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
    no_pixlist = KEYWORD_SET(no_pixlist)
    no_satrep = KEYWORD_SET(no_satrep)
    verbose = KEYWORD_SET(verbose)
    lmat = KEYWORD_SET(lmat)
    
    ;---  Get filename for LMAT messaging
    IF KEYWORD_SET(lmat) THEN fn = index[0].filename
    
    image1 = image
    
    ;---  Check whether to attempt check for missing pixel list
    IF ~(no_pixlist) THEN BEGIN
    	
    	;---  Check for FITS extension
    	IF ( index.extend NE 0 ) THEN BEGIN
    	    
	    ;---  Re-read FITS file to extract FITS extension #1
    	    img_ext = READFITS( fname, himg_ext, /EXTEN, /SILENT )
	    ;---  If extension information exists then process
    	    IF ( img_ext[0] NE -1 ) THEN BEGIN
	    	
		;---  img_ext is a 3xN element array containing: 
		;---    img_ext[0, *] - the pixel x coordinates, 
		;---    img_ext[1, *] - the pixel y coordinates, 
		;---    img_ext[2, *] - the pixel original values
		
	    	err_num = 2202L
	    	err_msg = 'Expected FITS extension exists in Level-0 file'
	    	IF ~(lmat) THEN BEGIN
	    	    IF (verbose) THEN MESSAGE, '** '+err_msg+' **', /CONTINUE
	    	ENDIF ELSE SEND2LMAT, 'SWBSDG', version, runid, err_msg + ' for file: ' + fn, err_num, prognam+', line: ', '/p2sc/temp/swbsdg'
	    	
		;---  Convert image extension header into structured index
		ind_ext = FITSHEAD2STRUCT( himg_ext )
		
		;---  Determine number of missing pixel indices
	    	n_mis_pix = ind_ext.naxis2
		;---  Replace each onboard-corrected pixel with its original value
	    	FOR i = 0, n_mis_pix-1 DO image1[ img_ext[0, i], img_ext[1, i] ] = img_ext[2, i]
    	    	
		;---  Set HISTORY update text
;    	    	tagval_a = STRING('Replaced ', n_mis_pix, ' onboard-corrected pixels with original values', FORMAT='(a,i7,a)')
    	    	tagval_a = STRING('Replaced ', n_mis_pix, ' pixels with preprocessed values', FORMAT='(a,i4,a)')
    	    	;---  Report if requested
		IF (verbose) THEN MESSAGE, 'HISTORY record updated:  '+tagval_a, /CONTINUE
    	    	;---  Add update text into HISTORY field of index structure
		UPDATE_HISTORY, index, tagval_a, CALLER='P2SW_PIXREP '+version
	    	
	    ;---  If no missing pixel indices in extension then report ERROR
    	    ENDIF ELSE BEGIN
    	    	
    	    	err_num = 3201L
    	    	err_msg = 'No missing pixel indices in expected FITS extension'
    	    	IF ~(lmat) THEN BEGIN
	    	    IF (verbose) THEN MESSAGE, '** '+err_msg+' **', /CONTINUE
	    	ENDIF ELSE SEND2LMAT, 'SWBSDG', version, runid, err_msg + ' for file: ' + fn, err_num, prognam+', line: ', '/p2sc/temp/swbsdg'
	    	
    	    ENDELSE
	    
	ENDIF
	
     ENDIF ELSE IF (verbose) THEN PRINT, '** No onboard cosmic ray list correction applied. **'

    
    image2 = image1

    IF ~(no_satrep) THEN BEGIN
       
       ;---  Check whether or not 2x2 binning was applied onboard
       IF ( STRMID( STRUPCASE( index.rebin ), 0, 2 ) NE 'ON' ) THEN BEGIN
    	
    	  ;---  Check for APS-CMOS detector capture mode
          mode = STRLOWCASE( index.cap_mode )
    	  ;---  Check for most recent saturation level map
          sat_files = FILE_SEARCH( caldir+'/swap_sat'+mode+'_????????_??????.fits', COUNT=sat_cnt )
          
          IF (sat_cnt GT 0) THEN BEGIN
             
             sat_tdiff = ANYTIM( index.DATE_OBS ) - $
                         ANYTIM( FILE2TIME( sat_files ) )
             sat_older = WHERE( sat_tdiff GT 0., n_sat_older )
             IF (n_sat_older GT 0) THEN BEGIN
                sat_valid = sat_files[ ( REVERSE(sat_older) )[0] ]
                sat_used = ( REVERSE( STRSPLIT( sat_valid, delim, /EXTRACT ) ) )[0]
             ENDIF ELSE BEGIN
                sat_valid = sat_files[0]
                sat_used = ( REVERSE( STRSPLIT( sat_valid, delim, /EXTRACT ) ) )[0]
                
                err_num = 4210L
                err_msg = 'No '+STRUPCASE(mode)+' saturation level FITS files older than image - using '+sat_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 saturation level image
             MREADFITS, sat_valid, sat_ind, sat_tmp, /SILENT, _EXTRA=ex
	     ;---  Embed detector sub-field region of interest in array of 5500's
	     ;---  Ensures that no out-of-sub-field pixels can have a value above 0.95*5500
             sat_img = INTARR( index.naxis1, index.naxis2 )+5500
             sat_img[ index.firstcol-1:index.last_col-1, index.firstrow-1:index.last_row-1 ] = $
                sat_tmp[ index.firstcol-1:index.last_col-1, index.firstrow-1:index.last_row-1 ]
             
             sat_pix = WHERE( image2 GE (0.95*sat_img), n_sat_pix )
             IF (n_sat_pix GT 0) THEN image2[sat_pix] = 4400
             
    	     ;---  Set HISTORY update text
;    	     tagval_c = STRING('Replaced ', n_sat_pix, ' saturated pixels (values above those in '+sat_used+') with 4400',  FORMAT='(a,i7,a)')
             tagval_c = 'Replaced wrt '+sat_used
	     ;---  Report if requested
             IF (verbose) THEN MESSAGE, 'HISTORY record updated:  '+tagval_c, /CONTINUE
    	     ;---  Add update text into HISTORY field of index structure
             UPDATE_HISTORY, index, tagval_c, CALLER='P2SW_PIXREP '+version
	    
    	  ;---  If no saturation level map files then report ERROR
          ENDIF ELSE BEGIN
    	    
             err_num = 4209L
             err_msg = 'No '+STRUPCASE(mode)+' saturation level 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
	
       ;---  If 2x2 binning was applied onboard then skip saturation map correction
       ENDIF ELSE BEGIN
    
          IF (verbose) THEN MESSAGE, '** No saturation correction applied due to onboard binning **', /CONTINUE
          
       ENDELSE
     ENDIF ELSE IF (verbose) THEN PRINT, '** No saturation correction applied. **'
    
    RETURN, image2
    
END
