pro stisnoise,file,freq,magnitude,exten=exten,outfile=outfile,db=db,$ dc=dc,digfilter=digfilter,median=median,boxcar=boxcar,lee=lee,wipe=wipe,$ window=window if n_params(0) lt 3 then begin print,'stisnoise, file,freq,magnitude,exten=exten,outfile=outfile,db=db,' print,'dc=dc,digfilter=digfilter,median=median,boxcar=boxcar,lee=lee,' print,'wipe=wipe,window=window' return endif ; Description: computes an FFT on STIS CCD frames to evaluate fixed ; pattern noise. Fixed pattern noise is most obvious in FFT of bias frames. ; Optional filtering to correct the fixed pattern noise is provided ; through keywords median, boxcar, lee, digfilter, wipe, & window. Filtered ; data can be saved as an output file. ; Author: Thomas M. Brown (STScI) ; Input: ; file= STIS FITS file (or database number if db=1) ; Output: ; freq = frequency in power spectrum (hz) ; magnitude = magnitude in power spectrum ; Optional input (keywords): ; exten = fits extension to be read (or readout if db=1) ; dc: when 0 (default), the power in the first freq bin is set to zero ; to allow easier plotting of the power spectrum. ; digfilter = 4-element array specifying the digital filter parameters: ; flow, fhigh, power relative to Gibbs (50 is good), nterms. ; Note: flow>fhigh for band stop, flow rotate by 180 degrees if amp eq 'D' then image=rotate(temp,2) else $ ; amp A data -> leave as is if amp eq 'A' then image=temp else $ ; amp B data -> flip left<->right if amp eq 'B' then image=reverse(temp,1) else $ ; amp C data -> flip top<->bottom if amp eq 'C' then image=reverse(temp,2) else begin print,'No amplifier given in header. Aborting.' return endelse ; CONVERT 2-D ARRAY TO 1-D TIME SERIES nx = nc + pps time_series = fltarr(nx*nr) ds = fltarr( pps ) for i=0, nr-1 do begin time_series[i*nx] = image[*,i] time_series[i*nx+nc] = ds + median( image[*,i] ) ; pad dead-time ; (note that non-integer nx prevents phase wandering) endfor ; BEGIN FILTERING OPTIONS ************** ; frequency filtering using digital_filter algorithm if keyword_set(digfilter) then begin nyqf=1.0/(2*sst*1.0e-6) ; Nyquist frequency flow=digfilter[0]/nyqf ; define frequency boundaries fhigh=digfilter[1]/nyqf powgibbs=digfilter[2] nterms=digfilter[3] print,"Filtering with flow = ",flow," and fhigh = ",fhigh,$ " (in terms of Nyquist frequency)",f='(a,f5.3,a,f5.3,a)' coeff=digital_filter(flow,fhigh,powgibbs,nterms) time_series=convol(time_series,coeff) endif ; median filtering if keyword_set(median) then begin time_series=median(time_series,median) endif ; boxcar smoothing if keyword_set(boxcar) then begin time_series=smooth(time_series,boxcar) endif ; Lee filter if keyword_set(lee) then begin time_series=leefilt(time_series,lee[0],lee[1],/exact) endif ; wipe frequencies in fft and reverse transform if keyword_set(wipe) then begin ntime=n_elements(time_series) ; if ntime is an odd number the fft will take forever so make ; it even with a small prime factor sum (not as quick as power of 2 but ; still much quicker). ; Note that padding data out to next power of two is too much padding ; (number of elements is just a bit over 2^20 for STIS data) if type eq 'raw' then ntimep=ntime+13 else ntimep=ntime+7 t2=fltarr(ntimep) t2[0]=time_series freq=findgen(ntimep)/(ntimep * sst * 1.0e-6) freq[(ntimep/2+1):(ntimep-1)]=reverse(freq[1:(ntimep/2-1)]) tran=fft(t2) ind=where(freq gt wipe[0] and freq lt wipe[1]) tran[ind]=tran[ind]*wipe[2] inv=fft(tran,/inverse) time_series=(float(inv))[0:ntime] endif ; window filter ; gradually wipe frequencies in fft and reverse transform if keyword_set(window) then begin ntime=n_elements(time_series) ; if ntime is an odd number the fft will take forever so make ; it even with a small prime factor sum (not as quick as power of 2 but ; still much quicker). ; Note that padding data out to next power of two is too much padding ; (number of elements is just a bit over 2^20 for STIS data) if type eq 'raw' then ntimep=ntime+13 else ntimep=ntime+7 t2=fltarr(ntimep) t2[0]=time_series freq=findgen(ntimep)/(ntimep * sst * 1.0e-6) freq[(ntimep/2+1):(ntimep-1)]=reverse(freq[1:(ntimep/2-1)]) tran=fft(t2) filter=fltarr(ntimep)+1.0 ind=where(freq gt (window[0]-window[1]/2.0) and $ freq lt (window[0]+window[1]/2.0)) filter[ind]=0.0 freqstep=1.0/(ntimep * sst * 1.0e-6) width=window[2]/freqstep ; specify window width in freq steps sigma=width/2.354820044 ; convert fwhm to sigma kernw=fix(5*sigma) ; make kernel have width of 5 sigma if (kernw mod 2) eq 0 then kernw=kernw+1 ; make kernel odd kernx=findgen(kernw) gauss,kernx,kernw/2,sigma,1.0,kerny ; gaussian kernel kerny=kerny/total(kerny) filterc=convol(filter,kerny,/edge_truncate,/center) tran=tran*filterc inv=fft(tran,/inverse) time_series=(float(inv))[0:ntime] endif ; END FILTERING OPTIONS ; RECREATE 2-D IMAGE FROM TIME SERIES outimage=fltarr(nc,nr) for i=0,nr-1 do begin outimage[*,i]=time_series[i*nx:(i*nx+nc-1)] endfor if type eq 'flt' then outimage=outimage[nos:(nc0-nos-1),*] ; RESTORE ORIGINAL IMAGE ORIENTATION ; amp D data -> rotate by 180 degrees if amp eq 'D' then outimage=rotate(outimage,2) else $ ; amp A data -> leave as is if amp eq 'A' then outimage=outimage else $ ; amp B data -> flip left<->right if amp eq 'B' then outimage=reverse(outimage,1) else $ ; amp C data -> flip top<->bottom if amp eq 'C' then outimage=reverse(outimage,2) ; TRIM VECTOR TO POWER OF 2 FOR FFT ; (this is the fastest fft calculation but it doesn't preserve all ; data, as needed in wipe routine above) p2 = fix( alog( nx*nr ) / alog(2) ) n_ts = 2L ^ p2 time_series = time_series[0:n_ts-1] ; PERFORM FFT AND RETURN FIRST HALF nt = n_ts / 2 fft_output = fft( time_series ) magnitude = (abs( fft_output ))[0:nt-1] real_part = float( fft_output ) imag_part = imaginary( fft_output ) freq = findgen(nt) / (2 * nt * sst * 1.0e-6) if dc eq 0 then magnitude[0]=0 ; set first bin in power spectrum ; to zero unless dc=0 if keyword_set (outfile) then begin if (db) then begin writefits,outfile,outimage,header ; write header & data from IDT stis_read endif else begin writefits,outfile,0,header ; write primary header then append ext writefits,outfile,outimage,extheader,/append endelse endif return end