;+ ; NAME: ; imgclean ; ; PURPOSE: ; This procedure is designed to remove cosmic ray hits (CRs) from an image, ; especially WFPC images. The procedure's effectiveness varies from image ; to image. Often, it does an excellent job, but sometimes ; the operational parameters must be modified (via keywords) to tweak ; the performance of the software. ; It should not be assumed that this procedure will automatically do a good ; job! Keep a close eye on before and after images. Occasionally, a faint ; star gets obliterated, especially if there is a cosmic ray around 3 pixels ; from it. Naturally, this procedure is only recommended when a CR split is ; not possible, as that will often yield better results. ; Run IMGclean twice on the same image to achieve best cleaning results ; especially on images with very dense CR's. ; Still in a somewhat primitive state, this procedure still need some ; improvement to the algorithm. Suggestions welcome to deutsch@stsci.edu. ; Use the CLEANEXAMINE main program to examine the results of the IMGclean ; run. ; Currently, IMGclean is tweaked for PC images. I haven't worked with ; WF images in a while, so you may to diddle with the parameters for best ; effect. ; ; CALLING SEQUENCE: ; imgclean,IMAGE,HEADER,[CR_ARRAY],[optional keywords]' ; imgclean,/help ; ; INPUT/OUTPUT PARAMETERS: ; IMAGE This parameter supplies the image in which the CRs are to be ; removed. This image is MODIFIED! The output cleaned image ; is returned via this variable. ; HEADER This parameter is the FITS header. The header will be modified ; with added HISTORY notes and keywords detailing the settings ; used on the last IMGclean run. ; ; OPTIONAL OUTPUT: ; CR_ARRAY This array is a BYTE array of the same size as the input image ; containing some information of which pixels the software ; considered, and what decisions it made as far as CR or STAR. ; DN Meaning ; 70 Low scan pixel not removed ; 120 Hi scan pixel not removed (i.e. suspected star) ; 255 Hi scan pixel removed (i.e. cosmic ray) ; 200 Neighboring Low scan pixel removed ; ; OPTIONAL INPUT: ; HELP Displays quick keyword defaults values ; TESTRUN If set, dumps a file with stats on each object considered ; STAR_PSF_SENS Sensitivity of the STAR checking. ; The higher the value, the more CRs will be left in the ; image because they are suspected as being stars. The ; lower the value, the more faint stars will be removed. ; Default=.35 Typical=.35, .25, .30, .40. ; -Value: .35 is probably the optimum value for doing a ; good job with CR's but leaving virtually faint ; scrungy stars for PC frames. ; -Value: .25 is probably the optimum value for doing ; the best possible job of cleaning CR's at the ; expense of removing a few more faint scrungy stars ; than is proper. If faint, scrungy stars are not ; important, this may be the best setting (again, PC). ; SKY_VAL_SAMP_SZ Size of the boxes used when calculating the local ; background. The X,Y image size must be a multiple of the ; box size. Use smaller boxes for steeper images. ; Default values are 10 or 16. ; HI_SCAN_HEIGHT Pixel value above the sky value in sky RMS units that is ; flagged as a suspected CR. Default=6. Typical=5,6,7 ; LO_SCAN_HEIGHT Pixel value above the sky value in sky RMS units that is ; removed if it is adjacent to a positively identified CR, ; provided FINE_CLEAN=1. Default=1.5. Typical=2,2.5,3 ; FINE_CLEAN Set (=1) this keyword (Flag) if pixels above LO_SCAN_HEIGHT ; neighboring pixels identified as CRs are to be removed. ; PHASE1_ITER Number of iterations for Phase 1. Should always be 2 ; because 1 iteration tends to leave more CRs behind. ; QPHOT If set, quick photometry is run on stars using qphot.pro ; NOT SUPPORTED!!!! ; NOCLEAN If set, all objects are assumed to be stars and nothing ; is checked or removed. Used in conjunction with QPHOT ; on an already cleaned image. ; ; HISTORY: ; 02-SEP-90 Version 1.0 written by Eric W. Deutsch (EWD) ; 27-JUN-91 Version 1.1 released with several minor modifications including ; changing the operational parameters to keywords. (EWD) ; 27-JAN-92 Version 1.2 released with the additions of changing the ; operational parameters to keywords and adding better on-line ; help. (EWD) ; 07-MAY-92 Version 1.21 released: proper header added and /HELP keyword ; added. EWD. ; 10-MAY-92 Version 1.22: Fixed "Donutting" problem and changed default ; STAR_PSF_SENS value to .50 instead of .66 since it was removing ; too many actual stars. EWD. ; 24-JUL-92 Version 1.3: Better Star/CR determination algorithm added. ; This algorithm is less Kludgy, but sometimes gives poorer ; results than the v1.22 release. Needs Work! EWD. ; 08-DEC-92 Version 1.31: Tidied things up a bit, but nothing major. EWD. ; 09-DEC-92 Version 1.32: Fixed a rather major bug in the focus pixel ; identifier and fixed the logic for negative ratios. This ; now shows a major improvement! The major task now is to add ; a special identifier for streak CR hits. EWD ; 04-JAN-93 Version 1.40: Changed the default sensitivity to 0.35 which ; make IMGclean more lenient as far as stars go, but added ; another simple-minded neighboring pixels check which catches ; A LOT of CR's. Basically, I say that if more than 2 of the ; 8 neighboring pixels aren't above the low scan hight, then ; it MUST be a cosmic ray. This now shows another big im- ; provement in number of CR's removed as well as star removed. ; This also does a better job at removing long streaks, but ; an algorithm specifically for longs streaks is needful and ; will be implemented soon. Header updated. Eric W. Deutsch ; 05-JAN-93 Version 1.41: Little Faster. Fixed FITS header updating. EWD ; 06-JAN-93 Added a few more comments and text to program header. EWD ; 28-FEB-93 Version 1.42: Added /QPHOT and /NOCLEAN options and code so that ; IMGclean can do some rudimentary quick aperture photometry. EWD ;- pro skyline,origline,skyv,rms,interactive ;+ ; NAME: ; skyline ; ; PURPOSE: ; Determine sky value and RMS for an image. ; Called by IMGCLEAN. ; ; HISTORY: ; Written by Eric Deutsch as part of the IMGCLEAN suite. ; Header added by PP/ACC April 16, 1997 ; ;- ; ;;;if (n_params(0) lt 4) then interactive=0 tmp=where(origline ne 0) if (tmp(0) eq -1) then begin ; print,'[SKYLINE]: Warning: piece of sky is all 0.00's!' skyv=0.0 & rms=1.0 return endif line=origline(where(origline ne 0)) els=n_elements(line) av1=avg(line) rms1=sigma(line) ;;;if (interactive eq 1) then begin if keyword_set(interactive) then begin print,'1st Iteration: AVG=',strn(av1),',RMS=',strn(rms1) plot,indgen(els),line oplot,[0,els],[av1,av1] oplot,[0,els],[av1+rms1,av1+rms1] ch=get_kbrd(1) endif atmp=where(line lt av1+3*rms1) chk=size(atmp) if (chk(0) eq 0) then begin a=line goto,SKIP1 endif a=line(atmp) av1=avg(a) rms1=sigma(a) ;;;if (interactive eq 1) then begin if keyword_set(interactive) then begin print,'2nd Iteration: AVG=',strn(av1),',RMS=',strn(rms1) plot,indgen(els),a oplot,[0,els],[av1,av1] oplot,[0,els],[av1+rms1,av1+rms1] ch=get_kbrd(1) endif SKIP1: atmp=where((a lt av1+2*rms1) and (a gt av1-2*rms1)) chk=size(atmp) if (chk(0) eq 0) then goto,DONE a=a(atmp) av1=avg(a) rms1=sigma(a) ;;;if (interactive eq 1) then begin if keyword_set(interactive) then begin print,'3nd Iteration: AVG=',strn(av1),',RMS=',strn(rms1) plot,indgen(els),a oplot,[0,els],[av1,av1] oplot,[0,els],[av1+rms1,av1+rms1] ch=get_kbrd(1) endif DONE: skyv=1.0 ; print,'Skyvalue=',strn(av1),', RMS=',strn(rms1) skyv=av1 & rms=rms1 return end FUNCTION SIGMA,ARRAY,N_PAR,DIMENSION ;+ ; NAME: ; SIGMA ; PURPOSE: ; Calculate the standard deviation value of an array, or calculate the ; standard deviation over one dimension of an array as a function of all ; the other dimensions. ; CALLING SEQUENCE: ; RESULT = SIGMA(ARRAY) ; RESULT = SIGMA(ARRAY,N_PAR) ; RESULT = SIGMA(ARRAY,N_PAR,DIMENSION) ; INPUTS: ; ARRAY = Input array. May be any type except string. ; OPTIONAL INPUT PARAMETERS: ; N_PAR = Number of parameters. Default value is zero. The number of ; degrees of freedom is N_ELEMENTS(ARRAY) - N_PAR. The value ; of sigma varies as one over the square root of the number of ; degrees of freedom. ; DIMENSION = Optional dimension to do standard deviation over. ; OUTPUTS: ; The standard deviation value of the array when called with one ; parameter. ; ; If DIMENSION is passed, then the result is an array with all the ; dimensions of the input array except for the dimension specified, ; each element of which is the standard deviation of the corresponding ; vector in the input array. ; ; For example, if A is an array with dimensions of (3,4,5), then the ; command B = SIGMA(A,N,1) is equivalent to ; ; B = FLTARR(3,5) ; FOR J = 0,4 DO BEGIN ; FOR I = 0,2 DO BEGIN ; B(I,J) = SIGMA( A(I,*,J) , N ) ; ENDFOR ; ENDFOR ; RESTRICTIONS: ; Dimension specified must be valid for the array passed; otherwise the ; input array is returned as the output array. ; PROCEDURE: ; Uses the function AVG. ; When DIMENSION is passed, then the function SUM is used. ; MODIFICATION HISTORY: ; William Thompson Applied Research Corporation ; July, 1986 8201 Corporate Drive ; Landover, MD 20785 ; Converted to Version 2 July, 1990 ;- ON_ERROR,2 S = SIZE(ARRAY) IF S(0) EQ 0 THEN MESSAGE,'*** Variable must be an array, name= ARRAY' ; IF N_PARAMS(0) EQ 3 THEN BEGIN IF ((DIMENSION GE 0) AND (DIMENSION LT S(0))) THEN BEGIN SIG = SQRT( AVG(ARRAY^2,DIMENSION) - AVG(ARRAY,DIMENSION)^2 ) N = S(DIMENSION+1) END ELSE $ MESSAGE,'*** Dimension out of range, name= ARRAY' END ELSE BEGIN DIFF = ARRAY - AVG(ARRAY) SIG = SQRT( AVG( DIFF*DIFF )) N = N_ELEMENTS(ARRAY) ENDELSE ; IF N_PARAMS(0) GE 2 THEN SIG = SIG * SQRT( N / ((N - N_PAR) > 1.) ) ; RETURN,SIG END pro imgclean,img,h,cr,$ SKY_VAL_SAMP_SZ = SKY_VAL_SAMP_SZ, FINE_CLEAN = FINE_CLEAN, $ HI_SCAN_HEIGHT = HI_SCAN_HEIGHT, LO_SCAN_HEIGHT = LO_SCAN_HEIGHT, $ STAR_PSF_SENS = STAR_PSF_SENS, PHASE1_ITER = PHASE1_ITER, $ HELP = HELP, TESTRUN = TESTRUN, NOCLEAN = NOCLEAN $ , interactive=interactive ;QPHOT = QPHOT qphot not supported if (n_elements(help) eq 1) then goto,PRNT_HELP if (n_params(0) lt 1) then begin print,'Call> IMGCLEAN,image_array,header,[returned_CR_array],[several keywords]' print,'e.g.> IMGCLEAN,img1,h1,cr1' print,"Type> IMGCLEAN,/HELP for parameter listing/default values" return endif s=size(img) if (s(0) ne 2) then goto,PRNT_HELP if (n_elements(SKY_VAL_SAMP_SZ) eq 0) then SKY_VAL_SAMP_SZ=10. if (n_elements(HI_SCAN_HEIGHT) eq 0) then HI_SCAN_HEIGHT=6. if (n_elements(LO_SCAN_HEIGHT) eq 0) then LO_SCAN_HEIGHT=1.5 if (n_elements(STAR_PSF_SENS) eq 0) then STAR_PSF_SENS=.35 if (n_elements(FINE_CLEAN) eq 0) then FINE_CLEAN=1 if (n_elements(PHASE1_ITER) eq 0) then PHASE1_ITER=2 if (n_elements(testrun) eq 0) then testrun=0 if (n_elements(qphot) eq 0) then qphot=0 if (n_elements(noclean) eq 0) then noclean=0 if (testrun eq 1) then openw,5,'imgclean.dmp' if (qphot ge 1) then begin openw,8,'qphot.dmp' qphot,img,-999,-999 endif if keyword_set(interactive) then begin ICversion='1.41' print,'[IMGclean '+ICversion+'] MESSAGE: Released 05-JAN-1993. ' print,' Please report problems or bugs to deutsch@stsci.edu.' print,' Suggestions for improvement are welcome.' print,' Include example images (or portions thereof) if possible.' endif s=size(img) NAXIS1=s(1) & NAXIS2=s(2) cr=bytarr(NAXIS1,NAXIS2) flag=2 ; yboxes=100 & xboxes=100 & flag=0 ; manual override while (flag ge 2) do begin xboxes=NAXIS1/SKY_VAL_SAMP_SZ & yboxes=NAXIS1/SKY_VAL_SAMP_SZ if (xboxes eq fix(xboxes)) and (yboxes eq fix(yboxes)) then flag=0 if (flag ge 14) then flag=1 if (flag ge 2) then begin if (SKY_VAL_SAMP_SZ eq 16) and ((flag and 4) eq 0) then begin SKY_VAL_SAMP_SZ=10. & flag=flag+4 & endif if (SKY_VAL_SAMP_SZ eq 10) and ((flag and 8) eq 0) then begin $ SKY_VAL_SAMP_SZ=16. & flag=flag+8 & endif if (SKY_VAL_SAMP_SZ ne 10) and (SKY_VAL_SAMP_SZ ne 16) then $ SKY_VAL_SAMP_SZ=10. endif endwhile if (flag eq 1) then begin print,'[IMGClean] WARNING: Axes are not multiples of either 10 or 16.' print,' Using boxsize of ',strn(fix(SKY_VAL_SAMP_SZ)), $ '. Edges of image may not be cleaned.' xboxes=NAXIS1/SKY_VAL_SAMP_SZ & yboxes=NAXIS1/SKY_VAL_SAMP_SZ endif xboxes=fix(xboxes) & yboxes=fix(yboxes) xboxsz=NAXIS1/xboxes & yboxsz=NAXIS2/yboxes hipix=0L & lopix=0L & phase=0 PH1ITER: if keyword_set(interactive) then begin print,'PHASE 1(Iteration ',strn(phase+1),'): Scanning for High Pixels (Stars and CRs)....' print,' High Scan height: ',strn(HI_SCAN_HEIGHT),'*RMS' print,' Low Scan height: ',strn(LO_SCAN_HEIGHT),'*RMS' endif for y=0,yboxes-1-phase do begin for x=0,xboxes-1-phase do begin tmp=1 & crtmp=1 tmp=extrac(img,(x+phase/2.)*xboxsz,(y+phase/2.)*yboxsz,xboxsz,yboxsz) skyline,tmp,skyv,rms,interactive lo=where(tmp gt skyv+rms*LO_SCAN_HEIGHT) chk=size(lo) if (chk(0) ne 0) then begin crtmp=cr((x+phase/2.)*xboxsz:(x+phase/2.+1)*xboxsz-1, $ (y+phase/2.)*yboxsz:(y+phase/2.+1)*yboxsz-1) crtmp(lo)=70 cr((x+phase/2.)*xboxsz:(x+phase/2.+1)*xboxsz-1, $ (y+phase/2.)*yboxsz:(y+phase/2.+1)*yboxsz-1)=crtmp lopix=lopix+n_elements(lo) endif high=where(tmp gt skyv+rms*HI_SCAN_HEIGHT) chk=size(high) if (chk(0) ne 0) then begin crtmp=cr((x+phase/2.)*xboxsz:(x+phase/2.+1)*xboxsz-1, $ (y+phase/2.)*yboxsz:(y+phase/2.+1)*yboxsz-1) crtmp(high)=120 cr((x+phase/2.)*xboxsz:(x+phase/2.+1)*xboxsz-1, $ (y+phase/2.)*yboxsz:(y+phase/2.+1)*yboxsz-1)=crtmp hipix=hipix+n_elements(high) endif endfor if keyword_set(interactive) then begin if (y/5 eq y/5.) then $ print,strn(fix((y+1)*yboxsz*100./NAXIS2),length=3),'% complete:', $ strn(hipix,length=5),' high pixels found',lopix,' low-level pixels found' endif endfor lopix=0L & hipix=0L if (PHASE1_ITER eq 2) and (phase eq 0) then begin phase=1 & goto,PH1ITER & endif no_crpix=0 & no_cr=0 & no_starpix=0 & no_star=0 & t2=0 no_adj_CR=0 & no_adj_CR_pix=0 if keyword_set(interactive) then begin print,'PHASE 2: Identifying High Pixels (Stars or CRs)....' endif for y=0,NAXIS2-1 do begin band=where(cr(*,y) eq 120) chk=size(band) if (chk(0) ne 0) then begin for i=0,n_elements(band)-1 do begin current=lonarr(20) & t1=0 & flag=0 current(t1)=band(i) & t1=t1+1 & starti=i while (flag eq 0) do begin if (i eq n_elements(band)-1) or (t1 eq 19) then flag=2 if (flag eq 0) then begin if (band(i) eq band(i+1)-1) then begin i=i+1 & current(t1)=band(i) & t1=t1+1 endif else begin flag=1 endelse endif endwhile if (flag ne 0) then begin cent=starti+t1/2 starchck,img,band(cent),y,ratio,radius,skyv,rms,test=testrun, $ crim=cr,sens=STAR_PSF_SENS,qphot=qphot,noclean=noclean $ , interactive=interactive if (ratio lt STAR_PSF_SENS) then begin is_a_CR=0 no_starpix=no_starpix+t1 & no_star=no_star+1 endif else begin is_a_CR=1 no_crpix=no_crpix+t1 & no_cr=no_cr+1 tmp=extrac(img,band(cent)-7,y-7,15,15) skyline,tmp,skyv,rms,interactive endelse seed=skyv for t2=starti,i do begin if (is_a_CR eq 1) then begin cr(band(t2),y)=255 n_rnd=n_elements(band(t2)) & rnd=fltarr(n_rnd) for rndi=0,n_rnd-1 do rnd(rndi)=randomu(seed)*rms*1.5-rms*.5 img(band(t2),y)=skyv+rnd endif endfor if (is_a_CR eq 1) and (band(starti) gt 0) and (band(i) lt NAXIS1-1) $ and (y gt 0) and (y lt NAXIS2-1) then begin subcr=extrac(cr,band(starti)-1,y-1,band(i)-band(starti)+3,3) lowcr=where(subcr eq 70) chk=size(lowcr) if (chk(0) ne 0) then begin subimg=extrac(img,band(starti)-1,y-1,band(i)-band(starti)+3,3) n_rnd=n_elements(lowcr) & rnd=fltarr(n_rnd) for rndi=0,n_rnd-1 do rnd(rndi)=randomu(seed)*rms*1.5-rms*.5 subimg(lowcr)=skyv+rnd subcr(lowcr)=200 img(band(starti)-1:band(i)+1,y-1:y+1)=subimg cr(band(starti)-1:band(i)+1,y-1:y+1)=subcr no_adj_CR=no_adj_CR+1 no_adj_CR_pix=no_adj_CR_pix+n_elements(lowcr) endif endif endif ;;;if (skyv gt 200) then print,' Large Sky!: ',skyv,rms if (skyv gt 200 and keyword_set(interactive)) then begin print,' Large Sky!: ',skyv,rms endif endfor endif if keyword_set(interactive) then begin if (y/25. eq y/25) then $ print,strn(fix((y+1)*100./NAXIS2),length=2),'% complete', $ ': (Ln-Obj,Pix): CRs=',vect([no_cr,no_crpix]), $ ' AdjCRs=',vect([no_adj_CR,no_adj_CR_pix]), $ ' Stars=',vect([no_star,no_starpix]) endif endfor if keyword_set(interactive) then begin print,'*** Final: ', $ ': (Ln-Obj,Pix): CRs=',vect([no_cr,no_crpix]), $ ' AdjCRs=',vect([no_adj_CR,no_adj_CR_pix]), $ ' Stars=',vect([no_star,no_starpix]) endif if (testrun eq 1) then close,5 if (qphot eq 1) then close,8 s=size(h) if (n_elements(s) lt 3) then return if (s(2) ne 7) then return on_error,2 ; return if no SX routines available tmp=sxpar(h,'IC_CRSRM') & iter='_' if (!ERR ge 0) then begin i=2 & next=9 while (i lt 8) do begin tmp=sxpar(h,'IC'+strn(i)+'CRSRM') if (!ERR lt 0) then begin & next=i & i=9 & endif i=i+1 endwhile iter=strn(next) endif sxaddhist,'[IMGclean '+ICversion+'] '+!stime+': IC'+iter+' keywords added',h sxaddpar,h,'IC'+iter+'CRSRM',no_crpix,' Number of CR pixels removed' sxaddpar,h,'IC'+iter+'ADJRM',no_adj_CR_pix,' Number of pixels adjacent to CRs removed' sxaddpar,h,'IC'+iter+'STRPX',no_starpix,' Pixels part of a star (not removed)' sxaddpar,h,'IC'+iter+'SMPSZ',SKY_VAL_SAMP_SZ,' Size of Box for local Sky Value' sxaddpar,h,'IC'+iter+'HISCN',HI_SCAN_HEIGHT,' RMSs above sky for HI classif.' sxaddpar,h,'IC'+iter+'LOSCN',LO_SCAN_HEIGHT,' RMSs above sky for LO classif.' sxaddpar,h,'IC'+iter+'PSFSN',STAR_PSF_SENS,' Sensitivity of Star/CR Discrimination' sxaddpar,h,'IC'+iter+'FINCL',FINE_CLEAN,' Adjacent Pixels removed? (1=Yes)' sxaddpar,h,'IC'+iter+'PH1IT',PHASE1_ITER,' Iterations of Phase 1 (Find)' return PRNT_HELP: print,'Call> IMGCLEAN,image_array,header,[returned_CR_array],[optional keywords] print,'Keywords: print,' SKY_VAL_SAMP_SZ Default: 10.0 pixels squared' print,' HI_SCAN_HEIGHT Default: 6.0 RMS units above local sky' print,' LO_SCAN_HEIGHT Default: 1.5 RMS units above local sky' print,' STAR_PSF_SENS Default: 0.35 height to volume ratio' print,' FINE_CLEAN Default: 1 (TRUE) (Remove highish adjacent pixels' print,' PHASE1_ITER Default: 2 iterations (each iteration slightly different).' return end