;pro Bad_Pixel_Mask
;
;PURPOSE:
;	To take a series of dark images and extract from them the pixels that
;	appear to have no dark current. These pixels are 
;
;INPUTS:
;
;OUTPUTS:
;
;KEYWORDS:
;       ROOTDIR: 
;         The Directory holding the directories of Raw files
;       DATE:
;         The Date during which they were taken.  Also the subdirectory that 
;         the files are in.
;       REDUCEDDIR:
;         The directory where the processed images and plots will be placed in.
;       BLOCKLENGTH:
;         An offset for files that were written improperly.  The readu 
;         function reads the values with this offset in place.
;       OBJECTNAME:
;         The string that indicates what files are being sought.  The filenames
;         should begin with this string ('Dark', 'Flat', etc.).
;       NREADS:
;         The number of reads (NAXIS3) that are present in the file.  This
;         is also a string in the filename that will be used as a regular
;         expression in searching for matched files.
;       FIRSTREAD:
;         The first read to be used in the difference 
;             Diff = LastRead - FirstRead
;       LASTREAD: 
;         The last read to be used in the difference
;       THISFILTER:
;         The filter through which the files were taken. ('I', 'G', or 'Y')
;	OVERRIDE: 
;	  Do the processing even if the output file already exists
;	ALLFILES:
;	  1 - Process all files matching the #Reads, Filter, and Object
;	  0 - Only process one file (the first by default)
;**************************************************************************

pro Bad_Pixel_Mask, RootDir=RootDir, Date=Date, $
         ReducedDir = ReducedDir, BlockLength = BlockLength, $
         ObjectName=ObjectName, NReads = NReads, ThisFilter = ThisFilter,$
         OverRide = OverRide, FirstRead = FirstRead, LastRead = LastRead, $
	 Threshold = Threshold

  ; set directory path delimiter
  pathdelim=path_sep()

  ;Directory and FileName Keywords
  If Not keyword_set(RootDir) then RootDir = '/nfs/slac/g/ki/ki09/lances/'
  If Not keyword_set(Date) then Date='07Apr30'
  If Not keyword_set(ReducedDir) then ReducedDir= RootDir+$
         PathDelim+'Reduced'+PathDelim+Date+PathDelim
  If Not keyword_set(BlockLength) then BlockLength = 0
  If Not keyword_set(ObjectName) then ObjectName = 'Flat'
  If Not keyword_set(NReads) then NReads = 2
  If Not keyword_set(FirstRead) then FirstRead = 0
  If Not keyword_set(LastRead) then LastRead = NReads - 1
  If Not keyword_set(ThisFilter) then ThisFilter = 'Blank'
  If Not keyword_set(OverRide) then OverRide = 0
  If Not keyword_set(AllFiles) then AllFiles = 1
  BadPixDir = ReducedDir+'BadPix'+PathDelim

  ;Parameters
  If Not keyword_set(Threshold) then Threshold = 100

  ;Start in the RootDir/Date directory
  cd, Rootdir+Date

  ;Get all of the Dark Files for this Number of Reads
  RawFiles = File_Search(ObjectName+'*'+strtrim(NReads,2)+'_Reads*.fits')
  If RawFiles(0) eq '' then stop
  NumFiles = 1
  if AllFiles then NumFiles = N_elements(RawFiles)   

  ;Get a Few Kewyords
  Fits_Read,  RawFiles(0), NoData, FitsHeader, /header_only
  Naxis1     = long(sxpar(FitsHeader, 'NAXIS1'))
  Naxis2     = long(sxpar(FitsHeader, 'NAXIS2'))
  TotalReads = long(sxpar(FitsHeader,'NAXIS3'))
  ArrSize = long(Naxis1*Naxis2)

  ;Form a Bad Pixel Mask Array
  BadPix = UIntArr(Naxis1,Naxis2)

  ;How many files to go through
  For FileNum = 0, NumFiles - 1 do begin  
    print, 'Finding bad pixels in ' + RawFiles(FileNum) + ' : ' + $
	   strtrim(FileNum,2) + ' out of ' + strtrim(NumFiles, 2)
    
    ;Go through all of the reads, take differences and sort out dead pixels 
    For ReadNum=0, TotalReads-2 do begin
       ;Get difference of ReadNum and ReadNum+1
       DiffIm = Return_Cube_Diff(RawFiles(FileNum), ArrSize, Naxis1, Naxis2, $
	                        ReadNum, ReadNum+1)
       ;Look for pixels that aren't building signal
       BadPixTemp=UIntArr(Naxis1,Naxis2)
       BadPixInd = where(DiffIm lt Threshold)
       If BadPixInd(0) ne -1 then BadPixTemp(BadPixInd) = 1
       ;Add them to the map so that really dead ones build up
       BadPix = BadPix + BadPixTemp
    EndFor

  EndFor

;*******************************************************************OUTPUT
;Form a string designating what type of Bad Pixel test was run
;and what date it's from, etc. 
BadPixStr = 'DeadPixelMap_'+strtrim(NumFiles,2)+$+
            ObjectName+'s_Threshold_'+strtrim(Threshold,2)+$
            '_'+Date

;Make a Histogram of the Number of times that the pixel did not meet the 
;threshold
 
;Write a .txt file that shows the pixel number and how many times it was 
;flagged, sorted from highest to least
TextFile = 1
If TextFile then begin

  BadPixNoCh0NoRef = BadPix(128:Naxis2-5,4:Naxis2-5)	;Skip Ch0 and ref pixels
  XSize = long((size(BadPixNoCh0NoRef))[1])
  YSize = long((size(BadPixNoCh0NoRef))[2])
  DeadPixInd = where(BadPixNoCh0NoRef eq NumFiles*(TotalReads-1))
  DeadPixInd = DeadPixInd(reverse(sort(DeadPixInd)))
  DeadPix = BadPixNoCh0NoRef(DeadPixInd)
  RowNum  = DeadPixInd/XSize+4
  ColNum  = (DeadPixInd mod XSize)+128

  get_lun, BadPixTxtFile
  openw,   BadPixTxtFile, BadPixDir+BadPixStr+'.txt'
  printf,  BadPixTxtFile, FORMAT = '(%"%s\t%s\t%s\t%s")',$
	'Row', 'Column', 'Pixel Number', 'Times Flagged'
  for PixInd = 0L, N_Elements(DeadPix)-1 do begin
    printf, BadPixTxtFile, FORMAT = '(%"%I\t%I\t%I\t%I")', $
	RowNum(PixInd), ColNum(PixInd), $
	DeadPixInd(PixInd), DeadPix(PixInd)
  endfor

  close,    BadPixTxtFile
  free_lun, BadPixTxtFile

EndIf

;Write a .fits file showing the pixels with value dependent on how many 
;times they were flagged through the stack of images
MkHdr, FitsHeader, BadPix
FxAddPar, FitsHeader, 'THRESHOL', Threshold, $
	  'Difference value below which pixel is flagged'
FxAddPar, FitsHeader, 'FILETYPE', ObjectName, $
	  'Type of File used for flagging bad pixels'
FxAddPar, FitsHeader, 'DATADATE', Date, $
	  'Directory from which data was taken'
FxAddPar, FitsHeader, 'NUMREADS', TotalReads, $
	  'Total Number of reads used in subtraction from each file'
FxAddPar, FitsHeader, 'NUMFILES', NumFiles, $
	  'Total Number of files used to create mask'
FxAddPar, FitsHeader, 'MAXPIXVL', NumFiles*TotalReads, $
	  'Maximum value a pixel will have (dead sh pixels)'
Fits_Write, BadPixDir+'DeadPixelMap_'+strtrim(NumFiles,2)+$+
	ObjectName+'s_Threshold_'+strtrim(Threshold,2)+$
	'_'+Date+'.fits', BadPix, FitsHeader

stop

end
