; NAME:
;      refsub.pro
;
; PURPOSE:
;      This program performs reference pixel
;      subtraction on NIR detectors having reference
;      pixels. The default action is to fit a smooth
;      polynomial to the reference pixels and to perform the
;      correction using interpolated values. One can override
;      this by setting the keyword simple=1.
;
;      The output depends on whether infile is a FITS file or
;      2D array. If it is a FITS file, refsub creates an
;      output file having the suffix '.rc.fits'. If infile is
;      an array, the array is overwritten with the reference
;      pixel corrected values.
;
; CALLING SEQUENCE:
;       refsub, infile[, sca=sca, plot=0|1, simple=0|1]
;
; INPUTS:
;       infile - The input file. May be either FITS or a 2D array
;      version - An empty string. If version is supplied, the
;                refsub version is returned in this variable
;                and refsub terminates.
;
; KEYWORD PARAMETERS:
;      scaName - Optional string specifying SCA name. If this
;                is not specified, refsub will try to get the
;                sca type from the FITS header. Currently
;                supported sca types are 'H1RG' and 'SB304' and 'H2RG'.
;         plot - Optional switch. Set =1 to show diagnostic plots
;       simple - Optional switch. Set =1 to perform 'simple' reference
;                pixel correction.
;         help - Print a help message.
;
; EXAMPLE
;       Perform reference pixel correction on a FITS file
;       IDL> refsub, 'inputFile.fits'
;
;
; REFERENCE:
;
;       This file has been approved for release by
;       B.J. Rauscher. It contains no proprietary material.
;
; MODIFICATION HISTORY:
;       Written by:  Bernie Rauscher, IDTL, March 27, 2002
;
; Modified by Sungsoo Kim, 09/22/02
;     --- Can receive an array as an input and output.
;
; Modified by Bernie Rauscher, 11/7/02
;     --- Make sca an
;         optional parameter. Try to get this from the image
;         header. This only works for FITS input. You have to
;         specify the sca name on the command line when the input
;         is an array.
;
;     --- Add scatype = SB304
;
; Modified by Bernie Rauscher, 1/21/03
;     --- Add scatype = H2RG
;     --- Add /help command line switch
;     --- Update FITS headers in output files to indicate that
;         refsub has been done.
;     --- Add version command line option. This returns the refsub
;         version and exits. It does not perform reference pixel correction.
;
; Modified by Ernie Morse, IDTL, April 11, 2003 (v1.5)
;		Changed the sca parameter to scaName
;		Added code to extract SCA type from SCA name
;		Modified call to refsub_h2rg to add the SCA name parameter to allow handling
;			of device-specific situations
;		Changed value of refsub_version to 1.5 to reflect changes
;

pro refsub, infile, scaName=scaName, plot=plot, simple=simple, help=help, version=version


	; Set refsub version
	refsub_version = '1.5'; Use this when updating fits headers

	; Handle requests for refsub version
	if (keyword_set(version)) then begin
		version = refsub_version
		return
	endif

	; Check for command line errors
	if (keyword_set(help)) then begin
		stop, 'Usage refsub, fits_file [, sca={H1RG|H2RG|SB304}, plot={0|1}, simple={0|1}, /help, version=version]'
	endif

	; Set defaults
	if (not keyword_set(scaName)) then begin
		get_sca_from_header = 1 ; Try to get sca from header
	endif else begin
		get_sca_from_header = 0 ; sca has been specified on command line.
		                       ; Keep this option for backward
		                       ; compatibility
	endelse
	if (not keyword_set(plot)) then plot=0     ; Default is not to plot reference pixel fits
	if (not keyword_set(simple)) then simple=0 ; Default subtracts a smooth function. Set
	                                          ; this =1 ot subtract a mean reference
	                                          ; pixel value instead

	; Determine if the input is a filename or array.
	if (n_elements(infile) eq 1) then begin
		; Read in the file
		fits_read, infile, data, header

		; Get sca from the header if it is not specified on the
		; command line
		if (get_sca_from_header) then begin
			scaName = sxpar(header, 'detname')
		endif

		; Get size from image header
		; For the time being, this only
		; works for 2D images.
		x_dim = sxpar(header, 'NAXIS1')
		y_dim = sxpar(header, 'NAXIS2')

		; Make destination filename
		_i = RSTRPOS(infile, '.fits')
		if (_i ge 0) then begin
			outfile = strmid(infile, 0, _i)+'.rc.fits' ; The .rc suffix means the file has been
		                                              ; reference pixel corrected.
		endif else begin
			_i = RSTRPOS(infile, '.fit')
			if (_i eq -1) then stop, 'REFSUB ERROR: Illegal FITS filename'
			outfile = strmid(infile, 0, _i)+'.rc.fit'
		endelse

	endif else begin
		; Input is an array

		; For array input, sca type must be specified on the
		; command line.
		if (get_sca_from_header) then begin
			stop, 'REFSUB ERROR: SCA type must be specified on the command line when using array input'
		endif
		sizes = size(infile)
		x_dim = sizes[1]
		y_dim = sizes[2]
		data  = infile
   endelse

	; parse the scaType from the scaName
	nameParts = strsplit(scaName, '-', /extract)
	if (n_elements(nameParts) lt 2) then begin
		stop, 'REFSUB ERROR: Expecting input detector name in format "type-part#-cutoff"'
	endif else begin
		scaType = nameParts[0]
	endelse

	; Make space for reference pixel corrected data
	newData = fltarr(x_dim, y_dim)

	; Handle many different types of SCAs
	case scaType of

		'H1RG': GOTO, CASE_H1RG
		'H2RG': GOTO, CASE_H2RG
		'H1RG_STAMP': GOTO, CASE_H1RG_STAMP
		'SB304': GOTO, CASE_SB304

		else: print, 'Error: SCA not recognized. Enter [H1RG|H1RG_STAMP|SB304]'

	endcase

	; Handle case of H1RG
	CASE_H1RG: refsub_h1rg, data, newData, simple=simple, plot=plot
	goto, DONE

	; Handle case of H2RG
	CASE_H2RG: refsub_h2rg, data, newData, scaName, simple=simple, plot=plot
	goto, DONE

	; Handle case of H1RG subarray
	CASE_H1RG_STAMP: refsub_h1rg_stamp, data, newData, simple=simple, plot=plot
	goto, DONE

	; Handle case of SB304
	CASE_SB304: refsub_sb304, data, newData, simple=simple, plot=0
	goto, DONE


	; Jump to here when finished
	DONE:

	if (n_elements(infile) eq 1) then begin

		; Update the image header
		sxaddhist, 'Processed by refsub_'+refsub_version, header
		if (simple) then begin
			sxaddhist, 'Reference pixel corrected using Maximal Spatial Averaging', $
			 header
		endif else begin
			sxaddhist, 'Reference pixel corrected using Spatial Averaging', $
			 header
		endelse

		; Write the output file
		fits_write, outfile, newData, header

	endif else begin
		infile = newData
	endelse
end
