pro nis_c_darksep,seq_in, obs_target, indir1, indir2, dark1,dark2,noise_mode, $ seq_out, sourcedir,verbose, voltcor, volterr, dark_mode, head ; SUB-PROGRAM of nis_proc ; ; ABSTRACT ; Removes dark spectra from nis data. Most darks are interleaved with spectra. ; this program is used when darks are not interleaved, but rather are ; dedicated sequences of shutter-closed dark spectra that bracket ; the acquired sequence of spectra in time (Dark mode 1 or 2, and 4 as a) ; special case ; ; INPUTS ; seq_in - sequence of averaged spectra from nis_c_div ; indir - directory where input files are located ; dark1,2 - filenames for the bracketing darks for dark_mode=1 ; noise_mode - how spectra serror is determined ; 0 = error determined from average of all dark ; spectra in sequence (Default) ; 1 = initial error predetermined from file of 300 ; averaged dark spectra ; sourcedir - source directory for NISCAL programs and data ; verbose - Toggle description of events std output ; dark_mode - Source of Dark for calibration ; This procedure is for dark_modes 1 2, and 4 ; voltcor - Motor Voltge correction from table ; volterr - Motor Voltge noise from table ; ; OUTPUTS ; seq_out - array of data spectra with dark subtracted ; ; USES ; nis_c_div - for dark sequences ; sxpar - creads header data for keyword ; eprop_sumdif - to propagate error from dark subtraction ; ; HISTORY ; Adapted 02/05/98 by N. R. Izenberg from nis_c_dark ; 07/15/98 (NRI) v2.0 Eliminate nis_parse_head and nis_extract. ; CNFF modifications ; 08/31/99 (NRI) v3.5 Fix interpolation for leading/trailing darks ; 02/17/00 (NRI) v3.9 Kill setting negative data to zero. This ; interfered with dark analysis by artificially ; removing variability in the data ; 05/04/00 (NRI) v4.1 Replace sz with sxpar(head,'NAXIS2') ; 06/08/00 (NRI) v4.2 Fix single sepdark multple spectra division ; 06/15/00 (NRI) v4.2 Change Motor Voltage correction ; from single file to table driven files ; 07/20/01 (NRI) v5.0 Compliant (mainly CNISF 5.0) ; ; NOTES ; From NIS sequence data: ; IDL columns 1 and 2 define MET high and low word ; CNISF 5.0 column 9 = shutter in/out (0 = in) ; CNISF 5.0 Data is 131:194 for Calibration ; CNISF 5.0 Data is 195:258 for Noise ;------------------------------------------------------------------------------ ; Main print," >>>> dark_sep subroutine (modes 1,2,4)" err_in=seq_in(195:258,*) seq_out=seq_in NAX=sxpar(head,'NAXIS2') ; number of spectra, read from header Fname=sxpar(head,'NEAR-003') FMET=double(strmid(fname,3,9)) ;MET of start spectrum if dark_mode ne 4 then begin ; Extract darks ;-------------- dark_1=readfits(indir1+dark1,dheader_dat1) dark_2=readfits(indir2+dark2,dheader_dat2) dark_1=float(dark_1) dark_2=float(dark_2) ; Divide by # spectra for average darks and dark error ; most dark only arrays will be several observartions of single spectra ;---------------------------------------------------- o_t = strmid(dark1,16,1) if sxpar(dheader_dat1,'NAXIS2') gt 1 then $ nis_c_div,dark_1, dark_arr1, dark_mode, o_t, sourcedir, verbose, $ dheader_dat1 else $ dark_arr1=dark_1/dark_1(25); divide by number of spectra o_t = strmid(dark2,16,1) if sxpar(dheader_dat2,'NAXIS2') gt 1 then $ nis_c_div,dark_2, dark_arr2, dark_mode, o_t, sourcedir, verbose, $ dheader_dat2 else $ dark_arr2=dark_2/dark_2(25) dark_err1=dark_arr1(195:258,*) dark_err2=dark_arr2(195:258,*) ; Average darks ;-------------- darkav1=fltarr(64) darkav2=fltarr(64) darker1=fltarr(64) darker2=fltarr(64) for i=0,63 do begin darkav1(i)=mean(dark_arr1(131+i,*)) darkav2(i)=mean(dark_arr2(131+i,*)) darker1(i)=0.0 darker2(i)=0.0 if ((size(dark_arr1))(0) gt 1) then darker1(i)=stdev(dark_arr1(131+i,*)) if ((size(dark_arr2))(0) gt 1) then darker2(i)=stdev(dark_arr2(131+i,*)) endfor endif else begin ; Dark_mode 4 looks to fixed library file for reference dark subtraction. refdark = fltarr(64) openr,unit,sourcedir+'lib_tables/nis_default_dark.dat',/get_lun readf,unit,refdark close,unit,/all darkav1=refdark darkav2=refdark darker1=refdark *.01 ; fix 1% noise for refdark darker2=refdark *.01 ; fix 1% noise for refdark endelse ;darkavs are the average preceeding and following darks. Need to interpolate ;them for each line of the spectrum. That size is NAX ;------------------------------------------------------ ; OR Read NAXIS out of header avdif=(darkav2-darkav1)/(NAX-1) erdif=(darker2-darker1)/(NAX-1) ;Interpolate dark for subtraction ;-------------------------------- dark_arr = fltarr(64,NAX) dark_err = fltarr(64,NAX) for i=0,NAX-1 do begin dark_arr(*,i)=darkav1+avdif*i dark_err(*,i)=darker1+erdif*i endfor ; 2. Apply voltage correction ; IF dark_mode is 1 or 0. If mode is 2, then darks are open space dark, ; and the motoer voltage correction is not needed. ;-------------------------------------------------------------------- if dark_mode le 1 or dark_mode eq 4 then begin for m= 0,NAX-1 do begin dark_arr(*,m)=dark_arr(*,m)+voltcor dark_err(*,m)=eprop_sumdif(dark_err(*,m),volterr) endfor endif ; Right now, dark_err is determined by a lookup table from an ; average of 300 dark spectra. If the noise_mode 0 is selected, the error ; will be the average of the dark spectra from the sequence curently ; being calibrated. The advantage is that the error is now closely ; associated with the spectra in time. The disadvantage is that less ; than 300 dark measurements will probably result in higher noise, as the ; standard deviation of a smaller number of spectra will be higher. ;---------------------------------------------------------------------------- if noise_mode eq 0 then begin mean_err=fltarr(64) for n=0,63 do begin mean_err(n)=eprop_sumdif(darker1(n), darker2(n)) endfor for o=0,NAX-1 do begin dark_err(*,o)=mean_err endfor endif ; Now run through all the spectra and subtract the dark ; need the appropriate interleave step. ;----------------------------------------------------- for l = 0,NAX-1 do begin seq_out(131:194,l)=seq_in(131:194,l)- dark_arr(*,l) seq_out(195:258,l)=eprop_sumdif(err_in(*,l),dark_err(*,l)) endfor if verbose eq 1 then print,' STEP 3: background removed' return end