;+ ; NAME: ; getspec ; PURPOSE: ; Extract a point source spectrum from OSIRIS XD data. ; DESCRIPTION: ; CATEGORY: ; Spectroscopy ; CALLING SEQUENCE: ; getspec,calib,root,i1,i2,spec,all, ; RAW=raw,NONEG=noneg,AUTO=auto,MASK=mask ; INPUTS: ; calib- Anonymous structure containing all pertinent calibration ; information. This structure is usually loaded beforehand using ; the routine, "ldcalir" ; root - string containing the root of the file name (with leading path ; if desired). DO NOT include the . between the root and suffix. ; i1 - Frame id (integer) of first image. ; i2 - Frame id (integer) of second image. ; OPTIONAL INPUT PARAMETERS: ; KEYWORD INPUT PARAMETERS: ; AUTO - Flag, if true, enables automatic aperture location for extracting ; the spectra. The image is collapsed into a single column. Any ; pixel more than 3 sigma from the background is flagged for ; extraction. Default is to require clicking on the image displayed ; in window 0. Three rows centered on the clicked location are ; extracted for the spetrum. /AUTO is the preferred option. ; APLOC- Override to specify the positive object location. Overrides AUTO. ; APSIZE-Override to force the size of the extraction aperture. The ; will extend from the location (auto or APLOC) + and - by APSIZE. ; Thus the total aperture is 2*APSIZE+1 rows. ; NONEG - Flag, if true, inhibits using the "negative" spectrum in the ; background image (i2). Default is to extact the negative ; spectrum, negate it, and add to the positive spectrum. ; RAW - Flag, if true will inhibit the column-wise background subtraction. ; The default is to fit the background in each column (along the ; slit) and subtract the fitted background. Use a linear function ; for the background. ; MASK - Indicies in strip image. These pixels will be replaced by the ; average of their nearest neighbors in the x direction. ; SAVE - Flag, if true, final spectrum will be saved to a file. The output ; file name is root+'s'+suffix. Thus 950911.003 would be saved to ; the file 950911s.003 ; PATH - optional string that points to the directory containing the data. ; This information is not used if the root already begins with '/'. ; If root is not an absolute pathname, then PATH is prepended to ; root for READ operations. This path is not used for saving. ; This allows reading from one directory (possible a read only area) ; and then saving to the current directory. ; CLEAN - Flag, if set, calls clnspec to allow removing bad points before ; saving spectrum. ; ; OUTPUTS: ; spec - 1-D spectrum extracted from spectral image. ; all - i1-i2 after XD spectra extracted to strip image. (see getpair) ; KEYWORD OUTPUT PARAMETERS: ; COMMON BLOCKS: ; SIDE EFFECTS: ; RESTRICTIONS: ; Specifically written for OSIRIS cross-dispersed spectral data. MASK ; does not work particularly well. ; PROCEDURE: ; MODIFICATION HISTORY: ; 95/03/24, Written by Marc W. Buie, Lowell Observatory ; 95/06/21, MWB, modified aperture algorithm. ; 95/09/14, MWB, added calib structure pass through, added SAVE flag, added ; PATH keyword, added CLEAN flag. ; 95/09/18, MWB, improved auto-aperture locating algorithm ; 95/09/21, MWB, added APLOC and APSIZE keywords ;- pro getspec,calib,root,i1,i2,spec,all, $ RAW=raw,NONEG=noneg,AUTO=auto,MASK=mask,SAVE=save,PATH=path,CLEAN=clean, $ APSIZE=apsize,APLOC=aploc if badpar(calib,8,1,CALLER='getspec (calib) ') then return if badpar(root,7,0,CALLER='getspec (root) ') then return if badpar(i1,[2,3],0,CALLER='getspec (i1) ') then return if badpar(i2,[2,3],0,CALLER='getspec (i2) ') then return if badpar(raw,[0,1,2,3],0,CALLER='getspec (RAW) ',DEFAULT=0) then return if badpar(save,[0,1,2,3],0,CALLER='getspec (SAVE) ',DEFAULT=0) then return if badpar(apsize,[0,1,2,3],0,CALLER='getspec (APSIZE) ',DEFAULT=0) then return if badpar(aploc,[0,1,2,3],0,CALLER='getspec (APLOC) ',DEFAULT=-1) then return if badpar(clean,[0,1,2,3],0,CALLER='getspec (CLEAN) ',DEFAULT=0) then return if badpar(auto,[0,1,2,3],0,CALLER='getspec (AUTO) ',DEFAULT=0) then return if badpar(mask,[0,2,3],[0,1],CALLER='getspec (MASK) ',DEFAULT=-1) then return if badpar(path,[0,7],0,caller='getspec: (path) ',default='./') then return if aploc ne -1 then auto=0 loadct,5,/silent if strmid(root,0,1) eq '/' then begin newroot = root endif else begin newroot = addslash(path)+root endelse ; Load two images and display print,'positive image ',i1,' negative image ',i2 getpair,calib,newroot,i1,i2,all,hdr,raw=raw,mask=mask sz=size(all) nrows=sz[2] ncols=sz[1] setwin,0,/show,xsize=ncols,ysize=nrows*3 erase tvscl,all,0 ; construct average column profile, done over a restricted range for S/N avgcol=fltarr(nrows) cut=all[220:380,*] for i=0,380-220-1 do begin cut[i,*]=cut[i,*]/max(cut[i,*]) endfor for i=0,calib.height-1 do begin robomean,cut[*,i],3,.5,avg avgcol[i]=avg endfor ; plot profile setwin,2,/show plot,avgcol ; show image, scaled on sky setwin,0 robomean,all,3,.5,avg,dummy,stddev tv,bytscl(all,min=avg-3.0*stddev,max=avg+3.0*stddev,top=127),1 ; Determine range of rows to sum ; Automatic location of object spectra if auto then begin posrowpos=where(avgcol eq max(avgcol[2:33])) posrowpos=posrowpos[0] if not keyword_set(noneg) then begin negrowpos=where(avgcol eq min(avgcol[2:33])) negrowpos=negrowpos[0] endif else begin negrowpos = -1 endelse ; Manual location for object spectra endif else begin if aploc eq -1 then begin print,'Click on positive object spectrum' cursor,x,posrowpos,/wait,/change,/device endif else begin posrowpos = aploc endelse posrowpos = posrowpos mod calib.height print,'Positive object at row ',posrowpos if not keyword_set(noneg) then begin print,'Click on negative object spectrum' cursor,x,negrowpos,/wait,/up,/device print,'Negative object at row ',negrowpos endif else begin negrowpos = -1 endelse endelse ; Replot the average column with mean background +- 3 sigma limits overlaid setwin,2 idx=indgen(n_elements(avgcol)) coeff=goodpoly(idx,avgcol,1,2.2,f_col,newx,newy,EXCLUDE=6) robomean,newy-poly(newx,coeff),3,.5,bavg,dummy,bstddev plot,avgcol for i=230,240 do $ oplot,idx,all[i,*]/max(abs(all[i,*])),color=45 oplot,avgcol oplot,avgcol,psym=8,symsize=0.7,color=70 oplot,idx,f_col+bavg+3.0*bstddev,color=55 oplot,idx,f_col+bavg-3.0*bstddev,color=55 posap=where( (avgcol-f_col-bavg gt 3.0*bstddev) and $ (abs(idx-posrowpos) lt 4) ,count) if apsize ne 0 then begin apleft = posrowpos - apsize apright = posrowpos + apsize print,'NOTE: manual aperture size used.' endif else if count ne 0 then begin apleft=min(posap)-1 apright=max(posap)+1 endif else begin apleft=posrowpos-2 apright=posrowpos+2 print,'WARNING: normal aperture location find failed.' endelse oplot,newx,newy,psym=8 setusym,-1 oplot,idx[apleft:apright],avgcol[apleft:apright], $ psym=8,color=96,symsize=1.5 setusym,1 ; Add annotation for negative image if wanted. if not keyword_set(noneg) then begin negap=where( (avgcol lt f_col-3.0*bstddev) and $ (abs(idx-negrowpos) lt 4) ,count) if (count ne 0) then begin oplot,idx[negap],avgcol[negap],psym=4,color=96,symsize=1.5 endif endif ;Now we know where the object is so redo background subtraction while ; leaving out the object rows. if save or clean then begin badloc=where( abs(avgcol-f_col-bavg) gt 3.0*bstddev, countbad ) if countbad ne 0 then begin setwin,0 backsub,all,/col,order=1,exclude=badloc tv,bytscl(all,min=avg-3.0*stddev,max=avg+3.0*stddev,top=127),2 endif endif ; Sum up rows in the aperture. posobj=fltarr(ncols) negobj=fltarr(ncols) for ii=apleft,apright do posobj=posobj+all[*,ii] if negrowpos ge 0 then $ for ii=0,n_elements(negap)-1 do negobj=negobj+all[*,negap[ii]] ; Compute final spectrum for output and plot it against pixels and wavelength spec = posobj-negobj setwin,1,/show plotspec,calib,spec setwin,3 plot,posobj if not keyword_set(noneg) then oplot,-negobj,color=60 setwin,1 ; Clean spectrum if requested. if clean then clnspec,calib,spec ; Save spectrum if requested. if save then begin outname = root+'s.'+string(i1,form='(i3.3)') sxaddpar,hdr,'HISTORY','Background from frame '+string(i2) writefits,outname,spec,hdr endif end