##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Lance Simms, Stanford University 2009
##ExaminePhotonTransfer.py
##
##PURPOSE: 
##  To examine the shot noise and fixed pattern noise as a function 
##  of signal. 
##
##INPUTS: 
##      FitsFileName1, FitsFileName2 : string
##          The full path to the two fits files that contains the 
##          uniform illumination
##KEYWORDS:
##  XStart: int
##    X start coordinate for region of interest
##  XStop: int
##    X stop coordinate for region of interest
##  YStart: int
##    Y start coordinate for region of interest
##  YStop: int
##    Y stop coordinate for region of interest
##  UseRef: int	      
##    A Boolean; 0-Don't subtract reference 1-Do subtract
##  CFac: float
##    The multiplicative factor for reference pix subtraction
##  ReadNoise: float
##    The readnoise value to subtract from the shot noise curve
##  Mode: int      
##    0 - Examine region of pixels
##  DarkSub: int       
##    0 - Don't subtract a dark
##    1 - Subtract a median dark with the same NReads
##  TvFlag: int         
##    0 - Don't plot
##    1 - Plot
##    2 - Plot Ramps and Deltas
##  AllReads: int
##    0 - Collect data only for read specified by ReadNum
##    1 - Collect data for all reads in all exposures
##
##CALLING SEQUENCE:
##  run ExaminePhotonTransfer.py [FitsFileName1] [FitsFileName2] 
##
##EXAMPLES:
##
##Extremely good linearity:
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec19/Flat/Flat_Y_H2RG_SIPIN_30_Reads_Dec19_2007_18_50_12.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec19/Flat/Flat_Y_H2RG_SIPIN_30_Reads_Dec19_2007_18_51_07.fits' --YStart=1000 --YStop=1450 --XStart=1470 --XStop=1700 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45
##
##ASIC:
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec15/Flat/Flat_Y_H2RG_SIPIN_30_Reads_Dec15_2007_21_22_17.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec15/Flat/Flat_Y_H2RG_SIPIN_30_Reads_Dec15_2007_21_23_10.fits' --YStart=1000 --YStop=1100 --XStart=1500 --XStop=1600 --TvFlag=0 --Mode=0 --UseRef=0
##
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec15/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec15_2007_20_59_53.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec15/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec15_2007_21_00_45.fits' --YStart=1400 --YStop=2000 --XStart=1100 --XStop=1500 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45


##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec19/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec19_2007_18_43_47.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec19/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec19_2007_18_44_39.fits' --YStart=1000 --YStop=1450 --XStart=1470 --XStop=1700 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec15/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec15_2007_21_01_39.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec15/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec15_2007_21_02_31.fits' --YStart=1000 --YStop=1450 --XStart=1470 --XStop=1700 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec12/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec13_2007_00_46_17.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec12/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec13_2007_00_47_10.fits'  --YStart=100 --YStop=500 --XStart=100 --XStop=500 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec12/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec13_2007_00_46_17.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/ASIC/07Dec12/Flat/Flat_G_H2RG_SIPIN_30_Reads_Dec13_2007_00_47_10.fits'  --YStart=1600 --YStop=2000 --XStart=1600 --XStop=2000 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45
##
##
##LEACH
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/LEACH/2007Dec15/Flat/Flat_G_Filter_2.fits' '/nfs/slac/g/ki/ki04/lances/H2RG-32-147/LEACH/2007Dec15/Flat/Flat_G_Filter_3.fits' --YStart=100 --YStop=500 --XStart=100 --XStop=500 --TvFlag=0 --Mode=0 --UseRef=0 --CFac=1.45
##H1RG======================================
##LEACH
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov14/Flat/Flat_Y_6.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov14/Flat/Flat_Y_7.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov14/Flat/Flat_I_6.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov14/Flat/Flat_I_7.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov14/Flat/Flat_G_6.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov14/Flat/Flat_G_7.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800

##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov18/Flat/Flats_Y_Filter_6.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov18/Flat/Flats_Y_Filter_7.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov18/Flat/Flats_I_Filter_6.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov18/Flat/Flats_I_Filter_7.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov18/Flat/Flats_G_Filter_6.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/LEACH/2007Nov18/Flat/Flats_G_Filter_7.fits' --YStart=600 --YStop=800 --XStart=600 --XStop=800

##ASIC
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_Y_H1RG_SIPIN_15_Reads_Nov17_2007_06_01_44.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_Y_H1RG_SIPIN_15_Reads_Nov17_2007_06_02_01.fits'  --YStart=500 --YStop=800 --XStart=500 --XStop=800
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_G_H1RG_SIPIN_15_Reads_Nov17_2007_05_54_49.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_G_H1RG_SIPIN_15_Reads_Nov17_2007_05_55_06.fits' --YStart=300 --YStop=700 --XStart=512 --XStop=970 --UseRef=1
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_G_H1RG_SIPIN_15_Reads_Nov17_2007_05_56_32.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_G_H1RG_SIPIN_15_Reads_Nov17_2007_05_56_50.fits' --YStart=300 --YStop=700 --XStart=512 --XStop=970
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_I_H1RG_SIPIN_15_Reads_Nov17_2007_05_49_13.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov16/Flat_I_H1RG_SIPIN_15_Reads_Nov17_2007_05_49_30.fits' --YStart=300 --YStop=700 --XStart=512 --XStop=970

##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov19/Flat_Y_H1RG_SIPIN_15_Reads_Nov19_2007_19_52_08.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov19/Flat_Y_H1RG_SIPIN_15_Reads_Nov19_2007_19_52_27.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800
##run ExaminePhotonTransfer.py '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov19/Flat_G_H1RG_SIPIN_15_Reads_Nov19_2007_19_46_22.fits' '/nfs/slac/g/ki/ki04/lances/H1RG-022/ASIC/07Nov19/Flat_G_H1RG_SIPIN_15_Reads_Nov19_2007_19_46_41.fits' --YStart=500 --YStop=800 --XStart=500 --XStop=800

##THESIS PLOTS:
##

##
##SETUP
execfile('/afs/slac/u/ki/lances/python/python_HxRG/HxRG_Setup.py')
execfile('/afs/slac/u/ki/lances/python/SPIEPlotSettings.py')
PlotDir = '/nfs/slac/g/ki/ki04/lances/LSST/KPNO/Latex/Thesis/NoiseVsSignal/Figures/'

from HxRG_Class import *
from ReturnCentroid import *
from ReturnRadialAvg import *
from Djs_Iterstat import *
from ReadNoise import *
import TableIO
import csv
import pdb
import asciidata

#Get the filename and options from command line
FitsFileName1  = sys.argv[1]
FitsFileName2  = sys.argv[2]

##INITIAL SETUP
HxRG1  = HxRG_C(FitsFileName=FitsFileName1)
HxRG2  = HxRG_C(FitsFileName=FitsFileName2)

##PARSE KEYWORDS
keywords    = ['XStart=', 'XStop=', 'YStart=', 'YStop=',\
               'UseRef=','DarkSub=','Mode=',\
	       'TvFlag=', 'Verbose=', \
               'CFac=', 'ReadNoise=']
XStart       = 4
XStop        = HxRG1.FNAxis1-5
YStart       = 4
YStop        = HxRG1.FNAxis2-5
UseRef       = 0
DarkSub      = 0
Mode         = 0
TvFlag	     = 0
Verbose      = 1
CFac         = -1
ReadNoise    = 8.0

opts, extraparams = getopt.getopt(sys.argv[3:],'',keywords)
for o,p in opts:
  if o in ['--XStart']:
    XStart =int(p)
  elif o in ['--XStop']:
    XStop  =int(p)
  elif o in ['--YStart']:
    YStart = int(p)
  elif o in ['--YStop']:
    YStop  = int(p)
  elif o in ['--UseRef']:
    UseRef  = int(p)
  elif o in ['--DarkSub']:
    DarkSub = int(p)
  elif o in ['--Mode']:
    Mode= int(p)
  elif o in ['--CenSize']:
    CenSize = int(p) 
  elif o in ['--TvFlag']:
    TvFlag = int(p)
  elif o in ['--Verbose']:
    TrackStar = int(p)
  elif o in ['--CFac']:
    CFac    = float(p)
  elif o in ['--ReadNoise']:
    ReadNoise = float(p)

##FIND THE MATCHING DARK
if DarkSub == 1:
   HxRG.Get_Median_Dark(HxRG.NReads)
   DarkHDU = pyfits.open(HxRG.DarkName)

##GO THROUGH THE FILES AND PLOT THE PERSISTENCE
if TvFlag > 0:
  mplot.close('all')
  Fig = mplot.figure(0)

##GET THE FIRST DATACUBE..........................................
##Get the slope and the slope header
FitsHDU      = pyfits.open(FitsFileName1)
HxRG1.Get_Raw_Header(FitsFileName1)

#Get the Bias Read and allow for dark subtraction
Im1 = FitsHDU[0].section[:,:,:]
if UseRef == 1:
  if CFac == -1:
    HxRG1.CFac = 3.1
    HxRG1.CFac = 1.5
    HxRG1.CFac = 1.45
    if HxRG1.DetStr == 'H2RG-001':
      HxRG1.CFac = 2.0
  else:
    HxRG1.CFac = CFac
  Im1   = ReturnRSCube(Im1, HxRG1.CFac, BadCols=HxRG1.BadCols)
if DarkSub == 1:
  Dark  = DarkHDU[0].section[0:,:,:]
  Im1   = Im1 -Dark

##GET THE VARIANCE DATACUBE==========
##Get the slope and the slope header
HxRG2.Get_Raw_Header(FitsFileName2)
FitsHDU  = pyfits.open(FitsFileName2)
Im2      = FitsHDU[0].section[:,:,:]
Header2  = FitsHDU[0].header
if UseRef == 1:
  Im2   = ReturnRSCube(Im2, HxRG1.CFac, BadCols=HxRG1.BadCols)
if DarkSub == 1:
  Dark  = DarkHDU[0].section[0:,:,:]
  Im2   = Im2 -Dark

##Find the full range of pixels being considered
XRange      = XStop - XStart
YRange      = YStop - YStart

if Mode == 0:

  MeanADUArr1 = zeros(HxRG1.NAxis3-1, dtype=float32)
  MeanADUArr2 = zeros(HxRG1.NAxis3-1, dtype=float32)
  SigADUArr1  = zeros(HxRG1.NAxis3-1, dtype=float32) #Total Noise
  SigADUArr2  = zeros(HxRG1.NAxis3-1, dtype=float32) #Total Noise 
  SigADUArrD  = zeros(HxRG1.NAxis3-1, dtype=float32) #Read Noise + ShotNoise
  SNRNADUArr  = zeros(HxRG1.NAxis3-1, dtype=float32) #Read Noise + ShotNoise
  SNADUArr    = zeros(HxRG1.NAxis3-1, dtype=float32) #ShotNoise Alone
  FPADUArr    = zeros(HxRG1.NAxis3-1, dtype=float32) #Fixed Pattern Noise

  for ReadNum in arange(HxRG1.NAxis3-1)+1:
    ThisIm1  = Im1[ReadNum, YStart:YStop, XStart:XStop]-\
               Im1[0, YStart:YStop, XStart:XStop]
    ThisIm2  = Im2[ReadNum, YStart:YStop, XStart:XStop]-\
               Im2[0, YStart:YStop, XStart:XStop] 
    ThisDiff = ThisIm2-ThisIm1

    if TvFlag > 0 :
      #Histogram and find FWHM
      NBins = int(ThisVar.max()-ThisVar.min())
      MinNoise = ThisVar.min()
      Bins     = arange(NBins)+MinNoise
      Bins, N  = histOutline.histOutline(ThisVar, binsIn=Bins)
      mplot.figure(2)
      mplot.clf()
      ThisP = mplot.plot(Bins,N, 'o')
      print 'Read Number : ' + str(ReadNum)
      pdb.set_trace()
    Mean1, Sig1, Med1, Mode1, Mask1 = \
      Djs_Iterstat(ThisIm1, RejVal=-100000., SigRej=3.5)
    Mean2, Sig2, Med2, Mode2, Mask2 = \
      Djs_Iterstat(ThisIm2, RejVal=-100000., SigRej=3.5)
    MeanD, SigD, MedD, ModeD, MaskD = \
      Djs_Iterstat(ThisDiff, RejVal=-100000., SigRej=3.5)
    Mean1 = ThisIm1.mean()
    Mean2 = ThisIm2.mean()
    MeanD = ThisDiff.mean()
    Sig1  = ThisIm1.std()
    Sig2  = ThisIm2.std()
    SigD  = ThisDiff.std()
    MeanADUArr1[ReadNum-1] = Mean1
    MeanADUArr2[ReadNum-1] = Mean2
    SigADUArr1[ReadNum-1]  = Sig1
    SigADUArr2[ReadNum-1]  = Sig2
    SigADUArrD[ReadNum-1]  = SigD/sqrt(2)
    SNRNADUArr[ReadNum-1]  = SigD/sqrt(2)
    SNADUArr[ReadNum-1]    = sqrt((SigD/sqrt(2))**2-ReadNoise**2) 
    FPADUArr[ReadNum-1]    = sqrt(Sig1**2-(SigD/sqrt(2))**2)


mplot.figure(0)
mplot.clf()
mplot.plot(MeanADUArr1,  SigADUArr1**2, 'b')
mplot.plot(MeanADUArr1,  SigADUArr1**2, 'bo')
mplot.plot(MeanADUArr2,  SigADUArr2**2, 'r')
mplot.plot(MeanADUArr2,  SigADUArr2**2, 'ro')

mplot.figure(1)
mplot.clf()
mplot.plot(MeanADUArr1,  SigADUArrD**2, 'b')
mplot.plot(MeanADUArr1,  SigADUArrD**2, 'bo')

m, b, E, CosE = Linefit(MeanADUArr1, SigADUArrD**2, RejectCos=0)
mplot.plot(MeanADUArr1, m*MeanADUArr1+b, 'r--')

Fig=mplot.figure(2)
mplot.clf()
Ax1=Fig.add_axes([0.08,0.12,0.90,0.85])
mplot.loglog(MeanADUArr1,  SNADUArr, 'b', linewidth=2)
mplot.loglog(MeanADUArr1,  SNADUArr, 'bo', label=r'\textbf{Shot Noise}', \
  markersize=6, markeredgewidth=1)
mplot.loglog(MeanADUArr1,  FPADUArr, 'r', linewidth=2)
mplot.loglog(MeanADUArr1,  FPADUArr, 'ro', label=r'\textbf{Fixed Pattern Noise}', \
  markersize=6, markeredgewidth=1)
mplot.loglog(MeanADUArr1,  SigADUArr1, 'g', linewidth=2)
mplot.loglog(MeanADUArr1,  SigADUArr1, 'go', label=r'\textbf{Total Noise}', \
  markersize=6, markeredgewidth=1)
xvals = arange(100000)+1
mplot.loglog(xvals, .0095*xvals,'k--', label=r'\textbf{Slope =\ 1}', linewidth=3)
mplot.loglog(xvals, (.26*xvals**.5), 'k-.', label=r'\textbf{Slope = 1/2}', linewidth=3)
ylim(4, 300)
xlim(500, 2.5e4)
xlabel(r'\textbf{Signal (ADU)}')
ylabel(r'\textbf{RMS Noise (ADU)}')
mplot.legend(loc=2, numpoints=1)
mplot.grid(True, which='minor')

SaveImg = 0
if SaveImg == 1:
  if UseRef == 0:
    mplot.savefig(PlotDir+'NoiseVsSignal_'+HxRG.DetStr+\
                 '_X_'+str(XStart)+'_'+str(XStop)+\
                 '_Y_'+str(YStart)+'_'+str(YStop)+\
                 '_CFAC_'+str(HxRG.CFac)+'.png')
    mplot.savefig(PlotDir+'NoiseVsSignal_'+HxRG.DetStr+\
                 '_X_'+str(XStart)+'_'+str(XStop)+\
                 '_Y_'+str(YStart)+'_'+str(YStop)+\
                 '_CFAC_'+str(HxRG.CFac)+'.eps')
                
  else:
    mplot.savefig(PlotDir+'NoiseVsSignal_RPS_'+HxRG.DetStr+\
                 '_X_'+str(XStart)+'_'+str(XStop)+\
                 '_Y_'+str(YStart)+'_'+str(YStop)+\
                 '_CFAC_'+str(HxRG.CFac)+'.png')
    mplot.savefig(PlotDir+'NoiseVsSignal_RPS_'+HxRG.DetStr+\
                 '_X_'+str(XStart)+'_'+str(XStop)+\
                 '_Y_'+str(YStart)+'_'+str(YStop)+\
                 '_CFAC_'+str(HxRG.CFac)+'.eps')


