;pro Return_RefPix_2RG
;
;PURPOSE:
; To return either a set of reference pixel averages or a frame in
; which the reference pixel values have been subtracted from the
; science pixel values.
;
; CALLING SEQUENCE:
;       Ref=Return_RefPix_2RG(FitsFileNameOrDataCube, MODE)
;
; INPUTS:
;       FitsFileNameOrFrame -
;	MODE = 0 - The name of the fits file containing the data cube from
;		   which the reference columns should be extracted
;	MODE = 1 - A frame of pixels
;	MODE = 2 - A cube of pixels
;	MODE = 3 - A ramp for one pixel
;
; OUTPUTS:
;	MODE = 0 - The output will be a 2xNaxis2xNaxi3 data cube called
;		   RefColSmooth consisting of the reference pixels on the
;		   left -  RefColSmooth(0,*,*) and
;		   right - RefColSmooth(1,*,*)
;	MODE = 1 - The output will be a single Naxis1xNaxis2 frame that
;		   is the inital data minus the reference pixels
;	MODE = 2 - The output will be an Naxis1xNaxis2xNaxis3 cube that
;		   is the inital data minus the reference pixels.
;	MODE = 3 - The output will be the input ramp with the average of the
;			   reference pixels in that same row subtracted.
;
; KEYWORD PARAMETERS:
;       fwindow       - The size of the filter window.
;       order         - Filter order, see the SAVGOL help page
;       degree        - Filter degree, see the SAVGOL help page
;       plot          - Set this =1 to plot the fits
;       simple        - Set this =1 for Maximal Spatial Averaging
;                       (subtract a median reference pixel)
;
;       verbose       - Set this =1 for verbose mode.
;
;
; EXAMPLE
;        IDL> fits_read, 'theImage.fits', myData, myHeader
;        IDL> myNewDate = fltarr(4096, 4096)
;        IDL> refsub_h4rg, myData, myNewData
;
; Code borrowed from Don Figer, Ernie Morse, B.J. Rauscher and others at STSCI
;
;*************************************************************************
Function Return_RefPix_2rg, FitsFileNameOrFrame, Mode, TvFlag = TvFlag, $
	 Date=Date, FWindow = FWindow, $
	 Order = Order, Degree = Degree, Row = Row, Col = Col, Ramp=Ramp

  If N_Elements(fwindow) eq 0 then fwindow = 64  ; 64 pixels for smoothing
  If N_Elements(order)   eq 0 then order  = 0    ; Use zero to smooth
  If N_Elements(degree)  eq 0 then degree = 3    ; Three seems reasonable

  Common KeyParams, KeyStr

  ;Capacitance factor for reference pixels seems to be different for ASIC/LEACH
  If KeyStr.Electronics eq 0 then CFactor = 1.25 else CFactor = 1

  ;**********************************************MODE 0
  Case Mode of
    0: begin
      ;Read In only the reference pixels. Do not use the first reference
      ;pixel on each side. HAWAII-2rg works best like this.

	  ;Right now the LEACH electronics have a bogus column 0 and
	  ;column 1020 is science data
	  If KeyStr.Electronics eq 0 then begin
        Fits_Read_DataCube, FitsFileNameOrFrame, RefPixLeft, $
	      XStart = 1, XStop = 3, $
   	      YStart = 0, YStop = KeyStr.Naxis2-1

        Fits_Read_DataCube, FitsFileNameOrFrame, RefPixRight, $
          XStart = KeyStr.Naxis1-4, XStop = KeyStr.Naxis1-2, $
          YStart = 0, YStop = KeyStr.Naxis2-1
	  EndIf Else Begin
	    Fits_Read_DataCube, FitsFileNameOrFrame, RefPixLeft, $
	      XStart = 1, XStop = 3, $
   	      YStart = 0, YStop = KeyStr.Naxis2-1

        Fits_Read_DataCube, FitsFileNameOrFrame, RefPixRight, $
          XStart = KeyStr.Naxis1-3, XStop = KeyStr.Naxis1-1, $
          YStart = 0, YStop = KeyStr.Naxis2-1

	  EndElse

      MeanRefColL = Avg(RefPixLeft,0)
      MeanRefColR = Avg(RefPixRight,0)
      SmooRefColL = fltarr(KeyStr.Naxis2, KeyStr.Naxis3) ; Smooth vector on left
      SmooRefColR = fltarr(KeyStr.Naxis2, KeyStr.Naxis3) ; Smooth vector on right
      SavgolFilter = savgol(FWindow, FWindow, Order, Degree)

      ;Go through the reads and smooth the reference pixels for each
      For ReadNum =0, KeyStr.Naxis3-1 do begin
        ;Form Arrays for filtering and subtraction
        SmooRefColL[4:KeyStr.Naxis1-5, ReadNum] = $
	  convol(MeanRefColL(4:KeyStr.Naxis1-5, ReadNum), SavgolFilter, $
	       /edge_truncate)
        SmooRefColR[4:KeyStr.Naxis1-5, ReadNum] = $
	  convol(MeanRefColR(4:KeyStr.Naxis1-5, ReadNum), SavgolFilter, $
	       /edge_truncate)
      EndFor
      ;Add in the capacitance factor
      SmooRefColL = SmooRefColL*CFactor
      SmooRefColR = SmooRefColR*CFactor

      ;Return the reference pixel arrays as well as place them in the KeyStr
      If (Where(Stregex(Tag_Names(KeyStr), 'LEFTREFPIX', /boolean) eq 1))[0] $
      eq -1 then begin
        KeyStr = Create_Struct(KeyStr, 'LeftRefPix', SmooRefColL, $
				 'RightRefPix', SmooRefColR)
      EndIf Else Begin
        KeyStr.LeftRefPix  = SmooRefColL
        KeyStr.RightRefPix = SmooRefColR
      EndElse

      RefPixSmooth = Fltarr(2,KeyStr.Naxis2, KeyStr.Naxis3)
      RefPixSmooth(0,*,*) = SmooRefColL
      RefPixSmooth(1,*,*) = SmooRefColR

      return, RefPixSmooth

   End
   1: begin
      ;Get the average of the reference pixels on the left and right
      Frame    = FitsFileNameOrFrame
      OutFrame = FitsFileNameOrFrame
      If KeyStr.Electronics eq 0 then begin
         MeanRefColL = Avg(Frame(1:3,*),0)
         MeanRefColR = Avg(Frame(KeyStr.Naxis1-4:KeyStr.Naxis1-2,*),0)
      EndIf Else Begin
		 MeanRefColL = Avg(Frame(1:3,*),0)
         MeanRefColR = Avg(Frame(KeyStr.Naxis1-3:KeyStr.Naxis1-1,*),0)
	  EndElse
      ;Now Smooth Them
      SavgolFilter = savgol(FWindow, FWindow, Order, Degree)
      SmooRefColL  = Fltarr(KeyStr.Naxis2)
      SmooRefColR  = Fltarr(KeyStr.Naxis2)
      SmooRefColL[4:KeyStr.Naxis1-5] = $
          convol(MeanRefColL(4:KeyStr.Naxis1-5), SavgolFilter, $
               /edge_truncate)
      SmooRefColR[4:KeyStr.Naxis1-5] = $
          convol(MeanRefColR(4:KeyStr.Naxis1-5), SavgolFilter, $
               /edge_truncate)
      For Col = 0, (KeyStr.Naxis1/2)-1 do begin
        OutFrame(Col,*) = Frame(Col,*) - SmooRefColL*CFactor
        OutFrame((KeyStr.Naxis1-1)-Col,*) = Frame((KeyStr.Naxis1-1)-Col,*) - $
					    SmooRefColR*CFactor
      EndFor

      ;Return the reference pixel subtracted frame
      Return, OutFrame

   End
   2: begin
      ;Get the average of the reference pixels on the left and right
      Cube    = FitsFileNameOrFrame
      OutCube = FitsFileNameOrFrame

      For FrameNum = 0, (Size(Cube))[3] - 1 do begin
        Frame = Cube(*,*,FrameNum)
        OutFrame = Frame

        If KeyStr.Electronics eq 0 then begin
         MeanRefColL = Avg(Frame(1:3,*),0)
         MeanRefColR = Avg(Frame(KeyStr.Naxis1-4:KeyStr.Naxis1-2,*),0)
        EndIf Else Begin
		 MeanRefColL = Avg(Frame(1:3,*),0)
         MeanRefColR = Avg(Frame(KeyStr.Naxis1-3:KeyStr.Naxis1-1,*),0)
	    EndElse
        ;Now Smooth Them
        SavgolFilter = savgol(FWindow, FWindow, Order, Degree)
        SmooRefColL  = Fltarr(KeyStr.Naxis2)
        SmooRefColR  = Fltarr(KeyStr.Naxis2)
        SmooRefColL[4:KeyStr.Naxis1-5] = $
          convol(MeanRefColL(4:KeyStr.Naxis1-5), SavgolFilter, $
               /edge_truncate)
        SmooRefColR[4:KeyStr.Naxis1-5] = $
          convol(MeanRefColR(4:KeyStr.Naxis1-5), SavgolFilter, $
               /edge_truncate)
        For Col = 0, (KeyStr.Naxis1/2)-1 do begin
          OutFrame(Col,*) = Frame(Col,*) - SmooRefColL*CFactor
          OutFrame((KeyStr.Naxis1-1)-Col,*) = Frame((KeyStr.Naxis1-1)-Col,*) - $
					    SmooRefColR*CFactor
        EndFor
        OutCube(*,*,FrameNum) = OutFrame
	  EndFor
      ;Return the reference pixel subtracted frame
      Return, OutCube

   End
   3: begin
     If N_Elements(Row)	eq 0 or N_Elements(Col) eq 0 then begin
     	print, 'Must Input Reference Row and Column (Row =, Col= )'
     	stop
     EndIf

	 OutRamp = Ramp
	 RampL	 = N_Elements(Ramp)

     ;Right now the LEACH electronics have a bogus column 0 and
	 ;column 1020 is science data
	 If KeyStr.Electronics eq 0 then begin
	    If Col le KeyStr.Naxis1/2 then begin
          Fits_Read_DataCube, FitsFileNameOrFrame, RefPix, $
	        XStart = 1, XStop = 3, $
   	        YStart = Row, YStop = Row
		EndIf Else Begin
          Fits_Read_DataCube, FitsFileNameOrFrame, RefPix, $
            XStart = KeyStr.Naxis1-4, XStop = KeyStr.Naxis1-2, $
            YStart = Row, YStop = Row
	    EndElse
	  EndIf Else Begin
	    If Col lt KeyStr.Naxis1 then begin
	      Fits_Read_DataCube, FitsFileNameOrFrame, RefPix, $
	        XStart = 1, XStop = 3, $
   	        YStart = Row, YStop = Row
		EndIf Else Begin
          Fits_Read_DataCube, FitsFileNameOrFrame, RefPix, $
            XStart = KeyStr.Naxis1-3, XStop = KeyStr.Naxis1-1, $
            YStart = Row, YStop = Row
		EndElse
	  EndElse

	  MeanRefCol = Avg(RefPix,0)
	  OutRamp = Long(Ramp) - CFactor*MeanRefCol
	  Return, OutRamp

   end

  EndCase
end
