;+ ; NAME: ; xdavg ; PURPOSE: ; Interactive tool for combining and correcting OSIRIS XD spectra. ; DESCRIPTION: ; ; This program handles the removal of instrumental defects from OSIRIS XD ; spectra. This is accomplished through the removal of bad points in the ; data from bad pixels on the NICMOS chip, applying slope corrections to the ; spectra to remove the effects of wavelength dependent vignetting, and the ; exclusion of bad spectra from the averaging process. ; ; CATEGORY: ; Spectroscopy ; CALLING SEQUENCE: ; xdavg ; INPUTS: ; ; OPTIONAL INPUT PARAMETERS: ; ; KEYWORD INPUT PARAMETERS: ; ; OUTPUTS: ; ; Spectra selected in the tool are displayed in cw_osipl. The final products ; consist of the individual corrected spectra and their averages. These ; spectra have had all the badflag editting done, primary slope correction ; applied to make them consistent within a set, all the bad spectra excluded, ; and have had the secondary slope correction applied relative to some ; reference. A preliminary amount of ratioing is also done in which these ; corrected spectra are ratioed against either one other corrected average or ; an airmass corrected denominator interpolated between two of these ; corrected averages. Each individual ratio is saved as well as the average ; of the set. The badflags for each spectrum are also saved. ; ; File format for each type is: ; ; Individual corrected spectra - Spec/yymmddc.### where ### is the index ; number of the spectrum. These have both ; the primary and secondary slope corrections ; applied but the flux in the file is still ; in units of [counts]. ; ; Average corrected spectra - Corr/yymmdda.## where ## is the set number of ; the average. These are weighted set averages ; and the "flux" values are all in counts/sec. ; ; Individual ratio spectra - Ratio/yymmddr.### where ### is the index number ; of the spectrum. ; ; Average ratio spectra - Ratio/yymmdda.## where ## is the set number of the ; average. ; ; Badflags have the same file format as their corresponding parents and are ; in the same directory except they are "b." files instead. ; ; KEYWORD OUTPUT PARAMETERS: ; ; COMMON BLOCKS: ; ; SIDE EFFECTS: ; ; RESTRICTIONS: ; ; At present, you cannot remove all spectra in a set (flag with X) with ; this tool. You must edit the .tbl file by hand in this case. ; ; PROCEDURE: ; ; This program begins by loading the information regarding the nights worth of ; data by loading the table and calibration files from whichever directory ; that has been selected. Next, the user can select to display whichever ; spectra that help in the process of removing the instrumental defects and ; edit them accordingly. The primary slope correction is applied ; automatically to the spectra. Spectra may also be excluded from the ; averages by means of either an x or s flag. ; ; The bulk of the editting of this type should be accomplished before moving on ; to making ratios with the bottom part of the tool and applying the ; secondary slope correction manually. You begin by selecting one numerator ; as the reference denominator and then getting the night consistent by ; applying the secondary slope correction to various ratios. Moving the an ; object into the denominator is also the point at which the various product ; spectra are saved to disk. ; ; Instance structure locations ; state - First child of XDAVG ; Contains all widget ids. ; ; tbl - UVALUE of state.cwdid (current working directory) ; Contains the contents of the observation summary table as ; generated by XDSPEC. Also has derived information about ; groups of observations. ; ; calib - UVALUE of state.tblnameid (name of current table file). ; This is the calibration structure as read in by ldcalir ; ; oblist - UVALUE of state.tblnsetid ; ; spec - UVALUE of state.butspecid (Structure containing the various ; levels of processed spectra as well as flags indicating how ; far each has been processed). ; ;------------------------------------------------------------------------------- ; Internal Support Procedures: ; ; xdavg_chngdir : Handles updating the widget for a directory change ; xdavg_crunch : Calculates various spectra ; xdavg_loadtbl : Loads the table file ; xdavg_mkidx : Creates indices for spectra for various selections ; xdavg_mkidx1 : Creates indices for spectra only for sets ; xdavg_mkratio : Calculates ratio spectra ; xdavg_plot : Handles plotting spectra for top part of tool ; xdavg_plot2 : Handles plotting spectra for bottom part of tool ; xdavg_refresh : Makes sure that editting changes progagate to saved spectra ; xdavg_setrefresh : Displays information about a set of selected spectra ; xdavg_tblrefresh : Displays information abuot a night's worth of data ; xdavg_eve : Event handler ; ;------------------------------------------------------------------------------- ; MODIFICATION HISTORY: ; 1998/06/09, Written by Marc W. Buie, Lowell Observatory and ; 1998/06/10 - 1998/08/05, Chris Dalla Piazza, Lycoming College ; 1998/09/08, MWB, numerous changes, most recently allowing more than 2 ; denominators. ;- PRO xdavg_chngdir,state,value cd,'.',current=old_dir fn = STRTRIM( value[0], 2 ) catch,error_status IF error_status ne 0 THEN BEGIN print,fn,' is not a valid directory.' fn='' WIDGET_CONTROL, state.cwdid, SET_VALUE=old_dir return ENDIF cd,fn catch,/cancel IF fn ne '' THEN BEGIN IF old_dir eq fn THEN BEGIN print,'Directory not changed, new directory same as old.' ENDIF ELSE BEGIN ; Destroy the lock file if state.lock ne -1 then begin free_lun,state.lock state.lock=-1 endif print,'Directory changed to ',fn WIDGET_CONTROL, state.cwdid, SET_VALUE=fn state.root='' ENDELSE xdavg_loadtbl,state ; do stuff for new directory ENDIF END ;------------------------------------------------------------------------------- ; Procedure xdavg_crunch ; ; This procedure handles the calculation and loading of the spectra that are ; used by xdavg. It receives a "request" for the level of processing that is ; desired and fills in the spec structure accordingly. There are also flags to ; indicate whether or not these calculations have been made yet ; ; The following request numbers correspond to the following spectra: ; ; 1 - the raw spectra and badflags are simply loaded from disk ; 2 - the raw spectra relative to their raw group mean are calculated ; 3 - the primary slope correction is applied to the raw spectra ; 4 - the the primary slope corrected spectra relative to the raw group mean are ; calculated ; 5 - the average of the primary slope corrected spectra is made and if this set ; is in the denominator list (and therefore a secondary slope correction has ; been committed to) the secondary slope correction is applied to the ; average and saved in a separate place ;------------------------------------------------------------------------------- PRO xdavg_crunch,state,idx,idx1,request WIDGET_CONTROL,state.tblnameid, GET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, GET_UVALUE=spec,/NO_COPY ; Load the raw spectra if they haven't been already for i=0,n_elements(idx)-1 do begin if spec.s[idx[i]] eq 0 then begin ; Load the raw spectra fn='Spec/'+state.root+'s.'+string(tbl.imnum[idx[i]],format='(i3.3)') if exists(fn) then spec.raw[*,idx[i]]=readfits(fn,/silent) ; Load the bad flags fn='Spec/'+state.root+'b.'+string(tbl.imnum[idx[i]],format='(i3.3)') if exists(fn) then begin openr,lun,fn,/get_lun dummy=bytarr(calib.npts) readu,lun,dummy spec.bad[*,idx[i]]=dummy free_lun,lun endif spec.s[idx[i]]=1 endif endfor ; Exit the procedure if you've fulfilled the requested state of processing if request eq 1 then begin WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY return endif ; Create the raw spectra relative to the raw group mean if spec.s[idx[0]] lt 2 then begin osismean,spec.raw[*,idx],spec.bad[*,idx],relsig,avgspec,badsum,/norm tbl.relsig[idx] = relsig tbl.dirty=1 spec.avg[*,idx1]=avgspec spec.afl[*,idx1]=badsum ; Create the relative spectra spec.rel[*,idx]=1.0 for i=0,n_elements(idx)-1 do begin zg=where(finite(spec.raw[*,idx[i]]) eq 1 and $ spec.avg[*,idx1] ne 0.0,count) if count ne 0 then $ spec.rel[zg,idx[i]] = $ spec.raw[zg,idx[i]]/tbl.relsig[idx[i]]/spec.avg[zg,idx1] endfor spec.s[idx]=2 endif ; Exit the procedure if you've fulfilled the requested state of processing if request eq 2 then begin WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY return endif ; Create the slope corrected spectra if spec.s[idx[0]] lt 3 then begin for i=0,n_elements(idx)-1 do begin ; Get the slope correction and apply it osidvfit,calib,spec.raw[*,idx[i]],spec.avg[*,idx1],fit, $ BAD=spec.bad[*,idx[i]] osislope,calib,spec.raw[*,idx[i]],fit,outspec spec.cor[*,idx[i]]=outspec endfor spec.s[idx]=3 endif ; Exit the procedure if you've fulfilled the requested state of processing if request eq 3 then begin WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY return endif ; Create the slope corrected spectra relative to the mean of the raw spectra if spec.s[idx[0]] lt 4 and request eq 4 then begin spec.cdv[*,idx]=1.0 for i=0,n_elements(idx)-1 do begin zg=where(finite(spec.cor[*,idx[i]]) eq 1 and $ spec.avg[*,idx1] ne 0.0,count) if count ne 0 then $ spec.cdv[zg,idx[i]]=spec.cor[zg,idx[i]]/spec.avg[zg,idx1] endfor spec.s[idx]=4 endif ; Exit the procedure if you've fulfilled the requested state of processing if request eq 4 then begin WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY return endif ; Make the new average spectra if spec.s2[idx1] eq 0 then begin ; Make the average spectrum of the slope corrected spectra to the raw ; group mean specset = spec.cor[*,idx] bad = spec.bad[*,idx] for j=0,n_elements(idx)-1 do $ specset[*,j] = specset[*,j]/tbl.exptim[idx[j]] cavgspec,specset,bad,avgspec,avgspec_sig,rbad,/weighted,wfactor=wfactor spec.cav[*,idx1] = avgspec spec.cavs[*,idx1] = avgspec_sig spec.bfl[*,idx1] = rbad spec.awf[idx] = wfactor ; spec.cav[*,idx1]=0.0 ; tot=fltarr(calib.npts) ; for j=0,n_elements(idx)-1 do begin ; mask=1.0-spec.bad[*,idx[j]] ; spec.cav[*,idx1]=spec.cor[*,idx[j]]*mask+spec.cav[*,idx1] ; tot=tot+mask ; endfor ; ; z=where(tot ne 0.0) ; spec.cav[z,idx1]=spec.cav[z,idx1]/tot[z] ; spec.afl[*,idx1]=1 ; spec.afl[z,idx1]=0 ; Only apply the secondary slope correction to the averages that are in ; the denominator if strlen(spec.lst[idx1]) gt 2 then begin fit=fltarr(2,calib.nor) fit[0,*]=1.0 ; Get the secondary slope correction from the fits header if spec.s3[idx1] eq 0 then begin fn='Corr/'+state.root+'a.'+string(idx1,format='(i2.2)') if exists(fn) then begin hdr=headfits(fn) spec.slp[idx1]=sxpar(hdr,'SLOPEFIX') endif else begin spec.slp[idx1]=0.0 endelse spec.s3[idx1]=1 endif fit[1,*]=spec.slp[idx1] osislope,calib,spec.cav[*,idx1],fit,outspec spec.cr2[*,idx1]=outspec osislope,calib,spec.cavs[*,idx1],fit,outerr spec.cr2s[*,idx1]=outerr spec.s2[idx1]=1 endif endif WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY END PRO xdavg_loadtbl, state ; Get current table information WIDGET_CONTROL, state.cwdid, GET_UVALUE=tbl, /NO_COPY ; Save the current table file if it's loaded and has been changed. if tbl.nobs ne 0 then begin if tbl.dirty then wrtbl,state.root+'.tbl',tbl tbl.dirty=0 endif reload=0 lscmd = '"ls" ' ; if root is blank, try to figure it out. IF state.root eq '' THEN BEGIN cd,'.',current=cwd ; root, derived from current directory. pos = rstrpos(cwd,'/') root = strmid(cwd,pos+1,99) reload=1 ENDIF ELSE BEGIN spawn,lscmd+' -l '+tbl.name,result IF result[0] ne state.tbldate THEN reload=1 state.tbldate = result[0] root = state.root ENDELSE IF reload THEN BEGIN IF exists('files.cal') THEN BEGIN ldcalir,'files.cal',calib,valid,/silent,/noflat IF not valid THEN BEGIN print,'calibration support file, files.cal, is invalid.' state.root='' state.tbldate='' root='' calib={nor:0} ENDIF WIDGET_CONTROL, state.tblnameid, GET_UVALUE=oldcalib, /NO_COPY WIDGET_CONTROL, state.tblnameid, SET_UVALUE=calib, /NO_COPY ENDIF ELSE BEGIN print,' Calibration information file, files.cal, does not exist.' print,' This directory is probably does not contain XDSPEC results.' state.root='' state.tbldate='' root='' ENDELSE ENDIF IF reload and root ne '' THEN BEGIN name = root+'.tbl' IF exists(name) THEN BEGIN ; Check to see if there is a lock file and make one if there isn't if exists('xdavg.lock') then begin spawn,'ls -l xdavg.lock',result print,'Lock file '+result print,' exists, Cannot continue.' state.root='' state.tbldate='' endif else begin cd,'.',current=dir openw,lock,dir+'/xdavg.lock',/get_lun,/delete state.lock=lock rdtbl,name,tbl tblparse,tbl,oblist,badset state.root = root spawn,lscmd+' -l '+tbl.name,result state.tbldate = result[0] IF badset or max(oblist[2,*]) ne 0 THEN BEGIN print,'The 2d-extraction reductions with XDSPEC are not complete on this' print,'dataset. You should exit this program and run XDSPEC to completion' print,'before continuing with XDAVG.' ENDIF WIDGET_CONTROL, state.tblnsetid, GET_UVALUE=oldoblist, /NO_COPY WIDGET_CONTROL, state.tblnsetid, SET_UVALUE=oblist, /NO_COPY endelse ENDIF ELSE BEGIN print,' Information table file (',name,') does not exist.' print,' This directory is probably does not contain XDSPEC results.' state.root='' state.tbldate='' ENDELSE ENDIF IF state.root eq '' THEN tbl={nobs:0} WIDGET_CONTROL, state.cwdid, SET_UVALUE=tbl, /NO_COPY IF reload or state.root eq '' THEN BEGIN xdavg_tblrefresh,state state.idx1=-1 xdavg_setrefresh,state ENDIF END ;------------------------------------------------------------------------------- ; Function xdavg_mkidx ; ; This function returns the index numbers of the spectra currently selected by ; the top part of the xdavg tool. This can be one index number for one selected ; spectrum, the index numbers for the set, or the index numbers for the whole ; night. Spectra flagged as x or s are not included in this index ;------------------------------------------------------------------------------- function xdavg_mkidx,state WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, GET_UVALUE=oblist,/NO_COPY ; Make the index of all spectra in the group CASE state.numshow OF 0: BEGIN idx=oblist[0,state.idx1]+state.idx2 END 1: BEGIN idx=indgen(oblist[1,state.idx1]-oblist[0,state.idx1]+1)+ $ oblist[0,state.idx1] END 2: BEGIN idx=where(tbl.imtype eq 'o') END ENDCASE ; Filter out those that have been x-ed or s-ed out tmp=where(tbl.imflag[idx] eq '-') idx=idx[tmp] WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, SET_UVALUE=oblist,/NO_COPY return,idx end ;------------------------------------------------------------------------------- ; Function xdavg_mkidx1 ; ; This function returns the index numbers of the spectra for a given set with ; those that have been marked as x or s filtered out ;------------------------------------------------------------------------------- function xdavg_mkidx1,state,idx1 WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, GET_UVALUE=oblist,/NO_COPY ; Make the index of all spectra in the group idx=indgen(oblist[1,idx1]-oblist[0,idx1]+1)+oblist[0,idx1] ; Filter out those that have been x-ed or s-ed out tmp=where(tbl.imflag[idx] eq '-') idx=idx[tmp] WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, SET_UVALUE=oblist,/NO_COPY return,idx end ;------------------------------------------------------------------------------- ; Procedure xdavg_mkratio ; ; This procedure is responsible for calculating the ratio spectra and their ; badflags given a numerator and denominator(s). If one numerator is supplied ; then a straight ratio is made. It there are more, then the airmass correction ; is applied by objratio. The individual ratios are made as well as the average ; of them with no secondary slope correction applied. The last ratio made for ; the numerator is also stored so that recalculating it can be avoided. ;------------------------------------------------------------------------------- PRO xdavg_mkratio,state,num,denlist idx=xdavg_mkidx1(state,num) WIDGET_CONTROL,state.tblnameid, GET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, GET_UVALUE=spec,/NO_COPY ; This flag indicates whether or not an average needs to be made of the ; individual ratios, this is necessary if they have been recomputed avgflag=0 if n_elements(denlist) eq 1 then begin ; Make the individual ratio spectra if they haven't been calculated yet if spec.r[num,0] ne denlist[0] or spec.r[num,1] ne -1 then begin spec.rat[*,idx]=1.0 for i=0,n_elements(idx)-1 do begin zg=where(finite(spec.cor[*,idx[i]]) eq 1 and $ spec.cr2[*,denlist[0]] ne 0.0,count) spec.rat[zg,idx[i]]=spec.cor[zg,idx[i]]/spec.cr2[zg,denlist[0]]/ $ tbl.exptim[idx[i]] spec.rbd[*,idx[i]] = spec.bad[*,idx[i]] or spec.bfl[*,denlist[0]] zg=where((finite(spec.cor[*,idx[i]]) eq 0 or $ spec.cr2[*,denlist[0]] eq 0.0) and $ spec.rbd[*,idx[i]] eq 0,count) if count ne 0 then begin print,'XDAVG: ',count,' values found in making ratio (.rat) where the values' print,'are bad but the bad flags do not help. ',tbl.fn[idx[i]] endif endfor ; Save the denominator list to make sure that the ratios are not ; recalculated unnecessarily spec.r[num,0]=denlist[0] spec.r[num,1]=-1 avgflag=1 endif endif else begin ; Prepare parameters for objratio and get the ratioed, airmass corrected ; spectra back if it hasn't already been calculated if total(spec.r[num,0:n_elements(denlist)-1] ne denlist) gt 0 or $ total(spec.r[num,*] ne -1) ne n_elements(denlist) then begin object=spec.cor[*,idx] for i=0,n_elements(idx)-1 do $ object[*,i] = object[*,i]/tbl.exptim[idx[i]] o_bad=spec.bad[*,idx] o_am=tbl.airmas[idx] o_times=tbl.jd[idx] comps=spec.cr2[*,denlist] c_bad=spec.bfl[*,denlist] c_am=fltarr(n_elements(denlist)) c_times=c_am for i=0,n_elements(denlist)-1 do begin WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY idx0=xdavg_mkidx1(state,denlist[i]) WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY c_am[i]=mean(tbl.airmas[idx0]) c_times[i]=(min(tbl.jd[idx0])+max(tbl.jd[idx0]))/2.0 endfor objratio,calib,object,o_am,o_times,comps,c_am,c_times,ratio, $ O_BAD=o_bad,C_BAD=c_bad,R_BAD=r_bad spec.rat[*,idx]=ratio spec.rbd[*,idx]=r_bad ; Save the denominator list to make sure that the ratios are not ; recalculated unnecessarily spec.r[num,*]=-1 spec.r[num,0:n_elements(denlist)-1]=denlist avgflag=1 endif endelse if avgflag then begin ; Make the average of these spectra specset = spec.rat[*,idx] bad = spec.rbd[*,idx] cavgspec,specset,bad,avgspec,avgspec_sig,rbad,/weighted,wfactor=wfactor spec.rav[*,num]=avgspec spec.ravs[*,num]=avgspec_sig spec.arb[*,num]=rbad spec.rwf[idx]=wfactor spec.ravjd[num]=(min(tbl.jd[idx])+max(tbl.jd[idx]))/2.0 endif WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY END ;------------------------------------------------------------------------------- ; Procedure xdavg_plot ; ; This procedure is responsible for displaying the selected spectra from the top ; of the xdavg tool. It makes sure that the requested spectra have been loaded ; or calculated and then extracts the spectra and related information that will ; be needed by cw_osipl. ;------------------------------------------------------------------------------- PRO xdavg_plot,state WIDGET_CONTROL,state.mainbase, UPDATE=0 ; Figure out what the index range is for the spectra to be processed is and ; run xdavg_crunch. ; Only one index is required if an individual spectrum is to be viewed raw. ; For all other situations, an entire group must be processed at a time and ; only that group's indices can be passed into xdavg_crunch at a time. For ; show all, the sets are processed and indices made up for each group if state.shospec ne 4 or state.pageflag eq 0 then begin if state.shospec eq 3 then request=4 else request=state.shospec if state.shospec eq 1 and state.numshow eq 0 then begin idx=xdavg_mkidx(state) xdavg_crunch,state,idx,state.idx1,request endif else begin if state.numshow le 1 then begin idx=xdavg_mkidx1(state,state.idx1) xdavg_crunch,state,idx,state.idx1,request endif else begin WIDGET_CONTROL, state.tblnsetid, GET_VALUE=nobj nobj=fix(nobj) for i=0,nobj-1 do begin idx=xdavg_mkidx1(state,i) xdavg_crunch,state,idx,i,request endfor endelse endelse endif ; Make the index of spectra that will actually be displayed in cw_osipl idx=xdavg_mkidx(state) if state.numshow eq 2 and state.shospec eq 4 then begin ; Filter out spectra that have no ratios WIDGET_CONTROL, state.tblnsetid, GET_VALUE=nobj flag=bytarr(n_elements(idx)) for i=0,fix(nobj)-1 do begin fn='Ratio/'+state.root+'a.'+string(i,format='(i2.2)') WIDGET_CONTROL,state.butspecid, GET_UVALUE=spec,/NO_COPY test=spec.r[i,0] WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY if test ne -1 or exists(fn) then begin idxtmp=xdavg_mkidx1(state,i) idxbegin=where(idx eq idxtmp[0]) flag[idxbegin[0]:idxbegin[0]+n_elements(idxtmp)-1]=1 endif endfor z=where(flag eq 1) idx=idx[z] endif WIDGET_CONTROL,state.tblnameid, GET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, GET_UVALUE=oblist,/NO_COPY WIDGET_CONTROL,state.butspecid, GET_UVALUE=spec,/NO_COPY ; Load the profiles if they haven't been loaded and if they exist if state.profile eq 0 then begin for i=0,n_elements(idx)-1 do begin if spec.p[idx[i]] eq 0 then begin fnpro='Spec/'+state.root+'p.'+string(tbl.imnum[idx[i]],format= $ '(i3.3)') if exists(fnpro) then begin readcol,fnpro,val1,val2,val3,val4,val5,FORMAT='I,F,A,F,F',/silent spec.idx[*,idx[i]]=val1 spec.prf[*,idx[i]]=val2 spec.flg[*,idx[i]]=val3 spec.ubd[*,idx[i]]=val4 spec.lbd[*,idx[i]]=val5 spec.p[idx[i]]=1 endif endif endfor endif ; Extract the spectra needed for osipl case state.shospec of 1: display=spec.raw[*,idx] 2: display=spec.rel[*,idx] 3: display=spec.cdv[*,idx] 4: begin case state.numshow of 0: idx1=state.idx1 1: idx1=state.idx1 2: begin idx1=indgen(n_elements(oblist)/3) end endcase display=fltarr(calib.npts,n_elements(idx)) dennam=strarr(n_elements(idx)) fit=fltarr(2,calib.nor) fit[0,*]=1.0 k=0 for i=0,n_elements(idx1)-1 do begin WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, SET_UVALUE=oblist,/NO_COPY idxtmp=xdavg_mkidx1(state,idx1[i]) WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, GET_UVALUE=oblist,/NO_COPY ; Load any ratio spectra that are on disk but not already in memory ; and get the names of the denominators for plotting purposes for ; all the existing ratio spectra if spec.r[idx1[i],0] ne -1 then begin for j=0,n_elements(idxtmp)-1 do begin dummy=where(idx eq idxtmp[j],cnt) if cnt ne 0 then begin if idx1[i] eq state.num then begin fit[1,*]=state.slope2 endif else fit[1,*]=spec.slp[idx1[i]] osislope,calib,spec.rat[*,idxtmp[j]],fit,outspec display[*,k]=outspec dennam[k]=' / '+string(spec.r[idx1[i],0],format= $ '(i2.2)')+' '+tbl.objnam[oblist[0,spec.r[idx1[i],0]]] if spec.r[idx1[i],1] ne -1 then begin dennam[k]=dennam[k]+' and '+string(spec.r[idx1[i],1], $ format='(i2.2)')+' '+ $ tbl.objnam[oblist[0,spec.r[idx1[i],1]]] endif k=k+1 endif endfor endif else begin fn='Ratio/'+state.root+'a.'+string(idx1[i],format='(i2.2)') if exists(fn) then begin hdr=headfits(fn) denlist=sxpar(hdr,'DEN*') dennamtmp=' / '+strcompress(string(denlist)) for j=0,n_elements(idxtmp)-1 do begin dummy=where(idx eq idxtmp[j],cnt) if cnt ne 0 then begin fn='Ratio/'+state.root+'r.'+ $ string(tbl.imnum[idxtmp[j]],format='(i3.3)') spec.rat[*,idxtmp[j]]=readfits(fn,/silent) fn='Ratio/'+state.root+'b.'+ $ string(tbl.imnum[idxtmp[j]],format='(i3.3)') openr,lun,fn,/get_lun bad=spec.bad[*,0] readu,lun,bad spec.rbd[*,idxtmp[j]]=bad free_lun,lun help,dennam,dennamtmp,display,k display[*,k]=spec.rat[*,idxtmp[j]] dennam[k]=dennamtmp k=k+1 endif endfor endif endelse endfor end endcase badflag=spec.bad[*,idx] ; Figure out the index number of the prefered spectrum if state.pref eq -1 then begin pref=0 endif else begin pref=where(idx eq state.pref)+1 endelse ; Define and fill the data structure to be plotted if state.shospec ne 4 then begin objname=tbl.objnam[idx] endif else begin objname=tbl.objnam[idx]+dennam endelse data={nspecs: n_elements(idx), $ calib: calib, $ pref: pref, $ filenam: tbl.fn[idx], $ objname: objname, $ display: display, $ badflag: badflag, $ pflag: state.profile, $ cflag: 0, $ pageflg: state.pageflag, $ prof: spec.prf[*,idx], $ index: spec.idx[*,idx], $ upbnd: spec.ubd[*,idx], $ lwbnd: spec.lbd[*,idx], $ relsig: tbl.relsig[idx], $ mate: tbl.mate[idx], $ airmass: tbl.airmas[idx], $ juldate: tbl.jd[idx], $ exptime: tbl.exptim[idx], $ ncoads: tbl.avego[idx] $ } ; Reset the page check flag state.pageflag=0 WIDGET_CONTROL,state.butspecid, SET_UVALUE=spec,/NO_COPY WIDGET_CONTROL,state.tblnameid, SET_UVALUE=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, SET_UVALUE=oblist,/NO_COPY ; Create the plot compound widget if necessary and plot the data valid=WIDGET_INFO(state.plotid,/VALID_ID) if not valid then begin state.plotid=cw_osipl(state.mainbase,0,TITLE='Component Spectra Plotter') endif widget_control,state.plotid,/map WIDGET_CONTROL,state.plotid,SET_VALUE=data WIDGET_CONTROL,state.mainbase, UPDATE=1 END ;------------------------------------------------------------------------------- ; Procedure xdavg_plot2 ; ; This procedure is responsible for displaying the selected ratios from the ; bottom of the xdavg tool. It makes sure that the related spectra have been ; calculated and applies the secondary slope correction to the ratios before ; displaying them. It waits until now to apply the secondary slope correction ; because it has not been committed to yet and is adjusted interactively by the ; user. The spectra and related information are then extracted for cw_osipl ;------------------------------------------------------------------------------- PRO xdavg_plot2,state ; Put the numerator and denominator selections into one index to make loading ; the necessary data easier denlist=widget_info(state.denid,/list_select) n=n_elements(denlist)+1 totidx=intarr(n) totidx[0]=state.num totidx[1:n-1]=denlist ; Make sure that the numerator and denominator spectra have been processed to ; the point that the slope corrected spectra relative to the raw group mean ; have been created, the averages of these spectra, and that the secondary ; slope correction has been applied to those averages in the denominator for i=0,n-1 do begin idx=xdavg_mkidx1(state,totidx[i]) xdavg_crunch,state,idx,totidx[i],5 endfor ; Make sure that the ratios have been created xdavg_mkratio,state,state.num,denlist ; Define and fill the data structure for the plot widget widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, GET_UVALUE=oblist,/NO_COPY display=fltarr(calib.npts,1) badflag=intarr(calib.npts,1) filenam=strarr(1) objname=strarr(1) ; Apply the current secondary slope correction before displaying the ratio fit=fltarr(2,calib.nor) fit[0,*]=1.0 fit[1,*]=state.slope2 osislope,calib,spec.rav[*,state.num],fit,outspec display=outspec badflag=spec.arb[*,state.num] filenam[0]=string(state.num,format='(i2.2)')+' '+ $ tbl.objnam[oblist[0,state.num]]+' /' if n_elements(denlist) eq 1 then begin objname[0]=string(state.den,format='(i2.2)')+' '+ $ tbl.objnam[oblist[0,state.den]] endif else begin objname[0]=string(denlist[0],format='(i2.2)')+' '+ $ tbl.objnam[oblist[1,denlist[0]]]+' and '+string(denlist[1], $ format='(i2.2)')+' '+tbl.objnam[oblist[1,denlist[1]]] endelse data={nspecs: 1, $ calib: calib, $ pref: 1, $ filenam: filenam, $ objname: objname, $ display: display, $ badflag: badflag, $ pflag: 1, $ ; no profile cflag: 1, $ pageflg: state.pageflag, $ airmass: 0.0, $ juldate: spec.ravjd[state.num], $ exptime: tbl.exptim[idx], $ ncoads: tbl.avego[idx] $ } ; Create the plot widget if necessary and set its value to the data structure valid=WIDGET_INFO(state.plotid2,/VALID_ID) if not valid then begin state.plotid2=cw_osipl(state.mainbase,1,TITLE='Ratio Spectra Plotter') endif widget_control,state.plotid2,/map state.map2=1 widget_control,state.svslopid,sensitive=1 widget_control,state.plotid2,set_value=data widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY WIDGET_CONTROL,state.tblnsetid, SET_UVALUE=oblist,/NO_COPY ; Refresh the top plot widget if ratios are being displayed and the effected ; ratio is being displayed or show all has been selected if state.shospec eq 4 then begin if state.numshow eq 2 then xdavg_plot,state else begin ; Check to see if the plotter contains an effected spectrum if state.num eq state.idx1 then xdavg_plot,state endelse endif END ;------------------------------------------------------------------------------- ; Procedure xdavg_rawrelcln ; ; This procedure will run the raw relative set cleaner on the current set. ;------------------------------------------------------------------------------- pro xdavg_rawrelcln,state ; Make sure that the spectra are loaded for the entire set idx=xdavg_mkidx1(state,state.idx1) xdavg_crunch,state,idx,state.idx1,1 ; Clean the spectra and save the badflags widget_control,state.ratdvalid,get_value=dval dval=float(dval[0]) WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY tmpbad=spec.bad[*,idx] osiclean,calib,spec.raw[*,idx],tmpbad,DVAL=dval dirty=0 for i=0,n_elements(idx)-1 do begin if total(spec.bad[*,idx[i]] eq tmpbad[*,i]) ne n_elements(tmpbad[*,i]) then begin fn='Spec/'+state.root+'b.'+string(tbl.imnum[idx[i]],format='(i3.3)') openw,lun,fn,/get_lun writeu,lun,tmpbad[*,i] free_lun,lun dirty=1 endif endfor spec.bad[*,idx]=tmpbad widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY if dirty then xdavg_refresh,state,state.idx1 end ;------------------------------------------------------------------------------- ; Procedure xdavg_refresh ; ; This procedure is responsible for making sure that edits made to spectra carry ; through their changes to the various spectra in memory, saved on disk and ; currently displayed in the plot widgets. The spectra in memory need not be ; recalculated immediately, just their flags reset so that the next time they ; are requested, they will be recalculated. Since all spectra at a higher level ; then the raw spectra are made in sets, the sets are checked for the existence ; of saved spectra on disk and recalculated where necessary. This includes all ; saved ratio spectra that have the effected set as a denominator. The plot ; widgets are only refreshed if the effected set is a part of what they are ; displaying. ;------------------------------------------------------------------------------- PRO xdavg_refresh,state,idx1 ; Reset flags so that spectra will be recomputed for i=0,n_elements(idx1)-1 do begin idx=xdavg_mkidx1(state,idx1[i]) widget_control,state.butspecid,get_uvalue=spec,/NO_COPY for j=0,n_elements(idx)-1 do if spec.s[idx[j]] gt 1 then spec.s[idx[j]]=1 spec.s2[idx1]=0 spec.r[idx1[i],*]=-1 z=where(spec.r[*,0] eq idx1[i]) if z[0] ne -1 then spec.r[z,*]=-1 z=where(spec.r[*,1] eq idx1[i]) if z[0] ne -1 then spec.r[z,*]=-1 widget_control,state.butspecid,set_uvalue=spec,/NO_COPY endfor ; Check to see if the affected set has been saved as a denominator, if it ; hasn't then there are no affected files saved to disk for i=0,n_elements(idx1)-1 do begin widget_control,state.butspecid,get_uvalue=spec,/NO_COPY test=strlen(spec.lst[idx1[i]]) widget_control,state.butspecid,set_uvalue=spec,/NO_COPY if test gt 2 then begin ; Recompute the spectra for the c files and save them to disk idx=xdavg_mkidx1(state,idx1[i]) xdavg_crunch,state,idx,idx1[i],5 ; Save the average and its badflags, remaking the header WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY outdata = [[spec.cr2[*,idx1[i]]],[spec.cr2s[*,idx1[i]]]] mkhdr,hdr,outdata sxdelpar,hdr,'DATE' sxaddpar,hdr,'OBJECT',strcompress(tbl.objnam[idx[0]]) sxaddpar,hdr,'JD',spec.ravjd[state.num], $ ' Effective mid-time of spectrum',format='f13.5' exptim=tbl.exptim[idx[0]]*tbl.avego[idx[0]]*n_elements(idx) sxaddpar,hdr,'EXPTIME',strcompress(exptim), $ ' Total integration time of spectrum (seconds)' sxaddpar,hdr,'AIRMASS',mean(tbl.airmas[idx]),'Mean airmass of spectrum' sxaddpar,hdr,'INSTRUME','OSIRIS XD' for j=0,n_elements(idx)-1 do begin sxaddpar,hdr,'SPEC'+string(j+1,format='(i2.2)'),state.root+'c.'+ $ string(tbl.imnum[idx[j]],format='(i3.3)'), $ string(spec.awf[idx[j]],format='(" weight =",f5.3)') endfor sxaddpar,hdr,'SLOPEFIX',strcompress(spec.slp[state.num]), $ ' Secondary slope correction' fn='Corr/'+state.root+'a.'+string(idx1[i],format='(i2.2)') writefits,fn,outdata,hdr ; Save the badflags fn='Corr/'+state.root+'b.'+string(idx1[i],format='(i2.2)') openw,lun,fn,/get_lun writeu,lun,spec.bfl[*,idx1[i]] free_lun,lun ; Get the headers from the existing s files and save the new files fit=fltarr(2,calib.nor) fit[0,*]=1.0 fit[1,*]=spec.slp[idx1[i]] for j=0,n_elements(idx)-1 do begin fn='Spec/'+state.root+'c.'+string(tbl.imnum[idx[j]],format='(i3.3)') hdr=headfits(fn) sxaddpar,hdr,'SLOPEFIX',strcompress(spec.slp[idx1[i]]), $ ' Secondary slope correction' osislope,calib,spec.cor[*,idx[j]],fit,outspec writefits,fn,outspec,hdr endfor ; Recompute the ratios that are on disk for which this spectrum is a ; numerator unless it is the first denominator if idx1[i] ne state.priden then begin fn='Ratio/'+state.root+'a.'+string(idx1[i],format='(i2.2)') hdr=headfits(fn) denlist=sxpar(hdr,'DEN*') WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY ; Make sure that the spectra for the denominators have been made for j=0,n_elements(denlist)-1 do begin idxtmp=xdavg_mkidx1(state,denlist[j]) xdavg_crunch,state,idxtmp,denlist[j],5 endfor xdavg_mkratio,state,idx1[i],denlist WIDGET_CONTROL,state.cwdid,GET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.tblnsetid,GET_UVALUE=oblist,/NO_COPY for j=0,n_elements(idx)-1 do begin ; Save the individual ratios fn='Ratio/'+state.root+'r.'+string(tbl.imnum[idx[j]],format= $ '(i3.3)') hdr=headfits(fn) osislope,calib,spec.rat[*,idx[j]],fit,outspec writefits,fn,outspec,hdr ; Save the badflags fn='Ratio/'+state.root+'b.'+string(tbl.imnum[idx[j]],format= $ '(i3.3)') openw,lun,fn,/get_lun writeu,lun,spec.rbd[*,idx[j]] free_lun,lun endfor ; Save the average fn='Corr/'+state.root+'a.'+string(idx1[i],format='(i2.2)') hdr=headfits(fn) inum=1 for iden=0,n_elements(denlist)-1 do begin if denlist[iden] ne -1 then begin kwd='DEN'+strcompress(inum,/remove_all) sxaddpar,hdr,kwd,denlist[iden], $ ' Denominator spectrum group number' inum=inum+1 endif endfor for j=0,n_elements(idx)-1 do begin sxaddpar,hdr,'SPEC'+string(j+1,format='(i2.2)'),state.root+ $ 'r.'+string(tbl.imnum[idx[j]],format='(i3.3)'), $ string(spec.rwf[idx[j]],format='(" weight =",f5.3)') endfor osislope,calib,spec.rav[*,idx1[i]],fit,outspec osislope,calib,spec.ravs[*,state.num],fit,outerr fn='Ratio/'+state.root+'a.'+string(idx1[i],format='(i2.2)') outdata = [[outspec],[outerr]] writefits,fn,outdata,hdr ; Save the badflags fn='Ratio/'+state.root+'b.'+string(idx1[i],format='(i2.2)') openw,lun,fn,/get_lun writeu,lun,spec.arb[*,idx1[i]] free_lun,lun WIDGET_CONTROL,state.tblnsetid,SET_UVALUE=oblist,/NO_COPY endif ; Scan through the ratios saved to disk to make sure that non of them ; contain the effected spectrum as a denominator savlist=where(strlen(spec.lst) gt 2) z=where(savlist ne state.priden) if z[0] eq -1 then begin n=0 endif else begin savlist=savlist[z] n=n_elements(savlist) endelse for j=0,n-1 do begin fn='Ratio/'+state.root+'a.'+string(savlist[j],format='(i2.2)') hdr=headfits(fn) denlist=sxpar(hdr,'DEN*') dummy=where(denlist eq idx1[i],cnt) if cnt ne 0 then begin ; Make sure that the numerator of the effected ratio has had the ; necessary spectra calculated as well as its denominators WIDGET_CONTROL,state.cwdid,SET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY n1=n_elements(denlist)+1 totidx=intarr(n1) totidx[0:n1-2]=denlist totidx[n1-1]=savlist[j] for k=0,n1-1 do begin idx=xdavg_mkidx1(state,totidx[k]) xdavg_crunch,state,idx,totidx[k],5 endfor xdavg_mkratio,state,savlist[j],denlist ; Resave the average WIDGET_CONTROL,state.cwdid,GET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY slope2=sxpar(hdr,'SLOPEFIX') fit[1,*]=float(slope2) osislope,calib,spec.rav[*,savlist[j]],fit,outspec osislope,calib,spec.ravs[*,savlist[j]],fit,outerr outdata = [[outspec],[outerr]] writefits,fn,outdata,hdr ; Save its badflags fn='Ratio/'+state.root+'b.'+string(savlist[j],format='(i2.2)') openw,lun,fn,/get_lun writeu,lun,spec.arb[*,savlist[j]] free_lun,lun ; Resave the individual ratioed spectra for k=0,n_elements(idx)-1 do begin fn='Ratio/'+state.root+'r.'+string(tbl.imnum[idx[k]],format= $ '(i3.3)') hdr=headfits(fn) osislope,calib,spec.rat[*,idx[k]],fit,outspec writefits,fn,outspec,hdr ; Save the badflags fn='Ratio/'+state.root+'b.'+string(tbl.imnum[idx[k]],format= $ '(i3.3)') openw,lun,fn,/get_lun writeu,lun,spec.rbd[*,idx[k]] free_lun,lun endfor endif endfor WIDGET_CONTROL,state.cwdid,SET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY endif endfor ; Refresh the plots if they contain the affected spectra if state.map2 then begin denlist=widget_info(state.denid,/list_select) dummy=where(idx1 eq state.num,cnt1) dummy=where(idx1 eq denlist[0],cnt2) cnt=cnt1+cnt2 if n_elements(denlist) eq 2 then begin dummy=where(idx1 eq denlist[1],cnt3) cnt=cnt+cnt3 endif if cnt ne 0 then xdavg_plot2,state endif dummy=where(idx1 eq state.idx1,cnt) if cnt ne 0 then xdavg_plot,state END ;------------------------------------------------------------------------------- ; Procedure xdavg_setrefresh ; ; This procedure is responsible for displaying the information for a selected ; set of spectra as well as sensitizing buttons that manipulate the spectra. ; When a set is selected, a few widgets above the set list widget display ; imformation about the set and the list widget is filled. Buttons that ; manipulate the spectra are also sensitized now that there is something to ; edit. When no set is selected, there is nothing to edit so the buttons are ; desensitized and the information widgets are blanked out. ;------------------------------------------------------------------------------- PRO xdavg_setrefresh, state WIDGET_CONTROL, state.mainbase, UPDATE=0 IF state.idx1 eq -1 THEN BEGIN ; If there is no table file loaded, make sure that the set information ; widgets are all blank, that the plot widgets are unmapped, and that the ; buttons that manipulate the spectra are all desensitized WIDGET_CONTROL, state.setnameid, SET_VALUE='' WIDGET_CONTROL, state.setnobsid, SET_VALUE='' WIDGET_CONTROL, state.setgoodid, SET_VALUE='' WIDGET_CONTROL, state.setexptid, SET_VALUE='' WIDGET_CONTROL, state.setcoadid, SET_VALUE='' WIDGET_CONTROL, state.setamenid, SET_VALUE='' WIDGET_CONTROL, state.setaranid, SET_VALUE='' WIDGET_CONTROL, state.setlistid, SET_VALUE='', SENSITIVE=0 valid=WIDGET_INFO(state.plotid,/VALID_ID) if valid then WIDGET_CONTROL, state.plotid,map=0 valid=WIDGET_INFO(state.plotid2,/VALID_ID) if valid then WIDGET_CONTROL, state.plotid2,map=0 state.map2=0 WIDGET_CONTROL,state.butmarkid,SENSITIVE=0,set_value='Mark Bad Data' widget_control,state.autoclnid,sensitive=0,set_value= $ 'Auto Clean Raw Spectrum' widget_control,state.clrbadfid,sensitive=0,set_value='Clear Bad Flags' widget_control,state.clnratid,sensitive=0 widget_control,state.ratdvalid,sensitive=0 widget_control,state.butxoutid,sensitive=0 widget_control,state.butsoutid,sensitive=0 ENDIF ELSE BEGIN idx=xdavg_mkidx1(state,state.idx1) WIDGET_CONTROL, state.cwdid, GET_UVALUE=tbl, /NO_COPY WIDGET_CONTROL, state.tblnsetid, GET_UVALUE=oblist, /NO_COPY WIDGET_CONTROL, state.setnameid, SET_VALUE=tbl.objnam[idx[0]] ; Find the number of observations in the set nobs=oblist[1,state.idx1]-oblist[0,state.idx1]+1 WIDGET_CONTROL, state.setnobsid, SET_VALUE=strcompress(nobs) WIDGET_CONTROL, state.setgoodid, SET_VALUE=strcompress(n_elements(idx)) WIDGET_CONTROL, state.setexptid, SET_VALUE=strcompress(fix(tbl.exptim[ $ idx[0]])) WIDGET_CONTROL, state.setcoadid, SET_VALUE=strcompress(tbl.avego[idx[0]]) ; Find the mean airmass mean=mean(tbl.airmas[idx]) WIDGET_CONTROL, state.setamenid, SET_VALUE=string(mean,format='(f4.2)') ; Find the airmass range range=max(tbl.airmas[idx])-min(tbl.airmas[idx]) WIDGET_CONTROL, state.setaranid, SET_VALUE=string(range,format='(f4.2)') ; Create list of observations infolist=strarr(nobs) for i=oblist[0,state.idx1],oblist[1,state.idx1] do begin infolist[i-oblist[0,state.idx1]]=string(tbl.imflag[i],tbl.fn[i], $ tbl.relsig[i],format='(a2,1x,a10,1x,f6.4)') endfor WIDGET_CONTROL, state.setlistid, SET_VALUE=infolist, SENSITIVE=1, $ SET_LIST_SELECT=state.idx2 ; Update the messages on the buttons that manipulate the spectra and ; sensitize buttons that manipulate the spectra case state.numshow of 0: type=tbl.fn[oblist[0,state.idx1]+state.idx2] 1: type='Set' 2: type='All' endcase widget_control,state.clrbadfid,set_value='Clear '+type+' Bad Flags', $ sensitive=1 widget_control,state.autoclnid,set_value='Auto Clean Raw '+type, $ sensitive=1 widget_control,state.butmarkid,set_value='Edit '+ $ tbl.fn[oblist[0,state.idx1]+state.idx2],sensitive=1 widget_control,state.clnratid,sensitive=1 widget_control,state.ratdvalid,sensitive=1 widget_control,state.butxoutid,sensitive=1 widget_control,state.butsoutid,sensitive=1 WIDGET_CONTROL, state.tblnsetid, SET_UVALUE=oblist, /NO_COPY WIDGET_CONTROL, state.cwdid, SET_UVALUE=tbl, /NO_COPY ENDELSE WIDGET_CONTROL, state.mainbase, UPDATE=1 END ;------------------------------------------------------------------------------- ; Procedure xdavg_tblrefresh ; ; This procedure is responsible for effecting the changes to the various widgets ; associated with the loading or loss of the table file (basically the ; information for a nights worth of data). This not only includes displaying ; the new information that accompanies the appearance of a new table file but ; also desensitizing and blanking out widgets during the disappearance of a ; table file. When a new table file appears, information about the spectra are ; displayed in a few widgets above the table list, the table list is filled, the ; numerator and denominator list widgets are filled and a few widget buttons are ; sensitized now that there is something to manipulate. When the table file ; disappears, all these areas must be blanked out as well as the buttons which ; edit the spectra be desensitized. ;------------------------------------------------------------------------------- PRO xdavg_tblrefresh, state WIDGET_CONTROL, state.mainbase, UPDATE=0 IF state.root eq '' THEN BEGIN ; If there is no table file, make sure the table information widgets are ; blank and that the numerator and denominator widgets as well as the ; buttons that manipulate the them are desensitized WIDGET_CONTROL, state.tblnameid, SET_VALUE='No Data ' WIDGET_CONTROL, state.tblnobsid, SET_VALUE=' ' WIDGET_CONTROL, state.tblnsetid, SET_VALUE=' ' WIDGET_CONTROL, state.tblnordid, SET_VALUE=' ' WIDGET_CONTROL, state.tbllistid, SET_VALUE='', SENSITIVE=0 widget_control,state.numid,set_value='',sensitive=0 widget_control,state.denid,set_value='',sensitive=0 widget_control,state.svslopid,sensitive=0 widget_control,state.slopslid,sensitive=0 widget_control,state.clrlstid,sensitive=0 ENDIF ELSE BEGIN WIDGET_CONTROL, state.cwdid, GET_UVALUE=tbl, /NO_COPY WIDGET_CONTROL, state.tblnsetid, GET_UVALUE=oblist, /NO_COPY WIDGET_CONTROL, state.tblnameid, GET_UVALUE=calib, /NO_COPY WIDGET_CONTROL, state.tblnameid, SET_VALUE=tbl.name WIDGET_CONTROL, state.tblnobsid, SET_VALUE=strcompress(tbl.nobs) ; Find the number of objects in the list nobj=n_elements(oblist)/3 WIDGET_CONTROL, state.tblnsetid, SET_VALUE=strcompress(nobj) WIDGET_CONTROL, state.tblnordid, SET_VALUE=strcompress(calib.nor) ; Create the list of objects infolist=strarr(nobj) for i=0,nobj-1 do begin nobs=oblist[1,i]-oblist[0,i]+1 infolist[i]=string(i,nobs,tbl.objnam[oblist[0,i]],format= $ '(i2,1x,i2,1x,a)') endfor WIDGET_CONTROL, state.tbllistid, SET_VALUE=infolist, SENSITIVE=1 ; Create the structure that will hold the spectra and information about ; how much it has been processed tmp=fltarr(calib.npts,tbl.nobs) avg=fltarr(calib.npts,nobj) tim=dblarr(nobj) afl=bytarr(calib.npts,nobj) bad=bytarr(calib.npts,tbl.nobs) s=bytarr(tbl.nobs) prf=fltarr(calib.height,tbl.nobs) idx=intarr(calib.height,tbl.nobs) flg=strarr(calib.height,tbl.nobs) lst=strarr(nobj) slp=fltarr(nobj) s2=bytarr(nobj) r=intarr(nobj,20) r[*,*]=-1 spec={raw: tmp, $ ;*Raw spectra, read from Spec/YYMMDDs.nnn files [cts] rel: tmp, $ ;*Ratio of raw spectra to group mean of raw spectra ;* spec.raw/relsig/spec.avg[setno] (relsig norm) cor: tmp, $ ;*Raw spectra that have had the primary slope correction ;* applied. [cts] cdv: tmp, $ ;*Ratio of primary slope corrected spectra to raw group ;* mean: spec.cor/spec.avg bad: bad, $ ;*Bad flags for raw, corrected, and secondary slope ;* corrected spectra avg: avg, $ ;*Average spectrum of raw set (called group mean) ;* uses only "good" spectra from spec.raw set. [cts] afl: afl, $ ;*Bad flags for spec.avg cav: avg, $ ;*Weighted average of spec.cor [counts/sec] cavs: avg, $ ;* uncertaintes of spec.cor awf: tmp, $ ;*Weights used in combining spec.cor into spec.cav cr2: avg, $ ;*spec.cav after applying the secondary slope correction. cr2s: avg, $ ;* uncertainties of cr2 bfl: afl, $ ;*Bad flags for spec.cav rat: tmp, $ ;*spec.cor/spec.cr2 (one or two denominators) rbd: bad, $ ;*The bad flags for the spec.rat spectra rav: avg, $ ;* Average of the spec.rat spectra ravs: avg, $ ;* uncertainties of spec.rat rwf: tmp, $ ;*Weights used in combining spec.rat into spec.rav arb: afl, $ ;*The badflags for the spec.rav spectra ravjd: tim, $ ; Julian date of spectrum mid-time prf: prf, $ ;Profile points ubd: prf, $ ;Upper bound of sky noise for profile lbd: prf, $ ;Lower bound of sky noise for profile idx: idx, $ ;The index numbers for the profile points flg: flg, $ ;The flag for point type in the profile slp: slp, $ ;The secondary slope correction for each group lst: lst, $ ;The denominator spectrum list s: s, $ ;The state of computation that each spectrum has been ;raised to p: s, $ ;Flag to indicate if profiles have been loaded s2: s2, $ ;Flag to indicate if the secondary slope correction has ;been applied yet s3: s2, $ ;Flag to indicate if the secondary slope correction has ;been loaded yet r: r} ;Array containing the indices of the ;denominators used to make a ratio. This is used to ;prevent the unnecessary recalculation of ratios WIDGET_CONTROL, state.tblnsetid, SET_UVALUE=oblist, /NO_COPY WIDGET_CONTROL, state.cwdid, SET_UVALUE=tbl, /NO_COPY WIDGET_CONTROL, state.tblnameid, SET_UVALUE=calib, /NO_COPY ; Create the numerator list and set up the widget list=strarr(nobj) blanks=' ' for i=0,nobj-1 do begin idx=xdavg_mkidx1(state,i) WIDGET_CONTROL, state.cwdid, GET_UVALUE=tbl, /NO_COPY WIDGET_CONTROL, state.tblnsetid, GET_UVALUE=oblist, /NO_COPY objnam=tbl.objnam[idx[0]] amasrng=string(min(tbl.airmas[idx]),'-',max(tbl.airmas[idx]),format= $ '(f4.2,a,f4.2)') nobs=n_elements(idx) idxrange=string(tbl.imnum[oblist[0,i]],'-',tbl.imnum[oblist[1,i]], $ format='(i3.3,a,i3.3)') list[i]=string(i,objnam+blanks,amasrng,nobs,idxrange, $ format='(i2,1x,a13,1x,a,1x,i2,1x,a)') WIDGET_CONTROL, state.tblnsetid, SET_UVALUE=oblist, /NO_COPY WIDGET_CONTROL, state.cwdid, SET_UVALUE=tbl, /NO_COPY endfor state.num=0 widget_control,state.numid,set_value=list,set_list_select=0,sensitive=1 ; Create the denominator list or load it from disk if exists('Corr/den.list') then begin ; Load the list openr,lun,'Corr/den.list',/get_lun priden=0 lst='' readf,lun,priden for i=0,n_elements(spec.lst)-1 do begin readf,lun,lst ; Get the secondary slope correction from the fits header and append ; it to the denominator list fn='Corr/'+state.root+'a.'+string(i,format='(i2.2)') if exists(fn) then begin hdr=headfits(fn) slope2=sxpar(hdr,'SLOPEFIX') endif else begin slope2=0.0 endelse if strlen(lst) gt 2 then begin if i eq priden then begin spec.lst[i]=lst+' ['+string(slope2,format='(f5.2)')+']' endif else begin spec.lst[i]=lst+' '+'('+string(slope2,format='(f5.2)')+')' endelse endif else spec.lst[i]=lst endfor state.priden=priden free_lun,lun ; Pick the first denominator in the list as the one to be selected and ; reset the numerator selection if it they are the same idx=where(strlen(spec.lst) gt 2) state.den=idx[0] if state.num eq state.den then begin if state.den ne 0 and state.priden ne 0 then begin state.num=0 endif else begin if state.den eq 1 or state.priden eq 1 then begin state.num=2 endif else begin state.num=1 endelse endelse endif ; Get the secondary slope correction from the fits header & display it fn='Corr/'+state.root+'a.'+string(state.num,format='(i2.2)') if exists(fn) then begin hdr=headfits(fn) spec.slp[state.num]=sxpar(hdr,'SLOPEFIX') endif else begin spec.slp[state.num]=0.0 endelse state.slope2=spec.slp[state.num] widget_control,state.slopslid,set_value=spec.slp[state.num] ; Sensitize buttons that manipulate the numerators and denominators widget_control,state.svslopid,set_value='Save Slope & Add to List' widget_control,state.clrlstid,sensitive=1 endif else begin ; Create the denominator list if there is non saved to disk for i=0,nobj-1 do spec.lst[i]=string(i,format='(i2)') state.priden=-1 endelse widget_control,state.denid,set_value=spec.lst widget_control,state.svslopid,sensitive=1 ; Set up the numerator and denominator widgets if there is a first ; denominator and sensitize the secondary slope correction slider if state.priden ne -1 then begin widget_control,state.denid,set_list_select=state.den,sensitive=1 widget_control,state.numid,set_list_select=state.num widget_control,state.slopslid,sensitive=1 endif WIDGET_CONTROL, state.butspecid, SET_UVALUE=spec, /NO_COPY ENDELSE WIDGET_CONTROL, state.mainbase, UPDATE=1 END ;------------------------------------------------------------------------------- ; Procedure xdavg_eve ; ; The event handler for xdavg ;------------------------------------------------------------------------------- PRO xdavg_eve, event WIDGET_CONTROL, event.id, /HOURGLASS stash = WIDGET_INFO( event.handler, /CHILD ) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY CASE event.id OF state.pickid: BEGIN value=dialog_pickfile(/directory) ; Make sure that the directory string has no slash at the end of it so it ; won't mess up xdavg_chngdir len=strlen(value) if strmid(value,len-1,1) eq '/' then value=strmid(value,0,len-1) xdavg_chngdir,state,value END state.cwdid: BEGIN WIDGET_CONTROL, state.cwdid, GET_VALUE=value ; Make sure that the directory string has no slash at the end of it so it ; won't mess up xdavg_chngdir len=strlen(value[0]) if strmid(value[0],len-1,1) eq '/' then value[0]=strmid(value[0],0,len-1) xdavg_chngdir,state,value END state.tbllistid: BEGIN ; Don't do anything if the object clicked on is the same as the currently ; selected object, otherwise set the prefered spectrum and refresh the ; set list if state.idx1 ne event.index then begin ; If the ratio option is selected, make sure that you aren't trying to ; select an object that has no ratio computed skip=0 idx=xdavg_mkidx1(state,event.index) if state.shospec eq 4 then begin widget_control,state.cwdid,get_uvalue=tbl,/no_copy fn='Ratio/'+state.root+'r.'+string(tbl.imnum[idx[0]],format= $ '(i3.3)') widget_control,state.cwdid,set_uvalue=tbl,/no_copy widget_control,state.butspecid,get_uvalue=spec,/NO_COPY if spec.r[event.index,0] eq -1 and exists(fn) eq 0 then begin skip=1 widget_control,state.tbllistid,set_list_select=state.idx1 endif widget_control,state.butspecid,set_uvalue=spec,/NO_COPY endif if not skip then begin state.idx1=event.index widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy state.idx2=idx[0]-oblist[0,state.idx1] widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy state.pref=idx[0] xdavg_setrefresh,state xdavg_plot,state endif endif END state.setlistid: BEGIN idx=xdavg_mkidx1(state,state.idx1) widget_control,state.cwdid,get_uvalue=tbl,/no_copy widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy test=tbl.imflag[oblist[0,state.idx1]+event.index] ; Do nothing if you have tried to select an x-ed or s-ed out spectrum if test eq '-' or event.clicks eq 2 then begin if event.clicks eq 1 then begin if state.idx2 eq event.index then begin state.pageflag=1 state.pref=oblist[0,state.idx1]+state.idx2 endif else begin state.idx2=event.index state.pref=oblist[0,state.idx1]+state.idx2 ; Update the messages on the badflag editting buttons widget_control,state.butmarkid,set_value='Edit '+ $ tbl.fn[state.pref] if state.numshow eq 0 then begin widget_control,state.autoclnid,set_value='Auto Clean Raw '+ $ tbl.fn[state.pref] widget_control,state.clrbadfid,set_value='Clear '+ $ tbl.fn[state.pref]+' Bad Flags' endif endelse widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy widget_control,state.cwdid,set_uvalue=tbl,/no_copy xdavg_plot,state endif else begin widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY ; Save the information about the bad flags before calling markdata idx2=oblist[0,state.idx1]+state.idx2 oldbad=spec.bad[*,idx2] newbad=oldbad ; Run markdata widget_control,state.butmarkid,get_value=elabel t='Flagging '+strmid(elabel,5,99) case state.shospec of 1: markdata,calib.w,spec.raw[*,idx2],newbad,TITLE=t+' (Raw)' 2: markdata,calib.w,spec.rel[*,idx2],newbad,TITLE=t+' (Raw Rel)' 3: markdata,calib.w,spec.cdv[*,idx2],newbad,TITLE=t+' (Corr Rel)' 4: markdata,calib.w,spec.rat[*,idx2],newbad,TITLE=t+' (Ratio)' endcase ; Save the new bad pixel flags if they are different from the ; originals WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY widget_control,state.tblnsetid,set_uvalue=oblist,/NO_COPY if fix(total(oldbad eq newbad)) ne n_elements(oldbad) then begin WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY spec.bad[*,idx2]=newbad fnbad='Spec/'+state.root+'b.'+string(tbl.imnum[idx2],format= $ '(i3.3)') openw,lun,fnbad,/get_lun writeu,lun,spec.bad[*,idx2] free_lun,lun WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY xdavg_refresh,state,state.idx1 endif endelse endif else begin widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy widget_control,state.cwdid,set_uvalue=tbl,/no_copy endelse END state.butnumid: BEGIN state.numshow=event.value ; Update the messages on the badflag editting buttons if there is a ; currently selected set and replot with no prefered spectrum if state.idx1 ne -1 then begin case state.numshow of 0: begin widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy widget_control,state.cwdid,get_uvalue=tbl,/no_copy type=tbl.fn[oblist[0,state.idx1]+state.idx2] widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy widget_control,state.cwdid,set_uvalue=tbl,/no_copy end 1: type='Set' 2: type='All' endcase widget_control,state.clrbadfid,set_value='Clear '+type+' Bad Flags' widget_control,state.autoclnid,set_value='Auto Clean Raw '+type state.pref=-1 xdavg_plot,state endif END state.butprofid: BEGIN state.profile=event.value ; Replot with no prefered spectrum if there is a selected set if state.idx1 ne -1 then begin state.pref=-1 xdavg_plot,state endif END state.butspecid: BEGIN ; Make sure that the ratios exist if they have been selected widget_control,state.butspecid,get_uvalue=spec,/NO_COPY if event.value eq 3 then begin ; Make sure that there is a table file loaded if state.idx1 eq -1 then begin event.value=state.shospec-1 endif else begin case state.numshow of 0: idx1=state.idx1 1: idx1=state.idx1 2: begin widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy idx1=indgen(n_elements(oblist)/3) widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy end endcase noratio=1 for i=0,n_elements(idx1)-1 do begin ; Check to see if there are ratios in memory if spec.r[idx1[i],0] eq -1 then begin ; Check to see if there are ratios on disk idx=xdavg_mkidx1(state,idx1[i]) WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY fn='Ratio/'+state.root+'r.'+string(tbl.imnum[idx[0]],format= $ '(i3.3)') if exists(fn) then noratio=0 WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY endif else noratio=0 endfor if noratio then event.value=state.shospec-1 endelse widget_control,state.butspecid,set_value=event.value endif widget_control,state.butspecid,set_uvalue=spec,/NO_COPY state.shospec=event.value+1 ; Replot with no prefered spectrum if there is a selected set if state.idx1 ne -1 then begin state.pref=-1 xdavg_plot,state endif END state.autoclnid: BEGIN widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY ; Clean the spectra and save the badflags idx=xdavg_mkidx(state) WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY dirty=0 for i=0,n_elements(idx)-1 do begin newbad=spec.bad[*,idx[i]] oldnum=fix(total(newbad)) print,'Cleaning spectrum ',state.root,'s.', $ tbl.imnum[idx[i]],format='($,a,a,a,i3.3)' osiclean,calib,spec.raw[*,idx[i]],newbad print,' ',fix(total(newbad))-oldnum if fix(total(spec.bad[*,idx[i]] eq newbad)) ne n_elements(newbad) $ then begin spec.bad[*,idx[i]]=newbad fn='Spec/'+state.root+'b.'+string(tbl.imnum[idx[i]],format='(i3.3)') openw,lun,fn,/get_lun writeu,lun,newbad free_lun,lun ; Keep track of whether or not any badflags were changed dirty=1 endif endfor widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY if dirty then begin case state.numshow of 0: idx1=state.idx1 1: idx1=state.idx1 2: begin widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy idx1=indgen(n_elements(oblist)/3) print,'XDAVG: idx1',idx1 print,'XDAVG: state.idx1',state.idx1 widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy end endcase xdavg_refresh,state,idx1 endif END state.clrbadfid: BEGIN ; Confirm action first. text = [ $ 'Clearing the bad flags will destroy any flags for this set (or sets). This', $ 'action is not reversible. Are you sure you want to clear these bad flags?'] confirmed = qannounc( text, TITLE='Clear Bad Flag Confirmation', $ FALSE='No, do not clear bad flags', $ TRUE='Yes, ok to clear bad flags', $ XSIZE=80, YSIZE=2) if confirmed then begin idx=xdavg_mkidx(state) widget_control,state.butspecid,get_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY ; Check to see if the badflags will be changed dirty=0 for i=0,n_elements(idx)-1 do begin if total(spec.bad[*,idx[i]]) ne 0.0 then dirty=1 endfor ; Reset the badflags to zeros and delete the files on disk spec.bad[*,idx]=0 fnlist='' for i=0,n_elements(idx)-1 do begin fn='Spec/'+state.root+'b.'+string(tbl.imnum[idx[i]],format='(i3.3)') if exists(fn) then fnlist=fnlist+' '+fn endfor if fnlist ne '' then spawn,'"rm" '+fnlist widget_control,state.butspecid,set_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY if dirty then begin case state.numshow of 0: idx1=state.idx1 1: idx1=state.idx1 2: begin widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy idx1=indgen(n_elements(oblist)/3) widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy end endcase xdavg_refresh,state,idx1 endif endif END state.butmarkid: BEGIN idx=xdavg_mkidx1(state,state.idx1) widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY widget_control,state.tblnsetid,get_uvalue=oblist,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY ; Save the information about the bad flags before calling markdata idx2=oblist[0,state.idx1]+state.idx2 oldbad=spec.bad[*,idx2] newbad=oldbad ; Run markdata widget_control,state.butmarkid,get_value=elabel t='Flagging '+strmid(elabel,5,99) case state.shospec of 1: markdata,calib.w,spec.raw[*,idx2],newbad,TITLE=t+' (Raw)' 2: markdata,calib.w,spec.rel[*,idx2],newbad,TITLE=t+' (Raw Rel)' 3: markdata,calib.w,spec.cdv[*,idx2],newbad,TITLE=t+' (Corr Rel)' 4: markdata,calib.w,spec.rat[*,idx2],newbad,TITLE=t+' (Ratio)' endcase ; Save the new bad pixel flags if they are different from the originals WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY widget_control,state.tblnsetid,set_uvalue=oblist,/NO_COPY if fix(total(oldbad eq newbad)) ne n_elements(oldbad) then begin WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY widget_control,state.butspecid,get_uvalue=spec,/NO_COPY spec.bad[*,idx2]=newbad fnbad='Spec/'+state.root+'b.'+string(tbl.imnum[idx2],format='(i3.3)') openw,lun,fnbad,/get_lun writeu,lun,spec.bad[*,idx2] free_lun,lun WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY xdavg_refresh,state,state.idx1 endif END state.butxoutid: BEGIN ; Change the imflag of the spectrum, reset the selected spectrum, ; and save the table file widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy widget_control,state.cwdid,get_uvalue=tbl,/no_copy idx2=widget_info(state.setlistid,/list_select) test=tbl.imflag[oblist[0,state.idx1]+idx2] if test ne 'x' then begin tbl.imflag[oblist[0,state.idx1]+idx2]='x' ; Make sure that state.idx2 doesn't reference a bad spectrum nobs=oblist[1,state.idx1]-oblist[0,state.idx1]+1 flag=0 while tbl.imflag[oblist[0,state.idx1]+idx2] ne '-' do begin if idx2 eq nobs-1 or flag eq 1 then begin idx2=idx2-1 flag=1 endif else begin idx2=idx2+1 endelse endwhile state.idx2=idx2 endif else begin tbl.imflag[oblist[0,state.idx1]+idx2]='-' state.idx2=idx2 endelse state.pref=oblist[0,state.idx1]+state.idx2 wrtbl,state.root+'.tbl',tbl tbl.dirty=0 widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy widget_control,state.cwdid,set_uvalue=tbl,/no_copy xdavg_setrefresh,state xdavg_refresh,state,state.idx1 END state.butsoutid: BEGIN ; Change the imflag of the spectrum, reset the selected spectrum, ; and save the table file widget_control,state.tblnsetid,get_uvalue=oblist,/no_copy widget_control,state.cwdid,get_uvalue=tbl,/no_copy idx2=widget_info(state.setlistid,/list_select) test=tbl.imflag[oblist[0,state.idx1]+idx2] if test ne 's' then begin tbl.imflag[oblist[0,state.idx1]+idx2]='s' ; Make sure that state.idx2 doesn't reference a bad spectrum nobs=oblist[1,state.idx1]-oblist[0,state.idx1]+1 flag=0 while tbl.imflag[oblist[0,state.idx1]+idx2] ne '-' do begin if idx2 eq nobs-1 or flag eq 1 then begin idx2=idx2-1 flag=1 endif else begin idx2=idx2+1 endelse endwhile state.idx2=idx2 endif else begin tbl.imflag[oblist[0,state.idx1]+idx2]='-' state.idx2=idx2 endelse state.pref=oblist[0,state.idx1]+state.idx2 wrtbl,state.root+'.tbl',tbl tbl.dirty=0 widget_control,state.tblnsetid,set_uvalue=oblist,/no_copy widget_control,state.cwdid,set_uvalue=tbl,/no_copy xdavg_setrefresh,state xdavg_refresh,state,state.idx1 END state.clnratid: BEGIN xdavg_rawrelcln,state END state.ratdvalid: BEGIN xdavg_rawrelcln,state END state.numid: BEGIN ; If the first denominator has not been selected yet, then just store ; the new numerator selection if state.priden ne -1 then begin ; Make sure that the newly selected numerator is not the same as the ; denominator if event.index eq state.den then begin ; Make sure that you have not tried to select the first denominator ; if there are no other denominators saved widget_control,state.butspecid,get_uvalue=spec,/NO_COPY idx=where(strlen(spec.lst) ne 2,cnt) widget_control,state.butspecid,set_uvalue=spec,/NO_COPY if cnt eq 1 then begin widget_control,state.numid,set_list_select=state.num endif else begin state.num=event.index ; Change the denominator if state.num eq idx[0] then begin state.den=idx[1] endif else begin state.den=idx[0] endelse widget_control,state.denid,set_list_select=state.den endelse endif state.num=event.index ; Get the secondary slope correction and display it widget_control,state.butspecid,get_uvalue=spec,/NO_COPY if spec.s3[state.num] eq 0 then begin fn='Corr/'+state.root+'a.'+string(state.num,format='(i2.2)') if exists(fn) then begin hdr=headfits(fn) spec.slp[state.num]=sxpar(hdr,'SLOPEFIX') endif else begin spec.slp[state.num]=0.0 endelse spec.s3[state.num]=1 endif state.slope2=spec.slp[state.num] widget_control,state.slopslid,set_value=state.slope2 widget_control,state.butspecid,set_uvalue=spec,/NO_COPY xdavg_plot2,state ; If you have selected the first denominator, make sure to desensitize ; the secondary slope correction slider so it can't be adjusted if state.num eq state.priden then begin widget_control,state.slopslid,sensitive=0 endif else begin widget_control,state.slopslid,sensitive=1 endelse endif else state.num=event.index END state.denid: BEGIN widget_control,state.butspecid,get_uvalue=spec,/NO_COPY list=widget_info(state.denid,/list_select) ; If you have deselected all the denominators then do nothing if list[0] gt -1 then begin ; If only one denominator is selected, proceed with the regular ; secondary slope correction proceedure if n_elements(list) eq 1 then begin ; Make sure that you haven't selected an unloaded denominator if strlen(spec.lst[event.index]) le 2 then begin widget_control,state.butspecid,set_uvalue=spec,/NO_COPY widget_control,state.denid,set_list_select=state.den endif else begin state.den=event.index ; Make sure that the numerator is not the same as the denominator if state.den eq state.num then begin if state.den ne 0 then state.num=0 else state.num=1 if state.num eq state.priden then begin widget_control,state.slopslid,sensitive=0 endif else widget_control,state.slopslid,sensitive=1 widget_control,state.numid,set_list_select=state.num ; Get the secondary slope correction & display it if spec.s3[state.num] eq 0 then begin fn='Corr/'+state.root+'a.'+string(state.num,format= $ '(i2.2)') if exists(fn) then begin hdr=headfits(fn) spec.slp[state.num]=sxpar(hdr,'SLOPEFIX') endif else begin spec.slp[state.num]=0.0 endelse spec.s3[state.num]=1 endif state.slope2=spec.slp[state.num] widget_control,state.slopslid,set_value=spec.slp[state.num] endif widget_control,state.butspecid,set_uvalue=spec,/NO_COPY xdavg_plot2,state endelse endif else begin ; Make sure that you haven't selected more than two denominators ; if n_elements(list) gt 2 then begin ; ; widget_control,state.denid,set_list_select=state.lstdenlst ; widget_control,state.butspecid,set_uvalue=spec,/NO_COPY ; ; endif else begin ; Make sure that you haven't selected an unloaded denominator z=where(strlen(spec.lst[list]) gt 2) if n_elements(z) ne n_elements(list) then begin widget_control,state.denid,set_list_select=list[z] list=list[z] endif ; Make sure that the numerator is not part of this list z=where(list ne state.num) if n_elements(z) ne n_elements(list) then begin widget_control,state.denid,set_list_select=list[z] list=list[z] endif ; Store the current denominator list in case you try to select ; more than two and the list has to be reset ; if n_elements(list) eq 2 then state.lstdenlst=list ; state.lstdenlst=list widget_control,state.butspecid,set_uvalue=spec,/NO_COPY xdavg_plot2,state ; endelse endelse endif else begin widget_control,state.butspecid,set_uvalue=spec,/NO_COPY endelse END state.svslopid: BEGIN widget_control,state.butspecid,get_uvalue=spec,/NO_COPY if state.priden eq -1 then begin ; Get the slope value from the slider or set it to 0.0 for the first ; denominator and sensitize buttons slope2=0.0 state.den=state.num widget_control,state.denid,sensitive=1,set_list_select=state.den spec.slp[state.den]=slope2 widget_control,state.svslopid,set_value='Save Slope & Add to List' widget_control,state.clrlstid,sensitive=1 ; Reset the numerator list widget to a different numerator if state.den ne 0 then numtmp=0 else numtmp=1 widget_control,state.numid,set_list_select=numtmp ; Get the secondary slope correction and display it if spec.s3[numtmp] eq 0 then begin fn='Corr/'+state.root+'a.'+string(numtmp,format='(i2.2)') if exists(fn) then begin hdr=headfits(fn) spec.slp[numtmp]=sxpar(hdr,'SLOPEFIX') endif else begin spec.slp[numtmp]=0.0 endelse spec.s3[numtmp]=1 endif state.slope2=spec.slp[numtmp] widget_control,state.slopslid,set_value=state.slope2 endif else begin widget_control,state.slopslid,get_value=slope2 endelse spec.slp[state.num]=slope2 ; Update the denominator list and save it to disk idx=xdavg_mkidx1(state,state.num) WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY blanks=' ' amasrng=string(min(tbl.airmas[idx]),'-',max(tbl.airmas[idx]),format= $ '(f4.2,a,f4.2)') if state.priden eq -1 or state.priden eq state.num then begin spec.lst[state.num]=string(state.num,tbl.objnam[idx[0]]+blanks, $ amasrng,format='(i2,1x,a13,1x,a)')+' ['+ $ string(slope2,format='(f5.2)')+']' endif else begin spec.lst[state.num]=string(state.num,tbl.objnam[idx[0]]+blanks, $ amasrng,format='(i2,1x,a13,1x,a)')+' ('+ $ string(slope2,format='(f5.2)')+')' endelse denlist=widget_info(state.denid,/list_select) widget_control,state.denid,set_value=spec.lst,set_list_select=denlist if not exists('Corr/') then spawn,'mkdir Corr/' openw,lun,'Corr/den.list',/get_lun if state.priden eq -1 then printf,lun,state.den else begin printf,lun,state.priden endelse for i=0,n_elements(spec.lst)-1 do begin if strlen(spec.lst[i]) gt 2 then begin printf,lun,string(spec.lst[i],format='(a26)') endif else begin printf,lun,string(spec.lst[i],format='(a2)') endelse endfor free_lun,lun ; Make sure that the desired spectra have been computed widget_control,state.butspecid,set_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY denlist=widget_info(state.denid,/list_select) if denlist[0] ne -1 then n=n_elements(denlist)+1 else n=1 totidx=intarr(n) totidx[0]=state.num if denlist[0] ne -1 then totidx[1:n-1]=denlist for i=0,n-1 do begin idx=xdavg_mkidx1(state,totidx[i]) xdavg_crunch,state,idx,totidx[i],5 endfor if denlist[0] ne -1 then xdavg_mkratio,state,state.num,denlist idx=xdavg_mkidx1(state,state.num) widget_control,state.butspecid,get_uvalue=spec,/NO_COPY WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY ; Save the corrected spectra and average to disk widget_control,state.tblnameid,get_uvalue=calib,/NO_COPY ; Get the header from the s files, add the slope correction to it, apply ; the slope correction, and save the corrected spectra to disk as c files for i=0,n_elements(idx)-1 do begin fn=string('Spec/'+state.root+'s.',tbl.imnum[idx[i]],format='(a,i3.3)') hdr=headfits(fn) sxaddpar,hdr,'SLOPEFIX',strcompress(spec.slp[state.num]), $ ' Secondary slope correction' fit=fltarr(2,calib.nor) fit[0,*]=1.0 fit[1,*]=spec.slp[state.num] osislope,calib,spec.cor[*,idx[i]],fit,outspec fn=string('Spec/'+state.root+'c.',tbl.imnum[idx[i]],format='(a,i3.3)') writefits,fn,outspec,hdr endfor ; Create the header for the average and save it and its bad flags to disk outdata = [[spec.cr2[*,state.num]],[spec.cr2s[*,state.num]]] mkhdr,hdr,outdata sxdelpar,hdr,'DATE' sxaddpar,hdr,'OBJECT',strcompress(tbl.objnam[idx[0]]) sxaddpar,hdr,'JD',spec.ravjd[state.num], $ ' Effective mid-time of spectrum',format='f13.5' exptim=tbl.exptim[idx[0]]*tbl.avego[idx[0]]*n_elements(idx) sxaddpar,hdr,'EXPTIME',strcompress(exptim), $ ' Total integration time of spectrum (seconds)' sxaddpar,hdr,'AIRMASS',mean(tbl.airmas[idx]),'Mean airmass of spectrum' sxaddpar,hdr,'INSTRUME','OSIRIS XD' for i=0,n_elements(idx)-1 do begin sxaddpar,hdr,'SPEC'+string(i+1,format='(i2.2)'),state.root+'c.'+ $ string(tbl.imnum[idx[i]],format='(i3.3)'), $ string(spec.awf[idx[i]],format='(" weight =",f5.3)') endfor sxaddpar,hdr,'SLOPEFIX',strcompress(spec.slp[state.num]), $ ' Secondary slope correction' fn='Corr/'+state.root+'a.'+string(state.num,format='(i2.2)') writefits,fn,outdata,hdr fn='Corr/'+state.root+'b.'+string(state.num,format='(i2.2)') openw,lun,fn,/get_lun writeu,lun,spec.bfl[*,state.num] free_lun,lun ; Save the ratioed spectra to disk widget_control,state.tblnsetid,get_uvalue=oblist,/NO_COPY ; Apply the secondary slope correction to the individual ratio files ; and save them as r files for all but the first denominator if state.priden ne -1 then begin if not exists('Ratio/') then spawn,'mkdir Ratio' for i=0,n_elements(idx)-1 do begin osislope,calib,spec.rat[*,idx[i]],fit,outspec ; Create the header for the spectrum fn='Spec/'+state.root+'c.'+string(tbl.imnum[idx[i]],format='(i3.3)') hdr=headfits(fn) inum=1 for iden=0,n_elements(denlist)-1 do begin if denlist[iden] ne -1 then begin kwd='DEN'+strcompress(inum,/remove_all) sxaddpar,hdr,kwd,denlist[iden], $ ' Denominator spectrum group number' inum=inum+1 endif endfor ; Save the spectrum and its badflags to disk fn='Ratio/'+state.root+'r.'+string(tbl.imnum[idx[i]],format= $ '(i3.3)') writefits,fn,outspec,hdr fn='Ratio/'+state.root+'b.'+string(tbl.imnum[idx[i]],format= $ '(i3.3)') openw,lun,fn,/get_lun writeu,lun,spec.rbd[*,idx[i]] free_lun,lun endfor ; Make the header for the average ratioed spectrum fn='Corr/'+state.root+'a.'+string(state.num,format='(i2.2)') hdr=headfits(fn) inum=1 for iden=0,n_elements(denlist)-1 do begin if denlist[iden] ne -1 then begin kwd='DEN'+strcompress(inum,/remove_all) sxaddpar,hdr,kwd,denlist[iden], $ ' Denominator spectrum group number' imnum=inum+1 endif endfor for i=0,n_elements(idx)-1 do begin sxaddpar,hdr,'SPEC'+string(i+1,format='(i2.2)'),state.root+'r.'+ $ string(tbl.imnum[idx[i]],format='(i3.3)'), $ string(spec.rwf[idx[i]],format='(" weight =",f5.3)') endfor ; Apply the secondary slope correction and save the spectrum as well as ; its badflags to disk osislope,calib,spec.rav[*,state.num],fit,outspec osislope,calib,spec.ravs[*,state.num],fit,outerr fn='Ratio/'+state.root+'a.'+string(state.num,format='(i2.2)') outdata = [[outspec],[outerr]] writefits,fn,outdata,hdr fn='Ratio/'+state.root+'b.'+string(state.num,format='(i2.2)') openw,lun,fn,/get_lun writeu,lun,spec.arb[*,state.num] free_lun,lun endif ; Reset the numerator list selection if it is the same as the first ; denominator if state.priden eq -1 then begin state.priden=state.den state.num=numtmp endif widget_control,state.tblnameid,set_uvalue=calib,/NO_COPY widget_control,state.butspecid,set_uvalue=spec,/NO_COPY widget_control,state.tblnsetid,set_uvalue=oblist,/NO_COPY WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY END state.slopslid: BEGIN ; Make sure that the slope value is within the range of the slider slope2=event.value if abs(slope2) gt 2.0 then begin slope2=2.0*abs(slope2)/slope2 print,'Slope value out of range of slider' widget_control,state.slopslid,set_value=slope2 endif state.slope2=slope2 xdavg_plot2,state END state.clrlstid: BEGIN ; Confirm action first. text = [ $ 'Clearing the denominator list will remove and reset all secondary slope', $ 'corrections. In addition, all of the final output spectra in the Spec', $ 'directory (c-files) as well as all of the results in the Corr and Ratio', $ 'will be deleted. Sometimes you really do need to do this but be warned that', $ 'this operation cannot be undone. If the secondary slope correction values', $ 'are important, then you should write them down somewhere before proceeding.', $ '',$ 'Given these conditions, please confirm or cancel this request.' ] confirmed = qannounc( text, TITLE='Clear Denominator Confirmation', $ FALSE='Cancel, do not clear denominator list', $ TRUE='Confirmed, ok to clear list', $ XSIZE=80, YSIZE=10) if confirmed then begin widget_control,state.butspecid,get_uvalue=spec,/NO_COPY ; Remove the denominator list file from disk and reset the widget for i=0,n_elements(spec.lst)-1 do spec.lst[i]=string(i,format='(i2)') state.priden=-1 if exists('Corr/den.list') then spawn,'"rm" Corr/den.list' widget_control,state.denid,set_value=spec.lst,sensitive=0 widget_control,state.svslopid,set_value='Pick First Denominator' widget_control,state.clrlstid,sensitive=0 widget_control,state.slopslid,set_value=0.0 widget_control,state.slopslid,sensitive=0 widget_control,state.butspecid,set_uvalue=spec,/NO_COPY ; Remove saved spectra spawn,'"rm" '+'Spec/'+state.root+'c*'+' Corr/'+state.root+'a*'+' Corr/'+ $ state.root+'b*'+' Ratio/'+state.root+'r*'+' Ratio/'+state.root+ $ 'a*'+' Ratio/'+state.root+'b*' endif END state.exitid: BEGIN WIDGET_CONTROL,state.cwdid, GET_UVALUE=tbl,/NO_COPY ; Save the table file if its been changed. if tbl.nobs ne 0 then begin if tbl.dirty then wrtbl,state.root+'.tbl',tbl tbl.dirty=0 endif WIDGET_CONTROL,state.cwdid, SET_UVALUE=tbl,/NO_COPY ; Destroy the lock file if state.lock ne -1 then begin free_lun,state.lock state.lock=-1 endif WIDGET_CONTROL, event.top, /DESTROY RETURN END ELSE : BEGIN MESSAGE, 'Unknown event:', /INFO HELP, event, /STRUCTURE END ENDCASE WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY END ;------------------------------------------------------------------------------- ; Procedure xdavg ; ; Setup of the appearance of the xdavg widget. ;------------------------------------------------------------------------------- PRO xdavg IF xregistered('xdavg') THEN return IF (!d.flags and 256) eq 0 THEN BEGIN print, 'Error. No windowing device. XDAVG cannot be started.' return ENDIF cd,'.',current=origdir p_multi=!P.MULTI state = { $ root: '', $ ; The string containing the date of the night that the ; observations were made on in format yymmdd tbldate: '', $ pickid: 0L, $ ; Id of the cw directory selection button cwdid: 0L, $ ; Id of the directory text widget mainbase: 0L, $ ; Id of the xdavg widget mainbase plotid: 0L, $ ; Id of the cw_osipl widget that displays spectra from the ; top part of the xdavg tool plotid2: 0L, $ ; If of the cw_osipl widget that displays the ratios from ; the bottom part of the xdavg tool idx1: -1, $ ; The index of the currently selected object set idx2: 0, $ ; The index of the currently selected spectrum pref: 0, $ ; The index of the spectrum that is prefered to be displayed lock: -1, $ ; The Id of the xdavg.lock file numshow: 0, $ ; The number of spectra (one, set, all) that are requested ; to be displayed shospec: 1, $ ; The type of spectrum to be displayed (Raw, Rel...) profile: 1, $ ; Flag indicating whether or not profiles should be hidden num: 0, $ ; The index of the currently selected numerator spectrum den: 1, $ ; The index(ices) of the currently selected denominator(s) slope2: 0.0, $ ; The current secondary slope correction as displayed in ; slider cw priden: -1, $ ; The index number of the first selected denominator ; lstdenlst: [-1,-1], $ ; The previous selections from denominator list map2: 0, $ ; Flag indicating whether the second plot widget is mapped pageflag: 0, $ ; Flag indicating if the plotter is to just check to make ; sure that the prefered spectrum is on the current page butnumid: 0L, $ ; Id of the number of spectra to show button group butspecid: 0L, $ ; Id of the type of spectra to show button group butprofid: 0L, $ ; Id of the profile display button group butmarkid: 0L, $ ; Id of the user interactive badflag editting button butxoutid: 0L, $ ; Id of the X flag toggling button butsoutid: 0L, $ ; Id of the S flag toggling button autoclnid: 0L, $ ; Id of the Raw spectra autocleaner button clrbadfid: 0L, $ ; Id of the badflag clearing button clnratid: 0L, $ ; Id of the Raw Rel spectra autocleaner button ratdvalid: 0L, $ ; Id of the delta value text tbllistid: 0L, $ ; Id of the table list setlistid: 0L, $ ; Id of the set list tblnameid: 0L, $ ; Id of the table name label tblnobsid: 0L, $ ; Id of the # of observations label tblnsetid: 0L, $ ; Id of the # of sets label tblnordid: 0L, $ ; Id of the # of orders label setnameid: 0L, $ ; Id of the object name label setnobsid: 0L, $ ; Id of the # of observations label setgoodid: 0L, $ ; Id of the # of good observations label setexptid: 0L, $ ; Id of the exposure time label setcoadid: 0L, $ ; Id of the # of coadds label setamenid: 0L, $ ; Id of the mean airmass label setaranid: 0L, $ ; Id of the airmass range label numid: 0L, $ ; Id of the numerator list denid: 0L, $ ; Id of the denominator list svslopid: 0L, $ ; Id of the save slope button slopslid: 0L, $ ; Id of the secondary slope correction slider clrlstid: 0L, $ ; Id of the clear denominator list button exitid: 0L $ ; Id of the exit button } ;Define the main base. mainbase = WIDGET_BASE( TITLE='XDAVG', /COLUMN, UVALUE=0) state.mainbase = mainbase ; Directory information section b=widget_base(mainbase,/row) state.pickid = WIDGET_BUTTON(b, VALUE='Select Directory' ) state.cwdid=WIDGET_TEXT(b,VALUE=origdir,/EDITABLE,XSIZE=45, UVALUE={nobs:0}) state.exitid = WIDGET_BUTTON(b, VALUE='Exit',xsize=60 ) ; The top spectrum selection part of the tool b3= WIDGET_BASE( mainbase, /ROW ) b4= WIDGET_BASE( b3, /COLUMN) b = WIDGET_BASE( b4, /ROW, /FRAME ) b1= WIDGET_BASE( b, /COLUMN ) b2 = WIDGET_LABEL( b1, VALUE='Data :') b2 = WIDGET_LABEL( b1, VALUE='Nobs :') b2 = WIDGET_LABEL( b1, VALUE='Nsets:') b2 = WIDGET_LABEL( b1, VALUE='Nords:') b1= WIDGET_BASE( b, /COLUMN ) state.tblnameid = WIDGET_LABEL( b1, VALUE='', UVALUE={nor:0}, /DYNAMIC_RESIZE ) state.tblnobsid = WIDGET_LABEL( b1, VALUE='', /DYNAMIC_RESIZE ) state.tblnsetid = WIDGET_LABEL( b1, VALUE='', UVALUE=[-1,-1,-1], /DYNAMIC_RESIZE ) state.tblnordid = WIDGET_LABEL( b1, VALUE='', /DYNAMIC_RESIZE ) state.tbllistid = WIDGET_LIST( b4, XSIZE=22, YSIZE=10, VALUE='') b=WIDGET_BASE(b3,/COLUMN) b1=WIDGET_BASE(b,/ROW,/FRAME) b2=WIDGET_BASE(b1,/COLUMN) b4=WIDGET_LABEL(b2, VALUE='Objname:') b4=WIDGET_LABEL(b2, VALUE='Nspecs :') b4=WIDGET_LABEL(b2, VALUE='Ngood :') b4=WIDGET_LABEL(b2, VALUE='Exptime:') b4=WIDGET_LABEL(b2, VALUE='Ncoadds:') b4=WIDGET_LABEL(b2, VALUE='Meanams:') b4=WIDGET_LABEL(b2, VALUE='Amsrang:') b2=WIDGET_BASE(b1,/COLUMN) state.setnameid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setnobsid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setgoodid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setexptid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setcoadid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setamenid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setaranid=WIDGET_LABEL(b2,VALUE='',/DYNAMIC_RESIZE) state.setlistid=WIDGET_LIST(b,XSIZE=23,YSIZE=6,VALUE='') b=WIDGET_BASE(b3,/COLUMN) state.butnumid=CW_BGROUP(b,['Show Spectrum','Show Set','Show All'], $ /NO_RELEASE,/FRAME,/EXCLUSIVE,SET_VALUE=0) state.butspecid=CW_BGROUP(b,['Raw','Raw Rel','Corr Rel','Ratio'], $ /FRAME,/EXCLUSIVE,/NO_RELEASE,SET_VALUE=0) state.butprofid=CW_BGROUP(b,['Show Profile','Hide Profile'], $ /NO_RELEASE,/FRAME,/EXCLUSIVE,SET_VALUE=1) ; Middle section of the widget that contains the spectrum editting buttons b=widget_base(mainbase,/row) state.autoclnid=widget_button(b,value='Auto Clean Raw Spectrum',xsize=175) widget_control,state.autoclnid,sensitive=0 state.clrbadfid=widget_button(b,value='Clear Bad Flags',xsize=175) widget_control,state.clrbadfid,sensitive=0 state.butmarkid=WIDGET_BUTTON(b,VALUE='Mark Bad Data',xsize=105) WIDGET_CONTROL, state.butmarkid, SENSITIVE=0 b=widget_base(mainbase,/row) state.clnratid=widget_button(b,value='Auto Clean Raw Rel Set',xsize=154) widget_control,state.clnratid,sensitive=0 b1=widget_label(b,value='Delta:') state.ratdvalid=widget_text(b,value='10',xsize=4,/editable) widget_control,state.ratdvalid,sensitive=0 state.butxoutid=widget_button(b,value='Toggle X Flag') widget_control,state.butxoutid,sensitive=0 state.butsoutid=widget_button(b,value='Toggle S Flag') widget_control,state.butsoutid,sensitive=0 ; Bottom part of the widget that contains the ratio widgets b=widget_base(mainbase,/row) b1=widget_base(b,/column) b2=widget_label(b1,value='Numerator Spectrum') state.numid=widget_list(b1,value='',xsize=37,ysize=6) widget_control,state.numid,set_uvalue=[''],sensitive=0 state.slopslid=cw_fslider(b1,minimum=-2.0,maximum=2.0,format='(f5.2)',/edit, $ xsize=245,title='Secondary Slope Correction') widget_control,state.slopslid,set_value=0.0,sensitive=0 b1=widget_base(b,/column) b2=widget_label(b1,value='Denominator Spectrum') state.denid=widget_list(b1,value='',xsize=34,ysize=6,/multiple) widget_control,state.denid,set_uvalue=[''],sensitive=0 state.svslopid=widget_button(b1,value='Pick First Denominator') state.clrlstid=widget_button(b1,value='Clear Denominator List') widget_control,state.svslopid,sensitive=0 widget_control,state.clrlstid,sensitive=0 WIDGET_CONTROL, state.tbllistid, SENSITIVE=0 WIDGET_CONTROL, state.setlistid, SENSITIVE=0 ;Stash area for the state structure. stash = WIDGET_INFO( mainbase, /CHILD ) xdavg_chngdir,state,origdir ;Stash the state structure. WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY ;Realize the main base. WIDGET_CONTROL, mainbase, /REALIZE ; Give control to the XMANAGER. XMANAGER, 'xdavg', mainbase, $ EVENT_HANDLER='xdavg_eve', $ GROUP_LEADER=mainbase cd,origdir !P.MULTI=p_multi END