;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Lance Simms, Stanford University 2009 ;pro Find_Dead_Pixels ; ;PURPOSE: ; To try to find the pixels that do not change in signal at all during illumination. ; ; The method of finding them will be to take the difference between the first and ; last read of a flat field exposure, where the luminance should cause the signal ; to rise significantly, and flag pixels that have not accumulated a value that is ; 3sigma above 0. ; ;INPUTS: ; FITSFILENAMEORLIST: string ; MODE = 0 or MODE = 1 ; The path to the fits file that should be used to find the dead pixels. ; Ideally, this should be a flat field. ; MODE = 2 ; The path to the file that contains the list of fits files that will be used ; to generate the mask. ;OUTPUTS: ; FILE 1: ; KeyStrDeadDir+'DeadPix_'+KeyStr.RawObjectKey+'_'+KeyStr.Date+'_'+KeyStr.ThisFilter+'.fits' ; This file will be a fits image that shows 1s where the DeadPix are and ; 0s elsewhere. ; ;KEYWORDS: ; DATE: ; The Date during which they were taken. Also the subdirectory that ; the files are in. ; OFFSET: ; An offset for files that were written improperly. The readu ; function reads the values with this offset in place. ; 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. ; THISFILTER: ; The filter through which the files were taken. ('I', 'G', or 'Y') ; OVERRIDE: ; Do the processing even if the output file already exists ; BATCHMODE: ; 0 - Process only the file specified ; 1 - Process all of the files in the LeakyFileList ; ALLFILES: ; 1 - Process all files matching the #Reads, Filter, and Object ; 0 - Only process one file (the first by default) ; MODE: ; 0 - Just plot a dead pixel and its 4 nearest neighbors ; 1 - Search for all of the dead pixels in the file ; ROW: int ; If MODE = 0, this will be the row of the ead pixel ; COL: int ; If MODE = 0, this will be the column of the dead pixel ; USEREF: int ; 0 - Don't subtract the reference pixels ; 1 - Subtract the reference pixels ; ADDBIAS: int ; 0 - Don't add the bias back to the data cube ; 1 - Add the bias back to the data cube if it's a median file ; ;EXAMPLES: ; GENERATE THE DEAD MASK FROM INDIVIDUAL FILES ; find_leaky_pixels_xrg, '/nfs/slac/g/ki/ki03/lances/H2RG-32-147/DeadPix/DeadFiles.txt', mode=2 ; find_dead_pixels_xrg, '/nfs/slac/g/ki/ki03/lances/H2RG-32-147/DeadPix/DeadFiles.txt', mode=2 ; ;************************************************************************** pro Find_Dead_Pixels_xRG, FitsFileNameOrList, $ Mode=Mode, Row=Row, Col=Col, $ Offset = Offset, $ UseRef = UseRef, TvFlag = TvFlag If N_Elements(Mode) eq 0 then Mode = 1 If N_Elements(Col) eq 0 then Col = 20 If N_Elements(Row) eq 0 then Row = 20 If N_Elements(AddBias) eq 0 then AddBias = 0 if Mode ne 2 then begin ;No lists are used in this mode FitsFileName = FitsFileNameOrList ;Include KeywordStruct.pro file with all the defaults for keywords @KeywordStruct_xRG.pro @PlotSettings_xRG.pro ;Get a Few Kewyords FileCheck = Return_File_Params_xRG(FitsFileName) ;Form the output filenames DeadValsFileName = KeyStr.DeadDir+'DeadPix_'+KeyStr.RawObjectKey+'_'+$ KeyStr.Date+'_'+KeyStr.ThisFilter+'.fits' ;Indices with skipping of reference pixels and channel 0 Threshold = KeyStr.ReadNoiseMax NAxis1 = KeyStr.NAxis1 NAxis2 = KeyStr.NAxis2 Ref = KeyStr.Ref ;If H4RG is used, take first channdel as obsolete If DetStr eq 'H4RG-10-007' then begin Ch0W = KeyStr.Ch0W EndIf Else Begin Ch0W = Ref/2 EndElse ;Don't include the reference pixels XMin = Ch0W YMin = KeyStr.Ref/2 XMax = KeyStr.Naxis1-KeyStr.Ch0W-KeyStr.Ref/2 YMax = KeyStr.Naxis2-KeyStr.Ref/2 EndIf Case Mode of 0: Begin ;//////////////////////////////////////////////////////////////////// ;PLOT PIXELS //////////////////////////////////////////////////////// ;Read in the 3x3 area Fits_Read_DataCube, FitsFileName, Im, H, XStart=Col-1, XStop=Col+1, $ YStart = Row-1, YStop = Row+1 ;Add the bias back to the median if requested If AddBias eq 1 then begin For ReadNum = 1, KeyStr.NAxis3-1 do begin Im(*,*,ReadNum) = Im(*,*,ReadNum)+Im(*,*,0) EndFor EndIf Else Begin Im = Im(*,*,1:KeyStr.NAxis3-1) EndElse ;Get the min, max, and fraction w/respect to surrounding pixels MaxIm = Max(Im) MinIm = Min(Im) AvgSr = (Im(0,1,KeyStr.NAxis3-2)+Im(2,1,KeyStr.NAxis3-2)+$ Im(1,0,KeyStr.NAxis3-2)+Im(1,2,KeyStr.NAxis3-2))/4 Frac = Im(1,1,KeyStr.NAxis3-2)/float(AvgSr) ;Do the plotting plot, Im(1,1,*), yrange = [MinIm, MaxIm], $ ytitle = 'Counts', $ title='Dead Pixel in : ' + KeyStr.RawObjectBase, /normal, $ color = fsc_color('black'), background = fsc_color('white') oplot, Im(0,1,*), color = fsc_color('Red') oplot, Im(2,1,*), color = fsc_color('Blue') oplot, Im(1,0,*), color = fsc_color('Green') oplot, Im(1,2,*), color = fsc_color('Orange') xyouts, 0.20, 0.9, 'Pixel Coordinates', color = fsc_color('Black'), /normal xyouts, 0.20, 0.85, 'X : '+strtrim(Col, 2), color = fsc_color('Black'), /normal xyouts, 0.35, 0.85, 'Y : '+strtrim(Row, 2), color = fsc_color('Black'), /normal xyouts, 0.20, 0.80, 'Fraction of Neighbors: ' + strtrim(Frac,2), color=fsc_color('black'),$ /normal xyouts, 0.25, 0.75, 'Upper', color = fsc_color('Orange') , /normal xyouts, 0.25, 0.70, 'Center', color = fsc_color('Black') , /normal xyouts, 0.20, 0.70, 'Left', color = fsc_color('Red') , /normal xyouts, 0.32, 0.70, 'Right', color = fsc_color('Blue') , /normal xyouts, 0.25, 0.65, 'Lower', color = fsc_color('Green') , /normal OrigCharSize = !p.charsize !p.charsize = .75 xyouts, 0.10, 0.000, KeyStr.RawObjectPath, color=fsc_color('black'), /normal !p.charsize = OrigCharSize If KeyStr.TvFlag eq 1 then begin Img = tvread(/tiff, FileName = KeyStr.LeakyDir+'Plots'+KeyStr.PathDelim+$ KeyStr.RawObjectKey+'_'+Strtrim(Col,2)+'_'+Strtrim(Row,2)+'.tif',$ /nodialog) EndIf stop End 1: Begin ;//////////////////////////////////////////////////////////////////////////////// ;*********************** FIND ALL DEAD PIXELS IN FILE ************************** ;Form an array that will keep track of how many times this pixel was leaky DeadPixVals = bytarr(Naxis1, Naxis2) ;Array to hold mask SciPixBool = bytarr(XMax-XMin, YMax-YMin) ;Array to hold mask without reference spaces MkHdr, DeadHeader, DeadPixVals FxAddPar, DeadHeader, 'DIFTHRESH', ThresHold, $ 'Threshold between first and last read' FxAddPar, DeadHeader, KeyStr.Date+'_'+KeyStr.RawObjectBase, $ 'Name of Files used to draw map' FxAddPar, DeadHeader, 'NUMDEAD', 0, $ 'Number of pixels with signal increase less than THRESHOLD' ;*************************************************************************** ;Begin the main loop for the files and read numbers print, 'Reading File: ' + FitsFileName ;Open up the raw image whether dark, flat, or object Fits_Read_DataCube, FitsFileName, Im, RawHeader if Stregex(KeyStr.RawObjectKey, 'Flat', /boolean) then begin FirstFrame = Float(Im(*,*,0)) LastFrame = Float(Im(*,*,KeyStr.NAxis3-1)) SciPixVals = LastFrame(XMin:XMax-1, YMin:YMax-1) DeadPix = where(SciPixVals lt Threshold) endif else begin FirstFrame = Float(Im(*,*,0)) LastFrame = Float(Im(*,*,KeyStr.NAxis3-1)) DiffFrame = LastFrame-FirstFrame SciPixVals = DiffFrame(XMin:XMax-1, YMin:YMax-1) DeadPix = where(SciPixVals lt Threshold) endelse Print, 'Found : '+strtrim(N_Elements(DeadPix),2) +'Dead Pixels' ;Change the header slightly for the mask SciPixBool(DeadPix) = 1 DeadPixVals(XMin:XMax-1, YMin:YMax-1) = SciPixBool ;FxAddPar, DeadHeader, 'BITPIX', 8 Fits_Write, DeadValsFileName, DeadPixVals, DeadHeader End 2: Begin ;//////////////////////////////////////////////////////////////////// ;Get the names of fits files that will be used readcol, FitsFileNameOrList, FitsFileNames, format='A' FitsFileName = FitsFileNames(0) DirName = File_DirName(FitsFileName) DeadFileName = DirName + Path_Sep()+'DeadMask.fits' fits_read, FitsFileName, D, H, /header_only NAxis1 = long(SxPar(H, 'NAXIS1')) NAxis2 = long(SxPar(H, 'NAXIS2')) DeadMask = BytArr(NAxis1, NAxis2) ;FileNames and headers for masks and value leaky files MkHdr, DeadHeader, DeadMask for FileNum = 0, N_Elements(FitsFileNames)-1 do begin FxAddPar, DeadHeader, 'FILENUM'+Strtrim(FileNum,2), $ File_BaseName(FitsFileNames(FileNum)), $ 'Files used to generate mask' endfor for FileNum = 0, N_Elements(FitsFileNames)-1 do begin Fits_Read, FitsFileNames(FileNum), DeadMaskInd, DeadHeadInd DeadMask(where(DeadMaskInd ne 0)) = 1 endfor ;Write the fits file Fits_Write, DeadFileName, DeadMask, DeadHeader End EndCase stop end