;+ ; NAME: ; dlooker ; PURPOSE: ; Visual identification and measurement of moving objects in digital images. ; DESCRIPTION: ; ; This program handles visually inspecting large digital images and permiting ; measuring positions of the objects and transients found. The object ; data is collected in mysql tables. ; ; CATEGORY: ; Astrometry ; CALLING SEQUENCE: ; dlooker ; INPUTS: ; ; OPTIONAL INPUT PARAMETERS: ; ; KEYWORD INPUT PARAMETERS: ; ; PATH - Optional path for root of image directory. ; default = /net/wixer/raid/buie/ ; ; XSIZE - x size, in pixels, of the main window (default=1070) ; ; YSIZE - y size, in pixels, of the main window (default=820) ; ; ZXSIZE - x size, in pixels, of the score window (default=148) ; ; ZYSIZE - y size, in pixels, of the score window (default=296) ; ; OUTPUTS: ; ; KEYWORD OUTPUT PARAMETERS: ; ; COMMON BLOCKS: ; ; SIDE EFFECTS: ; ; PROCEDURE: ; ; RESTRICTIONS: ; ; MODIFICATION HISTORY: ; 2012/01/01, Written by Marc W. Buie, Lowell Observatory, ; cloned from looker.pro ;- ;------------------------------------------------------------------------------ pro dlooker_cleanup, tlb widget_control, tlb, get_uvalue=state ; dlooker_svobjlist,state ptr_free,(*state).astinfo ptr_free,(*state).bcube ptr_free,(*state).blinkidx ptr_free,(*state).chiplist ptr_free,(*state).cube ptr_free,(*state).dimgfwhm ptr_free,(*state).dreffwhm ptr_free,(*state).exptime ; ptr_free,(*state).r ; ptr_free,(*state).g ; ptr_free,(*state).flags ptr_free,(*state).fieldlist ; ptr_free,(*state).fntrip ptr_free,(*state).fwhm ; ptr_free,(*state).hdr1 ; ptr_free,(*state).hdr2 ; ptr_free,(*state).im1 ; ptr_free,(*state).im2 ; ptr_free,(*state).info1 ; ptr_free,(*state).info2 ptr_free,(*state).invert ; ptr_free,(*state).idstr ptr_free,(*state).jdmid ptr_free,(*state).maglim ptr_free,(*state).night ptr_free,(*state).nrep ptr_free,(*state).objrad ptr_free,(*state).odec ptr_free,(*state).omag ptr_free,(*state).ora ptr_free,(*state).ox ptr_free,(*state).oy ; ptr_free,(*state).offvals ptr_free,(*state).partlist ptr_free,(*state).photzp ptr_free,(*state).setlist ; ptr_free,(*state).dt ; ptr_free,(*state).tdec ; ptr_free,(*state).tra ; ptr_free,(*state).ttype ; ptr_free,(*state).tx ; ptr_free,(*state).ty ptr_free,(*state).visitlist ; ptr_free,(*state).xyvals ; ptr_free,(*state).rate ; ptr_free,(*state).dir ptr_free, state setusym,-1 end ;---------------------------------------------------------------------------- pro dlooker_computerate, state ; if (*state).nobj eq 0 or (*state).info2 eq ptr_new() or $ ; (*state).idxfn2 lt 0 then return ; ; if (*state).idxfn2 ge (*state).nfiles then begin ; (*state).idxfn2 = -1 ; return ; endif ; ; ; Compute rate of motion and direction for all objects ; xa1 = (*(*state).xyvals)[0,*] ; ya1 = (*(*state).xyvals)[1,*] ; idx = (*state).idxfn2*2 ; xb1 = (*(*state).xyvals)[idx+2,*] - (*(*state).offvals)[idx] ; yb1 = (*(*state).xyvals)[idx+3,*] - (*(*state).offvals)[idx+1] ; dt = float((*(*state).info2).jd-(*(*state).info1).jd)*24.0 ; rate=sqrt((xb1-xa1)^2+(yb1-ya1)^2)/dt*(*state).pscale ; dir =atan(yb1-ya1,xb1-xa1) * !radeg ; z=where(xa1 lt 0.0 or ya1 lt 0.0 or $ ; (*(*state).xyvals)[idx+2,*] lt 0.0 or $ ; (*(*state).xyvals)[idx+3,*] lt 0.0,count) ; if count ne 0 then rate[z]=0.0 ; ; *(*state).rate = rate[*] ; *(*state).dir = dir[*] end ;---------------------------------------------------------------------------- ; This takes care of refreshing the visual display in all relevant windows ; based on the current state. Note that state is a pointer to an anonymous ; structure. pro dlooker_display,state,NOSCORE=noscore if not keyword_set(noscore) then noscore=0 widget_control, (*state).drawwin, get_value=winnum WSET, winnum erase ; Making a working copy of the desired corner of the display. x0 = (*state).x0 y0 = (*state).y0 ; Compute upper extraction boundary from main array x1 = x0 + (*state).szx - 1 y1 = y0 + (*state).szy - 1 ; Limit upper boundary to edge of array by shifting to edge (if needed). xshift = x1 - ( (*state).nx-1 ) > 0 yshift = y1 - ( (*state).ny-1 ) > 0 x0 = x0 - xshift x1 = x1 - xshift y0 = y0 - yshift y1 = y1 - yshift ; Now check to make sure we aren't pushing past the lower or left edges. xshift = x0 < 0 yshift = y0 < 0 x0 = x0 - xshift x1 = x1 - xshift y0 = y0 - yshift y1 = y1 - yshift ; Final check in case the display image is larger than full image. if x1 gt (*state).nx-1 then x1 = (*state).nx-1 if y1 gt (*state).ny-1 then y1 = (*state).ny-1 if (*state).colormode eq 0 then begin tv,(*(*state).bcube)[x0:x1,y0:y1,(*state).curvis] tag='' endif else begin othervis = (*state).curvis+1 if othervis eq (*state).nvisits then othervis=0 cube=[[[(*(*state).bcube)[x0:x1,y0:y1,(*state).curvis]]], $ [[(*(*state).bcube)[x0:x1,y0:y1,othervis]]], $ [[(*(*state).bcube)[x0:x1,y0:y1,othervis]]]] tv,cube,true=3 dt=(*(*state).jdmid)[othervis] - $ (*(*state).jdmid)[(*state).curvis] if abs(dt) gt 0.5 then begin tag=' '+string(dt,format='(f5.1)')+'d' endif else begin tag=' '+string(dt*24.0d0,format='(f5.1)')+'h' endelse endelse if (*state).onum gt 0 then begin setusym,-1 ; ; KBOs ; z=where( (*(*state).ttype) eq 1, count ) ; if count gt 0 then $ ; plots,(*(*state).tx)[z]-(*state).x0,(*(*state).ty)[z]-(*state).y0, $ ; psym=8,/device,color='00ff70'xl,symsize=2.5 ; setusym,1 ; ; varstar ; z=where( (*(*state).ttype) eq 2, count ) ; if count gt 0 then $ ; plots,(*(*state).tx)[z]-(*state).x0,(*(*state).ty)[z]-(*state).y0, $ ; psym=4,/device,color='00ff70'xl,symsize=2 ; ; asteroid ; setusym,-3 ; z=where( (*(*state).ttype) eq 3, count ) ; if count gt 0 then $ ; plots,(*(*state).tx)[z]-(*state).x0,(*(*state).ty)[z]-(*state).y0, $ ; psym=8,/device,color='00ff70'xl,symsize=2 setusym,1 ; ; unknown ; z=where( (*(*state).ttype) eq 0, count ) ; if count gt 0 then $ ; plots,(*(*state).tx)[z]-(*state).x0,(*(*state).ty)[z]-(*state).y0, $ ; psym=6,/device,color='ff00ff'xl,symsize=2 endif (*state).x0 = x0 (*state).y0 = y0 str=strn((*state).curvis+1)+' of '+strn((*state).nvisits) widget_control,(*state).visitid,set_value=str jdstr,(*(*state).jdmid)[(*state).curvis],0,jds widget_control,(*state).timeid,set_value=jds+tag str='FWHM='+strn((*(*state).fwhm)[(*state).curvis],format='(f10.1)')+ $ ' Rlim='+strn((*(*state).maglim)[(*state).curvis],format='(f10.2)') widget_control,(*state).info1id,set_value=str str='Ifwhm='+strn((*(*state).dimgfwhm)[(*state).curvis],format='(f10.1)')+ $ ' Rfwhm='+strn((*(*state).dreffwhm)[(*state).curvis],format='(f10.1)') widget_control,(*state).info2id,set_value=str if not noscore then dlooker_updatescore,state,x0,x1,y0,y1 end ;------------------------------------------------------------------------------ pro dlooker_checkinitials,state widget_control, (*state).initialsid, GET_VALUE=initials initials=trimrank(initials) if initials eq '' then begin text = [ $ 'You have not entered your initials next to the "Next/Previous" buttons. This', $ 'information is needed to track who was responsible for a given measurement.', $ 'You must provide this information before you can proceed with ANY operation', $ 'in this program.'] result=dialog_message(text,/ERROR) (*state).initials='' endif if initials eq (*state).initials then return ; If we get this far there has been a change to the requested initials ; to use. ; force to uppercase, keep only first three characters initials=strcompress(strupcase(initials),/remove_all) initials=strmid(initials,0,3) ; Check to see if these initials are already registered c=',' openmysql,dblun,'gen' cmd='select name from initials'+ $ ' where id='+quote(initials)+';' mysqlquery,dblun,cmd,name,format='a',ngood=nfound ; Initials not found, must query for name to go with it. if nfound eq 0 then begin name = qinput(PROMPT='Please enter the name to go with ' + $ 'initials ['+initials+']' ) name=strtrim(strcompress(name[0]),2) if name eq '' then begin (*state).initials='' endif else begin cmd='insert into initials values ('+quote(initials)+c+quote(name)+');' mysqlcmd,dblun,cmd (*state).initials=initials endelse ; Initials found, use them endif else begin (*state).initials=initials endelse free_lun,dblun widget_control,(*state).initialsid,SET_VALUE=(*state).initials end ;------------------------------------------------------------------------------ pro dlooker_getrunlist,runlist,out_dblist dblist=['nh11'] for i=0,n_elements(dblist)-1 do begin openmysql,dblun,'nh11' cmd='select rdir from diff group by rdir order by rdir;' mysqlquery,dblun,cmd,rdir,format='a',ngood=count if i eq 0 then begin runlist=rdir out_dblist=replicate(dblist[i],count) endif else begin runlist=[runlist,rdir] out_dblist=[out_dblist,replicate(dblist[i],count)] endelse free_lun,dblun endfor end ;------------------------------------------------------------------------------ pro dlooker_getsubimage,state,xpos,ypos,frame,wid,sky,subim ; Extract image sub-section around object, watch out for image edges. x10 = fix(xpos) - fix(wid)/2 x20 = fix(x10) + fix(wid) - 1 y10 = fix(ypos) - fix(wid)/2 y20 = fix(y10) + fix(wid) - 1 x1=max([x10,0]) x2=min([x20,(*state).nx-1]) y1=max([y10,0]) y2=min([y20,(*state).ny-1]) subim=replicate(sky,wid,wid) subim[x1-x10,y1-y10] = (*(*state).cube)[x1:x2,y1:y2,(*state).curvis] end ;------------------------------------------------------------------------------ pro dlooker_loadset,state,newset words=strsplit(newset,'.',/extract) field = words[0] chip = fix(words[1]) if n_elements(words) eq 2 then $ part='' $ else $ part=words[2] dlooker_loadset2,state,field,chip,part end ;------------------------------------------------------------------------------ pro dlooker_loadset2,state,field,chip,part if (*state).basis eq 'Delta' then $ (*state).dpath=(*state).path+'diff/'+(*state).rdir+'.d/' $ else $ (*state).dpath=(*state).path+'diff/'+(*state).rdir+'.g/' newset=field+'.'+strn(chip) if part ne '' then newset=newset+'.'+part (*state).field = field (*state).chip = chip (*state).part=part (*state).set=newset widget_control,(*state).setid,set_value=newset openmysql,dblun,(*state).db ; Get the list of files for this visit cmd='select diff.file,jdmid,diff.fwhm,diff.maglim,'+ $ 'dimgfwhm,dreffwhm,exptime,stack.photzp,diff.objrad'+ $ ' from diff,stack'+ $ ' where diff.file like '+quote(newset+'%')+ $ ' and diff.rdir='+quote((*state).rdir)+ $ ' and diff.rdir=stack.rdir'+ $ ' and diff.img=stack.file'+ $ ' and basis='+quote((*state).basis)+';' mysqlquery,dblun,cmd,file,jdmid,fwhm,maglim,dimgfwhm,dreffwhm, $ exptime,photzp,objrad, $ format='a,d,f,f,f,f,f,f,f' pos=strpos(file,'-t') if (*state).type eq 'pair' then begin z=where(pos lt 0,nset) inv=bytarr(nset) endif else begin z=where(pos gt 0,nset) inv=bytarr(nset) endelse file=file[z] jdmid=jdmid[z] nvisits=n_elements(file) if (*state).type eq 'pair' then begin cmd=['select setnum,refset from stack', $ 'where rdir='+quote((*state).rdir), $ 'and object='+quote((*state).field), $ 'and ccdnum='+strn((*state).chip), $ 'and part='+quote((*state).part), $ 'and setnum != refset', $ 'order by fwhm limit 1;'] mysqlquery,dblun,cmd,inv_visit,refset,format='i,i' cmd=['select jdmid,fwhm,maglim from stack', $ 'where rdir='+quote((*state).rdir), $ 'and object='+quote((*state).field), $ 'and ccdnum='+strn((*state).chip), $ 'and part='+quote((*state).part), $ 'and setnum=refset;'] mysqlquery,dblun,cmd,refjdmid,format='d' setnum=intarr(nvisits) for i=0,nvisits-1 do begin words1=strsplit(file[i],'.',/extract) words2=strsplit(words1[-2],'-',/extract) setnum[i]=fix(words2[0]) endfor z=where(setnum eq inv_visit,/null) file=[file,file[z]] maglim=[maglim,maglim[z]] fwhm=[fwhm,fwhm[z]] dimgfwhm=[dimgfwhm,dreffwhm[z]] dreffwhm=[dreffwhm,dimgfwhm[z]] exptime=[exptime,exptime[z]] photzp=[photzp,photzp[z]] objrad=[objrad,objrad[z]] inv=[inv,1] setnum=[setnum,refset] jdmid=[jdmid,refjdmid] idx=sort(jdmid) file=file[idx] maglim=maglim[idx] fwhm=fwhm[idx] dimgfwhm=dimgfwhm[idx] dreffwhm=dreffwhm[idx] exptime=exptime[idx] photzp=photzp[idx] objrad=objrad[idx] inv=inv[idx] setnum=setnum[idx] jdmid=jdmid[idx] nvisits=n_elements(file) endif free_lun,dblun ; Figure out the temporal grouping of the image set avger,jdmid,jdmid,replicate(1.0,nvisits),20,4, $ npts=nrep,group=night,xspread=0.5 z=where(nrep gt 1,count) if count eq 0 then begin widget_control,(*state).blinkset,sensitive=0,value='' endif else begin sets=strcompress(string(indgen(count)),/remove_all) widget_control,(*state).blinksetid,sensitive=1,set_value=sets, $ set_combobox_select=0 idx=where(night eq z[0],count,/null) ptr_free,(*state).blinkidx (*state).blinkidx=ptr_new(idx) endelse ptr_free,(*state).visitlist ptr_free,(*state).invert ptr_free,(*state).jdmid ptr_free,(*state).fwhm ptr_free,(*state).dimgfwhm ptr_free,(*state).dreffwhm ptr_free,(*state).exptime ptr_free,(*state).photzp ptr_free,(*state).objrad ptr_free,(*state).maglim ptr_free,(*state).nrep ptr_free,(*state).night (*state).nvisits=nvisits (*state).invert=ptr_new(inv) (*state).visitlist=ptr_new(file) (*state).jdmid=ptr_new(jdmid) (*state).fwhm=ptr_new(fwhm) (*state).dimgfwhm=ptr_new(dimgfwhm) (*state).dreffwhm=ptr_new(dreffwhm) (*state).exptime=ptr_new(exptime) (*state).photzp=ptr_new(photzp) (*state).objrad=ptr_new(objrad) (*state).maglim=ptr_new(maglim) (*state).nrep=ptr_new(nrep) (*state).night=ptr_new(night) (*state).curvis=0 (*state).x0=0 (*state).y0=0 if (*state).blink eq -2 then (*state).blink=0 $ else if (*state).blink gt 0 then (*state).blink=-1 for i=0,nvisits-1 do begin fn=(*state).dpath+(*(*state).visitlist)[i] print,i,fn,(*(*state).invert)[i],jdmid[i],night[i], $ format='(i2,1x,a,1x,i1,1x,f13.5,1x,i2)' img=readfits(fn,hdr) if i eq 0 then begin (*state).gain=sxpar(hdr,'GAIN') astinfo,hdr,info ptr_free,(*state).astinfo (*state).astinfo=ptr_new(info) sz=size(img,/dimen) (*state).nx=sz[0] (*state).ny=sz[1] ptr_free,(*state).cube (*state).cube=ptr_new(fltarr(sz[0],sz[1],nvisits)) (*state).bcube=ptr_new(bytarr(sz[0],sz[1],nvisits)) xedge=[indgen((*state).nx),replicate((*state).nx-1,(*state).ny), $ reverse(indgen((*state).nx)),replicate(0,(*state).ny)] yedge=[replicate(0,(*state).nx),indgen((*state).ny), $ replicate((*state).ny-1,(*state).nx),reverse(indgen((*state).ny))] astcvt,'xy',xedge,yedge,info,'rd',ra,dec (*state).rarange=minmax(ra) (*state).decrange=minmax(dec) endif if (*(*state).invert)[i] then img= -1.0*img (*(*state).cube)[*,*,i]=img endfor openmysql,dblun,'gen' cmd=['select id,file,x,y,ra,decl,mag from ast', $ 'where ra>'+string((*state).rarange[0]), $ 'and ra<'+string((*state).rarange[1]), $ 'and decl>'+string((*state).decrange[0]), $ 'and decl<'+string((*state).decrange[1]), $ 'and rdir='+quote((*state).rdir), $ 'order by file,id;'] mysqlquery,dblun,cmd,id,file,ox,oy,ora,odec,omag,format='a,a,f,f,d,d,f',ngood=nobjs free_lun,dblun if nobjs gt 0 then begin ptr_free,(*state).odec ptr_free,(*state).ora ptr_free,(*state).ox ptr_free,(*state).oy ptr_free,(*state).omag (*state).odec =ptr_new(odec) (*state).ora =ptr_new(ora) (*state).ox =ptr_new(ox) (*state).oy =ptr_new(oy) (*state).omag =ptr_new(omag) endif (*state).onum=nobjs ; openmysql,dblun,'nh04' ; cmd=['select ra,decl,type from transient', $ ; 'where ra>'+string((*state).rarange[0]), $ ; 'and ra<'+string((*state).rarange[1]), $ ; 'and decl>'+string((*state).decrange[0]), $ ; 'and decl<'+string((*state).decrange[1]), $ ; 'and state='+quote('y')+';'] ; mysqlquery,dblun,cmd,ra,dec,type,format='d,d,a',ngood=ntrans ; free_lun,dblun ; astcvt,'rd',ra,dec,info,'xy',tx,ty ; if ntrans gt 0 then begin ; ptr_free,(*state).tdec ; ptr_free,(*state).tra ; ptr_free,(*state).ttype ; ptr_free,(*state).tx ; ptr_free,(*state).ty ; (*state).tdec =ptr_new(dec) ; (*state).tra =ptr_new(ra) ; (*state).ttype=ptr_new(type) ; (*state).tx =ptr_new(tx) ; (*state).ty =ptr_new(ty) ; endif ; (*state).tnum=ntrans dlooker_stretch,state,/all ; Compute scale factor in each axis to go from full frame to score frame. xf = float((*state).nx) / (*state).szsx yf = float((*state).ny) / (*state).szsy ; The biggest factor is the one we'll use. (*state).sf = max([xf,yf]) dlooker_updatescore,state,/reset end ;------------------------------------------------------------------------------ pro dlooker_measure,state,visit,x,y,exact,error,xpos,ypos,maxsig,sky,skysig, $ NOUPDATE=noupdate error = 0 objrad=(*(*state).objrad)[visit] sky1=objrad+5 sky2=objrad+35 basphote,(*state).gain,(*(*state).cube)[*,*,visit], $ (*(*state).exptime)[visit],x,y,objrad,sky1,sky2,max=maxsig, $ /nolog,xcen=xpos,ycen=ypos,mag=mag,skymean=sky,skyerr=skysig mag=mag+(*(*state).photzp)[visit] astcvt,'xy',xpos,ypos,(*(*state).astinfo),'rd',ra,dec jdstr,(*(*state).jdmid)[visit],0,jds jdstr,(*(*state).jdmid)[visit],205,jds2 rastr,ra,3,ras decstr,dec,2,decs print,jds,xpos,ypos,ras,decs,mag, $ format='(a,2(1x,f7.2),2(1x,a),1x,f7.3)' print,jds2,xpos,ypos,ras,decs,mag, $ format='(a,2(1x,f7.2),2(1x,a),1x,f7.3)' ; if measuring an "old" object, give some protection against accidentally ; clicking much too far from last known position. ; if not keyword_set(noupdate) and (*state).nobj ge 0 and $ ; (*state).curobj ne (*state).nobj then begin ; if (*state).curframe eq 1 then begin ; oldx = (*(*state).xyvals)[ 0, (*state).curobj ] ; oldy = (*(*state).xyvals)[ 1, (*state).curobj ] ; endif else begin ; oldx = (*(*state).xyvals)[ ((*state).idxfn2+1)*2, (*state).curobj ] ; oldy = (*(*state).xyvals)[ ((*state).idxfn2+1)*2+1, (*state).curobj ] ; endelse ; ; dist = sqrt( (x-oldx)^2 + (y-oldy)^2 ) ; ; if dist gt 50.0 and oldx ge 0.0 and oldy ge 0.0 then begin ; text = [ $ ; 'The position you just clicked on is quite far from the last known', $ ; 'position of this object. Perhaps you forgot to change objects or', $ ; 'start a new one? In any case, if you made a mistake just click', $ ; 'Abort and this operation will be aborted. If you want to proceed,', $ ; 'just click on the Continue button.'] ; if qannounc(text,FALSE='Continue',TITLE='Position Warning', $ ; TRUE='Abort Measurement',xsize=72,ysize=5) then begin ; error=1 ; return ; endif ; endif ; ; endif else if not keyword_set(noupdate) and $ ; (*state).curobj eq (*state).nobj and $ ; (*state).curframe eq 2 then begin ; ; text = [ $ ; 'The current object has not been measured on the first frame yet.', $ ; 'This usually happens when you have forgotten to select the object for', $ ; 'which you are trying to measure a second position. If you meant to', $ ; 'measure an object for which there is no position in the first frame,', $ ; 'then click Continue to override this warning. If you did not mean to', $ ; 'make a measurement on a new object, then click Abort Measurement, right', $ ; 'click the object to select it and then try again.'] ; if qannounc(text,FALSE='Continue',TITLE='Right-click Measurement Warning', $ ; TRUE='Abort Measurement',xsize=72,ysize=7) then begin ; error=1 ; return ; endif ; endif ; ; ; Make the measurement ; if (*state).curframe eq 1 then $ ; basphote,(*state).gain,*(*state).im1,(*(*state).info1).exptime, $ ; x,y,(*state).radius,(*state).radius+10.0,(*state).radius+30.0, $ ; boxmrad = (*state).radius > 5,fwhm=fwhm,max=maxsig,exact=exact, $ ; mag=mag,err=err,/nolog,pscale=(*state).pscale, $ ; fname=(*(*state).fntrip)[0],name=(*state).curobjname, $ ; xcen=xpos,ycen=ypos,skymean=sky,skyerr=skysig $ ; else $ ; basphote,(*state).gain,*(*state).im2,(*(*state).info1).exptime, $ ; x,y,(*state).radius,(*state).radius+10.0,(*state).radius+30.0, $ ; boxmrad = (*state).radius > 5,fwhm=fwhm,max=maxsig,exact=exact, $ ; mag=mag,err=err,/nolog,pscale=(*state).pscale, $ ; fname=(*(*state).fntrip)[(*state).idxfn2+1],name=(*state).curobjname, $ ; xcen=xpos,ycen=ypos,skymean=sky,skyerr=skysig ; ; if not keyword_set(noupdate) then begin ; ; ; If new object, add new empty entry to list. ; if (*state).nobj eq 0 then begin ; (*state).xyvals = ptr_new(replicate(-1.0,2*n_elements((*(*state).fntrip)))) ; (*state).flags = ptr_new(['y']) ; (*state).idstr = ptr_new([curinitials]) ; (*state).nobj = 1 ; (*state).rate = ptr_new(fltarr(1)) ; (*state).dir = ptr_new(fltarr(1)) ; endif else if (*state).curobj eq (*state).nobj then begin ; *(*state).xyvals = [[*(*state).xyvals], $ ; [replicate(-1.0,2*n_elements((*(*state).fntrip)))]] ; *(*state).flags = [*(*state).flags,'y'] ; *(*state).idstr = [*(*state).idstr,curinitials] ; (*state).nobj = (*state).nobj + 1 ; endif ; ; if (*state).curframe eq 1 then begin ; (*(*state).xyvals)[ 0, (*state).curobj ] = xpos ; (*(*state).xyvals)[ 1, (*state).curobj ] = ypos ; endif else begin ; (*(*state).xyvals)[ ((*state).idxfn2+1)*2, (*state).curobj ] = xpos ; (*(*state).xyvals)[ ((*state).idxfn2+1)*2+1, (*state).curobj ] = ypos ; endelse ; ; dlooker_computerate,state ; ; ; Update entry. ; ; if (*state).curobj lt (*state).nobj then begin ; idstr = (*(*state).idstr)[(*state).curobj] ; idstr = idstr[0] ; dlooker_updateidstr,idstr,curinitials ; (*(*state).idstr)[(*state).curobj] = idstr ; endif ; (*state).dirtylist = 1 ; dlooker_display,state,/noload ; dlooker_objinfo,state ; endif ; end ;------------------------------------------------------------------------------ pro dlooker_objinfo,state ; fn0 = (*(*state).fntrip)[0] ; words = strsplit(fn0,'.',/extract) ; ; if (*state).curobj ge 0 then begin ; ; if (*state).curobj ne (*state).nobj then begin ; if (*(*state).rate)[(*state).curobj] ne 0.0 then begin ; ratestr = string((*(*state).rate)[(*state).curobj],'"', $ ; (*(*state).dir )[(*state).curobj], $ ; format='(f10.2,a,"/hr, ",f10.1,"dg")') ; ratestr = strcompress(strtrim(ratestr,2)) ; endif else begin ; ratestr = 'rate not valid' ; endelse ; endif else begin ; ratestr = 'rate not valid' ; endelse ; ; objstr = strmid(words[0],strlen(words[0])-2) + words[1] + $ ; (*state).exttag + strb36((*state).curobj,pad=2) ; endif else begin ; objstr = ' ' ; ratestr = ' ' ; endelse ; ; (*state).curobjname = objstr ; ; if (*state).curobj eq (*state).nobj then objstr = objstr+' NEW' ; ; if (*state).curobj ge 0 and (*state).curobj ne (*state).nobj then begin ; if (*(*state).flags)[(*state).curobj] eq 's' then begin ; widget_control, (*state).flagid, SENSITIVE=0 ; endif else begin ; widget_control, (*state).flagid, SENSITIVE=1 ; if (*(*state).flags)[(*state).curobj] eq '?' then nval=0 ; if (*(*state).flags)[(*state).curobj] eq 'y' then nval=1 ; if (*(*state).flags)[(*state).curobj] eq 'n' then nval=2 ; widget_control, (*state).flagid, SET_VALUE=nval ; endelse ; endif else begin ; widget_control, (*state).flagid, SENSITIVE=0 ; endelse ; ; widget_control, (*state).mainbase, UPDATE=0 ; widget_control, (*state).curobjid, SET_VALUE=objstr ; widget_control, (*state).rateid, SET_VALUE=ratestr ; widget_control, (*state).mainbase, UPDATE=1 end ;------------------------------------------------------------------------------ pro dlooker_refreshzoom,state,xpos,ypos,radius,RESET=reset ; size of extraction region wid = (*state).szsx/(*state).zf zsz = wid * (*state).zf widget_control, (*state).zoomwin, get_value=winnum WSET, winnum tv,rebin((*state).zim,zsz,zsz,/sample) if not keyword_set(reset) then begin x = (xpos - (*state).zx0) * (*state).zf y = (ypos - (*state).zy0) * (*state).zf theta=findgen(361.0)/!radeg xcirc=radius*cos(theta) ycirc=radius*sin(theta) plot,[0],[1],/nodata,xmargin=[0,0],ymargin=[0,0], $ xr=(*state).zx0+[-0.5,wid-0.5], $ yr=(*state).zy0+[-0.5,wid-0.5], $ xstyle=5,ystyle=5,/noerase ; if (*state).curframe eq 1 then color='0040ff'xl $ ; else color='ff8000'xl oplot,xcirc+xpos,ycirc+ypos,color='00ffff'xl endif end ;------------------------------------------------------------------------------ pro dlooker_setalloffset,state ; ; protect against non-group files ; if (*state).numext eq 1 then return ; ; print,'Copying offset to all other chips in this field.' ; ; ; Save current object list file. ; dlooker_svobjlist,state ; ; ; Loop over all the extensions on this field. ; for iext=1,(*state).numext do begin ; ; fnobj = (*state).objpath+(*state).field+'x'+strb36(iext)+'.obj' ; ; if exists(fnobj) then begin ; ; ; Load the object list file. ; rdoblist,fnobj,nobj,fnlist,dt,offvals,xyvals,flags,idstr,nfiles ; ; ; copy the offsets from the current pair ; offvals[(*state).idxfn2*2] = (*(*state).offvals)[(*state).idxfn2*2+[0,1]] ; ; ; Save the object list file. ; wroblist,fnobj,nobj,fnlist,dt,offvals,xyvals,flags,idstr,nfiles ; ; endif ; endfor end ;------------------------------------------------------------------------------ pro dlooker_setup,state,run,dbname (*state).db=dbname (*state).rdir=run print,dbname,' ',run openmysql,dblun,(*state).db cmd='select file from diff'+ $ ' where rdir='+quote((*state).rdir)+ $ ' and file not like '+quote('SUPA%')+ $ ' order by file;' print,cmd mysqlquery,dblun,cmd,files,format='a',ngood=nfiles free_lun,dblun help,nfiles field=strarr(nfiles) chip=intarr(nfiles) part=strarr(nfiles) visit=intarr(nfiles) set=strarr(nfiles) for i=0,nfiles-1 do begin pos=strpos(files[i],'-') set[i]=strmid(files[i],0,pos) words=strsplit(set[i],'.',/extract) set[i]=strjoin(words[0:-2],'.') field[i] = words[0] chip[i] = fix(words[1]) if n_elements(words) eq 3 then begin visit[i] = fix(words[2]) endif else begin part[i] = words[2] visit[i] = fix(words[3]) endelse endfor fieldlist=field[uniq(field,sort(field))] chiplist=chip[uniq(chip,sort(chip))] partlist=part[uniq(part,sort(part))] setlist=set[uniq(set,sort(set))] ptr_free,(*state).chiplist ptr_free,(*state).fieldlist ptr_free,(*state).partlist ptr_free,(*state).setlist (*state).chiplist=ptr_new(chiplist) (*state).fieldlist=ptr_new(fieldlist) (*state).partlist=ptr_new(partlist) (*state).setlist=ptr_new(setlist) (*state).x0=0 (*state).y0=0 widget_control,(*state).runid,set_value=(*state).rdir+' ['+(*state).db+']' widget_control,(*state).basisid,/sensitive widget_control,(*state).typeid,/sensitive dlooker_loadset,state,(*(*state).setlist)[0] end ;------------------------------------------------------------------------------ pro dlooker_setzoom,state,visit,xpos,ypos,peaksig,sky,skysig,RESET=reset if keyword_set(reset) then begin (*state).zim[*]=0B dlooker_refreshzoom,state,reset=reset return endif ; size of extraction region wid = (*state).szsx/(*state).zf zsz = wid * (*state).zf ; Extract image sub-section around object, watch out for image edges. x10 = xpos - wid/2 x20 = x10 + wid - 1 y10 = ypos - wid/2 y20 = y10 + wid - 1 x1=max([x10,0]) x2=min([x20,(*state).nx-1]) y1=max([y10,0]) y2=min([y20,(*state).ny-1]) subim=replicate(sky,wid,wid) subim[x1-x10,y1-y10] = (*(*state).cube)[x1:x2,y1:y2,visit] (*state).zx0 = x10 (*state).zy0 = y10 subim = ( (subim-(sky-2.0*skysig) > 0) + 10 )^0.1 maxv = ( (peaksig > (sky+2.0*skysig))-(sky-2.0*skysig) + 10 )^0.1 minv = 1.0 > min(subim) (*state).zim=bytscl(subim,min=minv,max=maxv,top=255) dlooker_refreshzoom,state,xpos,ypos,(*(*state).objrad)[visit] end ;------------------------------------------------------------------------------ pro dlooker_stretch,state,ALL=all if not keyword_set(all) then all=0 if all then todo=indgen((*state).nvisits) else todo=(*state).curvis for i=0,n_elements(todo)-1 do begin ; set the initial sky scaling levels for the subimages. widget_control, (*state).minsigid, GET_VALUE=dm widget_control, (*state).maxsigid, GET_VALUE=dp dm = float(dm[0]) dp = float(dp[0]) skysclim,(*(*state).cube)[*,*,todo[i]],lowval,hival,amean,asig, $ lowclip=0.1,hiclip=0.9 alowval=amean + dm*asig ahival =amean + dp*asig (*(*state).bcube)[*,*,todo[i]]=bytscl((*(*state).cube)[*,*,todo[i]], $ min=alowval,max=ahival,top=255) endfor end ;------------------------------------------------------------------------------ pro dlooker_svobjlist,state ; if (*state).dirtylist then begin ; ; print,'Updating object list file ',(*state).fnobj ; ; if (*state).nobj eq 0 then begin ; xyvals = 0 ; flags = '' ; idstr = '' ; endif else begin ; xyvals = (*(*state).xyvals) ; flags = (*(*state).flags) ; idstr = (*(*state).idstr) ; endelse ; ; wroblist,(*state).objpath+(*state).fnobj,(*state).nobj,(*(*state).fntrip), $ ; (*(*state).dt), $ ; (*(*state).offvals),xyvals,flags,idstr,n_elements((*(*state).fntrip)) ; ; (*state).dirtylist = 0 ; ; endif end ;------------------------------------------------------------------------------ pro dlooker_updateidstr,idstr,initials words=strsplit(idstr,',',/extract) if words[0] eq '' then begin idstr=initials endif else begin if words[n_elements(words)-1] ne initials then $ idstr = idstr+','+initials endelse end ;------------------------------------------------------------------------------ pro dlooker_updatescore,state,x0,x1,y0,y1,RESET=reset,REFRESH=refresh ; Make a local copy to save some typing sf = (*state).sf if not keyword_set(refresh) then begin if keyword_set(reset) then begin (*state).srgb[*,*,0] = 20B (*state).srgb[*,*,1] = 20B (*state).srgb[*,*,2] = 0B i0 = fix(( 0-(*state).nx/2.0 ) / sf + (*state).szsx/2.0) > 0 j0 = fix(( 0-(*state).ny/2.0 ) / sf + (*state).szsy/2.0) > 0 i1 = fix(i0 + (*state).nx/sf) < ((*state).szsx-1) j1 = fix(j0 + (*state).ny/sf) < ((*state).szsy-1) (*state).srgb[i0:i1,j0:j1,*] = 0B endif else begin i0 = fix(( x0-(*state).nx/2.0 ) / sf + (*state).szsx/2.0) > 0 j0 = fix(( y0-(*state).ny/2.0 ) / sf + (*state).szsy/2.0) > 0 i1 = fix(( x1-(*state).nx/2.0 ) / sf + (*state).szsx/2.0) < ((*state).szsx-1) j1 = fix(( y1-(*state).ny/2.0 ) / sf + (*state).szsy/2.0) < ((*state).szsy-1) inc = 50B bsub = (*state).srgb[i0:i1,j0:j1,1] z=where(bsub lt 185B-inc,count) if count ne 0 then begin bsub[z] = bsub[z] + inc (*state).srgb[i0:i1,j0:j1,1] = bsub endif endelse endif widget_control, (*state).scorewin, get_value=winnum WSET, winnum tv,(*state).srgb,true=3 plot,[0],[1],/nodata,xmargin=[0,0],ymargin=[0,0], $ xr = (*state).nx/2 + (*state).szsx * [-0.5,0.5] * (*state).sf, $ yr = (*state).ny/2 + (*state).szsy * [-0.5,0.5] * (*state).sf, $ xstyle=5,ystyle=5,/noerase ; outline current area display in main window xv = (*state).x0 + [ 0.0, 1.0, 1.0, 0.0, 0.0 ] * (*state).szx yv = (*state).y0 + [ 0.0, 0.0, 1.0, 1.0, 0.0 ] * (*state).szy oplot,xv,yv,color='800070'xl ; if (*state).nobj ne 0 then $ ; z=where( (*(*state).flags) ne 'n', count) $ ; else $ ; count = 0 ; ; if count ne 0 then begin ; for i=0,n_elements((*(*state).fntrip))-1 do begin ; ; ; extract just the objects to be plotted ; xyvals = (*(*state).xyvals)[i*2:i*2+1,z] ; ; ; only plot those that are valid measurements ; zz = where(xyvals[0,*] gt 0.0 and xyvals[1,*] gt 0.0, count) ; ; if count ne 0 then begin ; ; ; select color for symbol ; if i eq 0 then color='0000ff'xl $ ; else if i eq (*state).idxfn2+1 then color='ffff00'xl $ ; else color='40ff30'xl ; ; ; compute offset for this object ; if i eq 0 then begin ; xoff = 0 ; yoff = 0 ; endif else begin ; xoff = (*(*state).offvals)[(i-1)*2] ; yoff = (*(*state).offvals)[(i-1)*2+1] ; endelse ; ; oplot,xyvals[0,zz]-xoff, $ ; xyvals[1,zz]-yoff, $ ; psym=1,color=color,symsize=0.8 ; ; if i eq 0 then begin ; for j=0,count-1 do begin ; if (*(*state).flags)[z[zz[j]]] eq 'y' then $ ; color='00ffff'xl $ ; else if (*(*state).flags)[z[zz[j]]] eq 's' then $ ; color='19e212'xl $ ; else $ ; color='6020ff'xl ; tag = strb36(z[zz[j]],pad=2) ; xyouts,xyvals[0,zz[j]],xyvals[1,zz[j]]+5.0*(*state).sf,tag, $ ; align=0.5,color=color ; endfor ; endif ; ; endif ; ; endfor ; endif end ;------------------------------------------------------------------------------ PRO dlooker_eve, event widget_control, event.id, GET_UVALUE=event_name, /HOURGLASS widget_control, event.top, GET_UVALUE=state exit = event_name eq 'THE_MENU' if exit then exit = event.value eq 'Exit' if event_name ne 'Initials' and not exit then begin dlooker_checkinitials,state if (*state).initials eq '' then return endif CASE event_name OF 'THE_MENU': BEGIN case event.value OF 'Copy stretch': begin dlooker_stretch,state,/all dlooker_display,state,/noscore end ; 'Set all ? to N': begin ; z = where( (*(*state).flags) eq '?', count ) ; if count ne 0 then begin ; (*state).dirtylist = 1 ; (*(*state).flags)[z] = 'n' ; for i=0,count-1 do begin ; idstr = (*(*state).idstr)[z[i]] ; dlooker_updateidstr,idstr,curinitials ; (*(*state).idstr)[z[i]] = idstr ; endfor ; if (*state).curobj lt (*state).nobj then begin ; if (*(*state).flags)[(*state).curobj] eq 'n' then begin ; (*state).curobj=(*state).nobj ; (*state).curframe = 0 ; dlooker_setzoom,state,/reset ; endif ; endif ; dlooker_display,state,/noload ; dlooker_updatescore,state,/refresh ; dlooker_objinfo,state ; endif ; end ; 'Autoload Toggle': begin ; (*state).autoload = not (*state).autoload ; if (*state).fnobj eq '' then return ; end ; 'Change secondary field': begin ; ; widget_control, (*state).fn1id, get_value=fn1 ; ; if fn1 eq '' then return ; ; if (*state).nfiles eq 1 then return ; ; z=where(*(*state).fntrip ne fn1,count) ; if count eq 0 then return ; ; newstr=picker((*(*state).fntrip)[z],group=event.top, $ ; title='Pick Second Frame') ; if newstr ne '[[[CANCEL]]]' then begin ; widget_control, (*state).mainbase, UPDATE=0 ; widget_control, (*state).fn2id, SET_VALUE=newstr ; widget_control, (*state).mainbase, UPDATE=1 ; (*state).idxfn2 = -1 ; endif ; dlooker_display,state ; ; end ; 'Exit' : begin widget_control, event.top, /DESTROY RETURN end ; 'Postscript Hardcopy': begin ; if (*state).lastfn2 eq '' then return ; hardim,[[[*(*state).r]],[[*(*state).g]],[[*(*state).g]]], $ ; true=3,queue='chani',file='dlooker.ps',/noprint,autosize=2, $ ; /landscape ;,title='KPNO/MOSAIC 1998 Nov 18' ; hardim,*(*state).r, $ ; queue='chani',file='dlooker1.ps',/noprint,autosize=2, $ ; /landscape ;,title='KPNO/MOSAIC 1998 Nov 18' ; hardim,*(*state).g, $ ; queue='chani',file='dlooker2.ps',/noprint,autosize=2, $ ; /landscape ;,title='KPNO/MOSAIC 1998 Nov 18' ; end ; 'Refresh display': begin if (*state).rdir eq '' then return dlooker_display,state,/noscore end 'Select chip': begin if (*state).rdir eq '' then return if n_elements((*(*state).chiplist)) eq 1 then return chip=picker(string((*(*state).chiplist)),index=idx, $ group=event.top,title='Pick Chip') if chip eq '[[[CANCEL]]]' then return chip=fix(chip) dlooker_loadset2,state,(*state).field, $ chip, $ (*(*state).partlist)[0] dlooker_display,state end 'Select field': begin if (*state).rdir eq '' then return field=picker((*(*state).fieldlist),index=idx, $ group=event.top,title='Pick Field') if field eq '[[[CANCEL]]]' then return dlooker_loadset2,state,field, $ (*(*state).chiplist)[0], $ (*(*state).partlist)[0] dlooker_display,state end 'Select run': begin dlooker_getrunlist,runlist,dblist rundir=picker(runlist+' ['+dblist+']',index=idx, $ group=event.top,title='Pick Extension') if rundir eq '[[[CANCEL]]]' then return dlooker_setup,state,runlist[idx],dblist[idx] dlooker_display,state end ; 'Snap object': begin ; ; if (*state).idxfn2 lt 0 then return ; if (*state).curobj eq (*state).nobj or (*state).curobj lt 0 then return ; ; size of extraction region ; wid = (*state).szsx/(*state).zf ; zsz = wid * (*state).zf ; ; ; offset between frame 2 and reference frame ; xoff = fix( (*(*state).offvals)[(*state).idxfn2*2] + 0.5 ) ; yoff = fix( (*(*state).offvals)[(*state).idxfn2*2+1] + 0.5 ) ; ; ; Positions of the objects in their own frames ; xa = (*(*state).xyvals)[0,(*state).curobj] ; ya = (*(*state).xyvals)[1,(*state).curobj] ; xb = (*(*state).xyvals)[ ((*state).idxfn2+1)*2, (*state).curobj ] ; yb = (*(*state).xyvals)[ ((*state).idxfn2+1)*2+1, (*state).curobj ] ; ; ; position of second image in frame 1 ; xb1 = xb - xoff ; yb1 = yb - yoff ; ; ; distance moved between images ; dist = sqrt((xa-xb1)^2 + (ya-yb1)^2) ; ; ; mid-point between two object positions in frame 1 ; xmid = (xa+xb1)/2.0 ; ymid = (ya+yb1)/2.0 ; ; fmt='(a,2(1x,f6.1),1x,f7.3,"+/-",f6.3,1x,g10.3,"+/-",g7.3)' ; ; print,'extract around object',(*state).curobj ; ; basphote,(*state).gain,*(*state).im1,(*(*state).info1).exptime, $ ; xa,ya,(*state).radius,(*state).radius+10.0,(*state).radius+30.0, $ ; boxmrad = (*state).radius > 5,fwhm=fwhm,max=maxsig1,/exact, $ ; mag=mag,err=err,/nolog,pscale=(*state).pscale, $ ; fname=(*(*state).fntrip)[0],name=(*state).curobjname, $ ; xcen=xpos,ycen=ypos,skymean=sky1,skyerr=skysig1,/silent ; print,'frame 1 x,y ',xa,ya,mag,err,sky1,skysig1,format=fmt ; ; basphote,(*state).gain,*(*state).im2,(*(*state).info1).exptime, $ ; xb,yb,(*state).radius,(*state).radius+10.0,(*state).radius+30.0, $ ; boxmrad = (*state).radius > 5,fwhm=fwhm,max=maxsig2,/exact, $ ; mag=mag,err=err,/nolog,pscale=(*state).pscale, $ ; fname=(*(*state).fntrip)[(*state).idxfn2+1],name=(*state).curobjname, $ ; xcen=xpos,ycen=ypos,skymean=sky2,skyerr=skysig2,/silent ; print,'frame 2 x,y ',xb,yb,mag,err,sky2,skysig2,format=fmt ; ; ; Get the sky scaling levels for the subimages. ; widget_control, (*state).minsigid, GET_VALUE=dm ; widget_control, (*state).maxsigid, GET_VALUE=dp ; dm = float(dm[0]) ; dp = float(dp[0]) ; ; ; Probably would use LZW but it seems to need licensing. ; compression=0 ; ; widget_control, (*state).curobjid, GET_VALUE=objname ; ; ; FITS versions, add dw extra pixels to extraction ; dw=300 ; dlooker_getsubimage,state,xa,ya,1,wid+dw,sky1,subim1 ; hdr1 = (*(*state).hdr1) ; sxaddpar,hdr1,'NAXIS1',wid+dw ; sxaddpar,hdr1,'NAXIS2',wid+dw ; sxaddpar,hdr1,'XLLHC',fix(xa)-fix(wid+dw)/2 ; sxaddpar,hdr1,'YLLHC',fix(ya)-fix(wid+dw)/2 ; writefits,objname+'_1.fits',subim1,hdr1 ; ; dlooker_getsubimage,state,xb,yb,2,wid+dw,sky2,subim2 ; hdr2 = (*(*state).hdr2) ; sxaddpar,hdr2,'NAXIS1',wid+dw ; sxaddpar,hdr2,'NAXIS2',wid+dw ; sxaddpar,hdr2,'XLLHC',fix(xb)-fix(wid+dw)/2 ; sxaddpar,hdr2,'YLLHC',fix(yb)-fix(wid+dw)/2 ; writefits,objname+'_2.fits',subim2,hdr2 ; ; ; Linear stretch versions ; ; image 1 B/W, centered on object ; dlooker_getsubimage,state,xa,ya,1,wid,sky1,subim1 ; subim1 = reverse(float(subim1)-sky1,2) ; bsubim1 = bytscl(subim1,min=(*state).lowval1-sky1, $ ; max=(*state).highval1-sky1,top=255) ; write_tiff,objname+'_1.tiff',bsubim1,compression=compression ; ; ; image 2 B/W, centered on object ; dlooker_getsubimage,state,xb,yb,2,wid,sky2,subim2 ; subim2 = reverse(float(subim2)-sky2,2) ; bsubim2 = bytscl(subim2,min=(*state).lowval2-sky2, $ ; max=(*state).highval2-sky2,top=255) ; write_tiff,objname+'_2.tiff',bsubim2,compression=compression ; ; ; Power-law stretch versions ; lsubim1 = ( (subim1+2.0*skysig1 > 0) + 10 )^0.1 ; maxv1 = ( ((maxsig1-sky1) > (2.0*skysig1))+2.0*skysig1 + 10 )^0.1 ; minv1 = 1.0 > min(lsubim1) ; lsubim1 = bytscl(lsubim1,min=minv1,max=maxv1,top=255) ; write_tiff,objname+'_1l.tiff',lsubim1,compression=compression ; ; lsubim2 = ( (subim2+2.0*skysig2 > 0) + 10 )^0.1 ; maxv2 = ( ((maxsig2-sky2) > (2.0*skysig2))+2.0*skysig2 + 10 )^0.1 ; minv2 = 1.0 > min(lsubim2) ; lsubim2 = bytscl(lsubim2,min=minv2,max=maxv2,top=255) ; write_tiff,objname+'_2l.tiff',lsubim2,compression=compression ; ; ; image 1 B/W, centered on object mid-point ; dlooker_getsubimage,state,xmid,ymid,1,wid+dist,sky1,subim1 ; subim1 = reverse(float(subim1)-sky1,2) ; bsubim1 = bytscl(subim1,min=(*state).lowval1-sky1, $ ; max=(*state).highval1-sky1,top=255) ; write_tiff,objname+'_1c.tiff',bsubim1,compression=compression ; ; ; image 2 B/W, centered on object mid-point ; dlooker_getsubimage,state,xmid+xoff,ymid+yoff,2,wid+dist,sky2,subim2 ; subim2 = reverse(float(subim2)-sky2,2) ; bsubim2 = bytscl(subim2,min=(*state).lowval2-sky2, $ ; max=(*state).highval2-sky2,top=255) ; write_tiff,objname+'_2c.tiff',bsubim2,compression=compression ; ; ; color composite of image 1 and 2 ; write_tiff,objname+'_c.tiff',[[[bsubim1]],[[bsubim2]],[[bsubim2]]], $ ; planarconfig=2 ; ; ; Power-law stretch versions ; lsubim1 = ( (subim1+2.0*skysig1 > 0) + 10 )^0.1 ; maxv1 = ( ((maxsig1-sky1) > (2.0*skysig1))+2.0*skysig1 + 10 )^0.1 ; minv1 = 1.0 > min(lsubim1) ; lsubim1 = bytscl(lsubim1,min=minv1,max=maxv1,top=255) ; write_tiff,objname+'_1lc.tiff',lsubim1,compression=compression ; ; lsubim2 = ( (subim2+2.0*skysig2 > 0) + 10 )^0.1 ; maxv2 = ( ((maxsig2-sky2) > (2.0*skysig2))+2.0*skysig2 + 10 )^0.1 ; minv2 = 1.0 > min(lsubim2) ; lsubim2 = bytscl(lsubim2,min=minv2,max=maxv2,top=255) ; write_tiff,objname+'_2lc.tiff',lsubim2,compression=compression ; ; write_tiff,objname+'_l.tiff',[[[lsubim1]],[[lsubim2]],[[lsubim2]]], $ ; planarconfig=2 ; ; end ; ; 'Suppress overlay': begin ; (*state).nomarks = not (*state).nomarks ; if (*state).fnobj eq '' then return ; dlooker_display,state,/noload,/noscore ; dlooker_updatescore,state,/refresh ; end 'Toggle color mode': begin if (*state).rdir eq '' then return (*state).colormode = not (*state).colormode dlooker_display,state,/noscore end ; 'Toggle lines': begin ; (*state).lines = not (*state).lines ; if (*state).fnobj eq '' then return ; dlooker_display,state,/noload,/noscore ; dlooker_updatescore,state,/refresh ; end ; else: begin MESSAGE, 'Unknown menu event:', /INFO HELP, event, /STRUCTURE end endcase end 'Blink Set': begin if (*state).rdir eq '' then return ; Z is the group number z=where((*(*state).nrep) gt 1,count) if count eq 0 then return idx=where((*(*state).night) eq z[event.index],count) if count eq 0 then return ; safety, shouldn't happen ptr_free,(*state).blinkidx (*state).blinkidx=ptr_new(idx) end 'blink': begin if (*state).rdir eq '' then return z=where((*(*state).nrep) gt 1,count) if count eq 0 then return if (*state).blink eq 0 then begin (*state).blink = 512 (*state).blinkframe=0 widget_control,(*state).blinkid,timer=float((*state).blink)/1000.0 endif else if (*state).blink eq -1 then begin (*state).blink = 0 endif else if (*state).blink eq -2 then begin ; single step to next frame newblinkframe=(*state).blinkframe+1 if newblinkframe eq n_elements((*(*state).blinkidx)) then $ newblinkframe=0 (*state).blinkframe = newblinkframe endif else if (*state).blink gt 0 then begin widget_control,(*state).blinkid,timer=float((*state).blink)/1000.0 newblinkframe=(*state).blinkframe+1 if newblinkframe eq n_elements((*(*state).blinkidx)) then $ newblinkframe=0 (*state).blinkframe = newblinkframe endif else begin print,'LOOKER: Illegal blink value! ',(*state).blink (*state).blink = 0 endelse if (*state).blink eq 0 then begin ; restore normal display dlooker_display,state,/noscore endif else begin ; show blinkframe idx=(*state).blinkframe visit=(*(*state).blinkidx)[idx] (*state).curvis=visit dlooker_display,state,/noscore endelse end 'blink slower': begin if (*state).rdir eq '' then return z=where((*(*state).nrep) gt 1,count) if count eq 0 then return if (*state).blink eq 0 then begin return endif else if (*state).blink gt 0 then begin (*state).blink = (*state).blink*2 if (*state).blink gt 8192 then (*state).blink=8192 endif end 'blink faster': begin if (*state).rdir eq '' then return z=where((*(*state).nrep) gt 1,count) if count eq 0 then return if (*state).blink eq 0 then begin return endif else if (*state).blink gt 0 then begin (*state).blink = (*state).blink/2 if (*state).blink lt 128 then (*state).blink=128 endif else if (*state).blink eq -2 then begin (*state).blink = 1024 widget_control,(*state).blinkid,timer=float((*state).blink)/1000.0 endif ; do nothing if blink -1 or < -2 end 'blink pause': begin if (*state).rdir eq '' then return z=where((*(*state).nrep) gt 1,count) if count eq 0 then return if (*state).blink eq 0 then $ return $ else $ (*state).blink = -2 end 'blink stop': begin if (*state).rdir eq '' then return z=where((*(*state).nrep) gt 1,count) if count eq 0 then return if (*state).blink eq 0 then return (*state).blink = -1 end 'Change Basis': begin if event.str eq (*state).basis then return (*state).basis=event.str dlooker_loadset,state,(*state).set dlooker_display,state end 'Change Type': begin if event.str eq (*state).type then return (*state).type=event.str dlooker_loadset,state,(*state).set dlooker_display,state end ; 'Down1': begin ; if (*state).idxfn2 lt 0 then return ; idx = (*state).idxfn2*2 ; (*(*state).offvals)[idx+1] = (*(*state).offvals)[idx+1]+1 ; (*state).dirtylist = 1 ; idx = (*state).idxfn2*2 ; dlooker_display,state,/noscore ; dlooker_objinfo,state ; end ; 'Initials': begin dlooker_checkinitials,state end ; 'Left1': begin ; if (*state).idxfn2 lt 0 then return ; idx = (*state).idxfn2*2 ; (*(*state).offvals)[idx] = (*(*state).offvals)[idx]+1 ; (*state).dirtylist = 1 ; idx = (*state).idxfn2*2 ; dlooker_display,state,/noscore ; dlooker_objinfo,state ; end 'Next': begin if (*state).rdir eq '' then return nparts=n_elements((*(*state).partlist)) nchips=n_elements((*(*state).chiplist)) nfields=n_elements((*(*state).fieldlist)) z=trimrank(where((*state).part eq (*(*state).partlist),/null))+1 if z eq nparts then begin z=0 carry=1 endif else carry=0 newpart=(*(*state).partlist)[z] if carry then begin z=trimrank(where((*state).chip eq (*(*state).chiplist),/null))+1 if z eq nchips then begin z=0 carry=1 endif else carry=0 newchip=(*(*state).chiplist)[z] endif else newchip=(*state).chip if carry then begin z=trimrank(where((*state).field eq (*(*state).fieldlist),/null))+1 if z eq nfields then begin z=0 carry=1 endif else carry=0 newfield=(*(*state).fieldlist)[z] endif else newfield=(*state).field if carry eq 1 then begin print,'Already at last set, cannot move forward' return endif dlooker_loadset2,state,newfield,newchip,newpart dlooker_display,state end 'Next chip': begin if (*state).rdir eq '' then return z=where((*state).chip eq (*(*state).chiplist),/null) if z[0] eq !NULL then return z = trimrank(z)+1 if z eq n_elements((*(*state).chiplist)) then begin print,'Already at the last chip, cannot go forward.' return endif dlooker_loadset2,state,(*state).field, $ (*(*state).chiplist)[z], $ (*(*state).partlist)[0] dlooker_display,state end 'Next field': begin if (*state).rdir eq '' then return z=where((*state).field eq (*(*state).fieldlist),/null) if z[0] eq !NULL then return z = trimrank(z)+1 if z eq n_elements((*(*state).fieldlist)) then begin print,'Already at the last field, cannot go forward.' return endif dlooker_loadset2,state,(*(*state).fieldlist)[z], $ (*(*state).chiplist)[0], $ (*(*state).partlist)[0] dlooker_display,state end 'Next part': begin if (*state).rdir eq '' then return z=where((*state).part eq (*(*state).partlist),/null) if z[0] eq !NULL then return z = trimrank(z)+1 if z eq n_elements((*(*state).partlist)) then begin print,'Already at the last part, cannot go forward.' return endif dlooker_loadset2,state,(*state).field, $ (*state).chip, $ (*(*state).partlist)[z] dlooker_display,state end 'Next visit': begin if (*state).rdir eq '' then return newvisit = (*state).curvis+1 if newvisit eq (*state).nvisits then newvisit=0 (*state).curvis=newvisit dlooker_display,state,/noscore end ; 'New Object': begin ; if (*state).curobj eq (*state).nobj or (*state).curobj lt 0 then return ; (*state).curobj = (*state).nobj ; dlooker_objinfo,state ; dlooker_setzoom,state,/reset ; end 'Previous': begin if (*state).rdir eq '' then return nparts=n_elements((*(*state).partlist)) nchips=n_elements((*(*state).chiplist)) nfields=n_elements((*(*state).fieldlist)) z=trimrank(where((*state).part eq (*(*state).partlist),/null))-1 if z lt 0 then begin z=nparts-1 carry=1 endif else carry=0 newpart=(*(*state).partlist)[z] if carry then begin z=trimrank(where((*state).chip eq (*(*state).chiplist),/null))-1 if z lt 0 then begin z=nchips-1 carry=1 endif else carry=0 newchip=(*(*state).chiplist)[z] endif else newchip=(*state).chip if carry then begin z=trimrank(where((*state).field eq (*(*state).fieldlist),/null))-1 if z lt 0 then begin z=nfields-1 carry=1 endif else carry=0 newfield=(*(*state).fieldlist)[z] endif else newfield=(*state).field if carry eq 1 then begin print,'Already at first set, cannot move backward' return endif dlooker_loadset2,state,newfield,newchip,newpart dlooker_display,state end 'Prev chip': begin if (*state).rdir eq '' then return z=where((*state).chip eq (*(*state).chiplist),/null) if z[0] eq !NULL then return z = trimrank(z)-1 if z lt 0 then begin print,'Already at the first chip, cannot go back further.' return endif dlooker_loadset2,state,(*state).field, $ (*(*state).chiplist)[z], $ (*(*state).partlist)[0] dlooker_display,state end 'Prev field': begin if (*state).rdir eq '' then return z=where((*state).field eq (*(*state).fieldlist),/null) if z[0] eq !NULL then return z = trimrank(z)-1 if z lt 0 then begin print,'Already at the first field, cannot go back further.' return endif dlooker_loadset2,state,(*(*state).fieldlist)[z], $ (*(*state).chiplist)[0], $ (*(*state).partlist)[0] dlooker_display,state end 'Prev part': begin if (*state).rdir eq '' then return z=where((*state).part eq (*(*state).partlist),/null) if z[0] eq !NULL then return z = trimrank(z)-1 if z lt 0 then begin print,'Already at the first part, cannot go back further.' return endif dlooker_loadset2,state,(*state).field, $ (*state).chip, $ (*(*state).partlist)[z] dlooker_display,state end 'Prev visit': begin if (*state).rdir eq '' then return newvisit = (*state).curvis-1 if newvisit lt 0 then newvisit=(*state).nvisits-1 (*state).curvis=newvisit dlooker_display,state,/noscore end ; 'Right1': begin ; if (*state).idxfn2 lt 0 then return ; idx = (*state).idxfn2*2 ; (*(*state).offvals)[idx] = (*(*state).offvals)[idx]-1 ; (*state).dirtylist = 1 ; idx = (*state).idxfn2*2 ; dlooker_display,state,/noscore ; dlooker_objinfo,state ; end ; 'Score': BEGIN if (*state).rdir eq '' then return case event.press OF 0: begin end ; Move to cursor location 1: begin xm = fix(( event.x-(*state).szsx/2.0 ) * (*state).sf + (*state).nx/2.0) ym = fix(( event.y-(*state).szsy/2.0 ) * (*state).sf + (*state).ny/2.0) (*state).x0 = xm - (*state).szx/2 (*state).y0 = ym - (*state).szy/2 dlooker_display,state end ; Move half field either up/down or right/left depending on largest ; distance between current point and cursor point. 2: begin xm = fix(( event.x-(*state).szsx/2.0 ) * (*state).sf + (*state).nx/2.0) ym = fix(( event.y-(*state).szsy/2.0 ) * (*state).sf + (*state).ny/2.0) newx0 = xm - (*state).szx/2 newy0 = ym - (*state).szy/2 xdiff = (*state).x0 - newx0 ydiff = (*state).y0 - newy0 if abs(xdiff) gt abs(ydiff) then begin newx0 = (*state).x0 + (xdiff gt 0.0 ? -1.0 : 1.0) * (*state).szx/2 newy0 = (*state).y0 endif else begin newx0 = (*state).x0 newy0 = (*state).y0 + (ydiff gt 0.0 ? -1.0 : 1.0) * (*state).szy/2 endelse (*state).x0 = newx0 (*state).y0 = newy0 dlooker_display,state end ; Move full field either up/down or right/left depending on largest ; distance between current point and cursor point. 4: begin xm = fix(( event.x-(*state).szsx/2.0 ) * (*state).sf + (*state).nx/2.0) ym = fix(( event.y-(*state).szsy/2.0 ) * (*state).sf + (*state).ny/2.0) xm = xm / (*state).szx * (*state).szx ym = ym / (*state).szy * (*state).szy (*state).x0 = xm (*state).y0 = ym dlooker_display,state end else: begin MESSAGE, 'Unknown window event:', /INFO HELP, event, /STRUCTURE end endcase ; ; if current object is no longer on frame, then set current ; ; object to NEW ; if (*state).curobj ne (*state).nobj and (*state).nfiles le 2 then begin ; objx = (*(*state).xyvals)[0,(*state).curobj] ; objy = (*(*state).xyvals)[1,(*state).curobj] ; if objx lt (*state).x0 or objy lt (*state).y0 or $ ; objx gt (*state).x0+(*state).szx-1 or $ ; objy gt (*state).y0+(*state).szy-1 then begin ; ; (*state).curobj = (*state).nobj ; dlooker_setzoom,state,/reset ; dlooker_objinfo,state ; endif ; endif end ; ; 'Set Flag': begin ; ; if (*state).curobj eq (*state).nobj or (*state).curobj lt 0 then return ; ; (*(*state).flags)[(*state).curobj] = event.value ; idstr = (*(*state).idstr)[(*state).curobj] ; dlooker_updateidstr,idstr,curinitials ; (*(*state).idstr)[(*state).curobj] = idstr ; ; (*state).dirtylist = 1 ; if event.value ne 'y' then begin ; (*state).curobj=(*state).nobj ; dlooker_setzoom,state,/reset ; endif ; ; dlooker_display,state,/noload,/noscore ; dlooker_updatescore,state,/refresh ; dlooker_objinfo,state ; end 'Set Max Sig': begin widget_control, event.id, GET_VALUE=hivalue hivalue = float(fix(hivalue[0]*10.0))/10.0 widget_control, (*state).minsigid, GET_VALUE=lovalue lovalue=float(lovalue[0]) if lovalue eq hivalue then hivalue=hivalue+0.1 hivalue = strcompress(string(hivalue,format='(f10.1)')) widget_control, (*state).maxsigid, SET_VALUE=hivalue dlooker_stretch,state dlooker_display,state,/noscore end 'Set Min Sig': begin widget_control, event.id, GET_VALUE=lovalue lovalue = float(fix(lovalue[0]*10.0))/10.0 widget_control, (*state).maxsigid, GET_VALUE=hivalue hivalue=float(hivalue[0]) if lovalue eq hivalue then lovalue=lovalue-0.1 lovalue = strcompress(string(lovalue,format='(f10.1)')) widget_control, (*state).minsigid, SET_VALUE=lovalue dlooker_stretch,state dlooker_display,state,/noscore end ; 'Up1': begin ; if (*state).idxfn2 lt 0 then return ; idx = (*state).idxfn2*2 ; (*(*state).offvals)[idx+1] = (*(*state).offvals)[idx+1]-1 ; (*state).dirtylist = 1 ; idx = (*state).idxfn2*2 ; dlooker_display,state,/noscore ; dlooker_objinfo,state ; end ; 'Window': BEGIN if (*state).rdir eq '' then return case event.press OF 0: begin end 1: begin if (*state).curobj lt 0 then begin print,'define new object' endif print,'Window, left button press' x=event.x+(*state).x0 y=event.y+(*state).y0 exact=0 dlooker_measure,state,(*state).curvis,x,y,exact,error, $ xpos,ypos,maxsig,sky,skysig dlooker_setzoom,state,(*state).curvis,xpos,ypos,maxsig,sky,skysig end 2: begin if (*state).curobj lt 0 then return if (*state).colormode eq 0 then return print,'Window, middle button press' print,event.x+(*state).x0,event.y+(*state).y0 end 4: begin print,'Window, right button press' end else: begin MESSAGE, 'Unknown window event:', /INFO HELP, event, /STRUCTURE end endcase END ; 'Zoom': BEGIN ; if (*state).lastfn2 eq '' or (*state).curframe eq 0 then return ; case event.press OF ; 0: begin ; end ; 1: begin ; ; position for measurement ; xc = (float(event.x)+0.5)/(*state).zf+(*state).zx0-0.5 ; yc = (float(event.y)+0.5)/(*state).zf+(*state).zy0-0.5 ; ; dlooker_measure,state,xc,yc,1,error ; if error then return ; ; dlooker_refreshzoom,state,xc,yc ; ; end ; 2: begin ; ; position for measurement ; xc = (float(event.x)+0.5)/(*state).zf+(*state).zx0-0.5 ; yc = (float(event.y)+0.5)/(*state).zf+(*state).zy0-0.5 ; ; dlooker_measure,state,xc,yc,1,error,xpos,ypos,maxsig,sky,skysig ; if error then return ; ; dlooker_setzoom,state,xpos,ypos,maxsig,sky, $ ; skysig*sqrt( ((*state).radius+30.0)^2 - $ ; ((*state).radius+10.0)^2 *!pi ) ; end ; 4: begin ; print,'right click in zoom window' ; help,event,/st ; end ; else: begin ; MESSAGE, 'Unknown window event:', /INFO ; HELP, event, /STRUCTURE ; end ; endcase ; END ELSE : BEGIN print,'EVENT NAME: ',event_name MESSAGE, 'Unknown event:', /INFO HELP, event, /STRUCTURE END ENDCASE END ; end of event handler ;------------------------------------------------------------------------------ PRO dlooker,PATH=path,XSIZE=szx,YSIZE=szy,ZXSIZE=szsx,ZYSIZE=szsy if xregistered('dlooker') then return IF (!d.flags and 256) eq 0 THEN BEGIN print, 'Error. No windowing device. LOOKER cannot be started.' return ENDIF IF !d.n_colors ne 16777216 THEN BEGIN print,'Error. 24-bit display device is required.' return ENDIF IF badpar(path,[0,7],0,CALLER='LOOKER: (PATH) ', $ DEFAULT='/net/wixer/raid/buie/') THEN RETURN if path ne '' then path=addslash(path) IF badpar(szx,[0,2,3],0, $ caller='LOOKER: (XSIZE) ',default=1200) THEN RETURN IF badpar(szy,[0,2,3],0, $ caller='LOOKER: (YSIZE) ',default=1100) THEN RETURN IF badpar(szsx,[0,2,3],0, $ caller='LOOKER: (ZXSIZE) ',default=148) THEN RETURN IF badpar(szsy,[0,2,3],0, $ caller='LOOKER: (ZYSIZE) ',default=296) THEN RETURN basislist= ['Delta','Gaussian'] typelist=['pair','template'] setusym,-1 ;Define the main base. mainbase=widget_base(TITLE='DLOOKER: Visual Inspection and Measuring Tool', $ /COLUMN,UVALUE=0,MBAR=bar) menu = CW_PdMenu(bar, /RETURN_NAME, $ ['1\File',$ '0\Select run', $ '0\Select field',$ '0\Select chip',$ '0\Change secondary field', $ '0\Autoload Toggle', $ '0\Postscript Hardcopy', $ '2\Exit',$ '1\Edit', $ '2\Set all ? to N', $ '1\Tools',$ '0\Refresh display', $ '0\Copy stretch', $ '0\Suppress overlay', $ '0\Toggle lines', $ '0\Toggle color mode', $ '2\Snap object'], UVALUE='THE_MENU', /MBAR) base = widget_base( mainbase, /ROW ) win1 = widget_draw( base, XSIZE=szx, YSIZE=szy, RETAIN=2, $ /BUTTON_EVENTS, UVALUE='Window' ) cbase = widget_base( base, /COLUMN ) win2 = widget_draw( cbase, XSIZE=szsx, YSIZE=szsy, RETAIN=2, $ /BUTTON_EVENTS, UVALUE='Score' ) win3 = widget_draw( cbase, XSIZE=szsx, YSIZE=szsx, RETAIN=2, $ /BUTTON_EVENTS, UVALUE='Zoom' ) b1 = widget_base( cbase, /column, /frame) b2 = widget_base( b1, /row ) t1 = widget_label( b2, value='Object:' ) curobj = widget_label( b2, value=' ', /align_left, /dynamic_resize ) b2 = widget_base( b1, /row ) t1 = widget_label( b2, value=' V/Dir:' ) rate = widget_label( b2, value=' ', /align_left, /dynamic_resize ) b2 = widget_base( b1, /row ) t1 = widget_label( b2, value=' Flags:' ) flag = cw_bgroup( b2, ['?','y','n'], /no_release, $ /return_name, /exclusive, /row, uvalue='Set Flag' ) newobj = widget_button( cbase, VALUE='New Object', uvalue='New Object' ) cbase = widget_base( base, /COLUMN ) b1 = widget_base( cbase, /row, /frame) t1 = widget_label( b1, value='Run:' ) runid = widget_label( b1, value='',/dynamic_resize) b1 = widget_base( cbase, /row, /frame) previd = widget_button( b1, VALUE='Previous', uvalue='Previous' ) nextid = widget_button( b1, VALUE='Next', uvalue='Next' ) initialsid = widget_text(b1, VALUE='', /EDITABLE, XSIZE=4, uvalue='Initials' ) b2 = widget_base(cbase,/column,/frame) b3 = widget_base(b2,/row) t1 = widget_button(b3,VALUE='Field -',uvalue='Prev field') t1 = widget_button(b3,VALUE='Field +',uvalue='Next field') b3 = widget_base(b2,/row) t1 = widget_button(b3,VALUE=' Chip -',uvalue='Prev chip') t1 = widget_button(b3,VALUE=' Chip +',uvalue='Next chip') b3 = widget_base(b2,/row) t1 = widget_button(b3,VALUE=' Part -',uvalue='Prev part') t1 = widget_button(b3,VALUE=' Part +',uvalue='Next part') b3 = widget_base( b2, /row ) t1 = widget_label( b3, value=' Basis:' ) basisid=widget_combobox(b3,value=basislist,sensitive=0, $ uvalue='Change Basis',/dynamic_resize ) b3 = widget_base( b2, /row ) t1 = widget_label( b3, value=' Type:' ) typeid=widget_combobox(b3,value=typelist,sensitive=0, $ uvalue='Change Type',/dynamic_resize ) b1 = widget_base( cbase, /column, /frame) b2 = widget_base( b1, /row ) t1 = widget_label( b2, value=' Set:' ) setid = widget_label(b2, value='', /dynamic_resize ) b2 = widget_base( b1, /row ) t1 = widget_label( b2, value=' Visit:' ) visitid = widget_label( b2, value='', /dynamic_resize ) timeid = widget_label( b1, value='', /dynamic_resize ) info1id = widget_label( b1, value='', /dynamic_resize ) info2id = widget_label( b1, value='', /dynamic_resize ) b2 = widget_base(b1,/row) t1 = widget_button(b2,VALUE='Visit -',uvalue='Prev visit') t1 = widget_button(b2,VALUE='Visit +',uvalue='Next visit') b2 = widget_base(cbase,/row,/frame) b3 = widget_base(b2,/column) b4 = widget_base( b3, /row ) t1 = widget_label(b4,value='Blink Set:' ) blinksetid=widget_combobox(b4,value=strn(0),sensitive=0, $ uvalue='Blink Set',/dynamic_resize ) b4 = widget_base(b3,/row) t1 = widget_button(b4,VALUE='X',uvalue='blink stop') t1 = widget_button(b4,VALUE='-',uvalue='blink slower') t1 = widget_button(b4,VALUE='[ ]',uvalue='blink pause') t1 = widget_button(b4,VALUE='+',uvalue='blink faster') blinkid = widget_button(b4, VALUE='>',uvalue='blink') b2 = widget_base( cbase, /column, /frame) t1 = widget_label( b2, VALUE='Max Display (sigma)' ) maxsig = widget_text( b2, VALUE='5', /EDITABLE, XSIZE=5, uvalue='Set Max Sig' ) b2 = widget_base( cbase, /column, /frame) t1 = widget_label( b2, VALUE='Min Display (sigma)' ) minsig = widget_text( b2, VALUE='-3', /EDITABLE, XSIZE=5, uvalue='Set Min Sig' ) widget_control, flag, SENSITIVE=0 state = ptr_new({ $ ; Data and information in the widget ; autoload: 1, $ ; Automatically load frame pair if set. astinfo: ptr_new(), $ ; Astrometry information for current set. basis: 'Delta', $ ; Current active diff basis set basislist: basislist, $ ; list of basis choices bcube: ptr_new(), $ ; pre-scaled images from all visits. blink: 0, $ ; Blink rate in milliseconds. Disabled if 0 blinkframe: 0B, $ ; Current blinking frame showing. blinkid: blinkid, $ ; widget id for timer events and starting. blinkidx: ptr_new(), $ ; index of visits to blink chip: 0, $ ; current chip being displayed chiplist: ptr_new(), $ ; list of chips colormode: 0, $ ; 1=color composite, 0=b/w cube: ptr_new(), $ ; Difference images from all visits. ; curframe: 0, $ ; Current frame being measured. curobj: -1, $ ; Current object number being manipulated. ; curobjname: '', $ ; Current object name. curvis: -1, $ ; current visit number db: '', $ ; Support database for difference data decrange: dblarr(2), $ ; range of Dec for current set dimgfwhm: ptr_new(), $ ; FWHM of images in current set dreffwhm: ptr_new(), $ ; FWHM of images in current set ; dir: ptr_new(), $ ; Direction of motion (degrees) ; dirtylist: 0, $ ; Flag, if true object/file list needs saving. dpath: '', $ ; full path exptime: ptr_new(), $ ; exposure time ; exttag: '', $ ; Image extension tag. field: '', $ ; Name of current field. fieldlist: ptr_new(), $ ; List of available fields. ; flags: ptr_new(), $ ; Object validity flags. ; fnobj: '', $ ; File name of current field object list. ; fntrip: ptr_new(), $ ; Pointer to string array of file names for field. fwhm: ptr_new(), $ ; FWHM of images in current set ; dt: ptr_new(), $ ; Pointer to array of delta t from first frame. ; g: ptr_new(bytarr(szx,szy)), $ ; green (and blue) plane of color cube for display gain: -1.0, $ ; Gain of CCD (e-/ADU). ; hdr1: ptr_new(), $ ; Header of frame 1 ; hdr2: ptr_new(), $ ; Header of frame 2 ; highval1: 0.0, $ ; top of stretch for image 1. ; highval2: 0.0, $ ; top of stretch for image 2. ; idstr: ptr_new(), $ ; Object measurement description strings. ; idxfn2: -1, $ ; Index for file 2 into oblist data. ; im1: ptr_new(), $ ; Pointer to primary epoch image. ; im2: ptr_new(), $ ; Pointer to secondary epoch image. ; info1: ptr_new(), $ ; Pointer to information structure on image 1. ; info2: ptr_new(), $ ; Pointer to information structure on image 2. initials: '', $ ; String, initials of scanner. invert: ptr_new(), $ ; Flag array, true if image is to be flipped jdmid: ptr_new(), $ ; Jd of all exposures in visit ; lastobj: '', $ ; Name of last object list file loaded. ; lastfn2: '', $ ; Name of last secondary image loaded. ; lines: 1B, $ ; Flag, if true connecting lines are drawn. ; lowval1: 0.0, $ ; bottom of stretch for image 1. ; lowval2: 0.0, $ ; bottom of stretch for image 2. maglim: ptr_new(), $ ; FWHM of images in current set night: ptr_new(), $ ; night number for each visit nrep: ptr_new(), $ ; number of visits on each night nvisits: 0, $ ; number of visits for the current set. ; nomarks: 0, $ ; Flag, if true suppress overplot in main window ; numext: 1, $ ; Number of frame extensions. nx: 0L, $ ; X size of image(s). ny: 0L, $ ; Y size of image(s). objrad: ptr_new(), $ odec: ptr_new(), $ onum: 0L, $ ; number of objects loaded ora: ptr_new(), $ ox: ptr_new(), $ oy: ptr_new(), $ omag: ptr_new(), $ ; objpath: '', $ ; Path to object list file. ; offvals: ptr_new(), $ ; Offsets between frames. part: '', $ ; current image part partlist: ptr_new(), $ ; List of image parts path: path, $ ; Location for raw image data. photzp: ptr_new(), $ ; photometric zero-point ; pscale: -1.0, $ ; Plate scale of image. ; r: ptr_new(bytarr(szx,szy)), $ ; red plane of color cube for display ; radius: -1.0, $ ; Object aperture radius. rarange: dblarr(2), $ ; range of RA for current set ; rate: ptr_new(), $ ; Rate of motion ("/hr) ; ref1: [0.0,0.0], $ ; Reference position of image 1. ; ref2: [0.0,0.0], $ ; Reference position of image 2. rdir: '', $ ; Run ID set: '', $ ; name of current set setlist: ptr_new(), $ ; List of image sets sf: 1.0, $ ; Scale factor between full image and score. srgb: bytarr(szsx,szsy,3), $ ; color cube for score szsx: szsx, $ ; X-width of score display in pixels. szsy: szsy, $ ; Y-width of score display in pixels. szx: szx, $ ; X-width of main display in pixels. szy: szy, $ ; Y-width of main display in pixels. ; tdec: ptr_new(), $ ; tnum: 0L, $ ; tra: ptr_new(), $ ; ttype: ptr_new(), $ ; tx: ptr_new(), $ ; ty: ptr_new(), $ type: 'pair', $ ; style of difference to view typelist: typelist, $ ; list of types visitlist: ptr_new(), $ ; ordered list of files in the visit. x0: 0, $ ; LLHC of display window from full image. ; xyvals: ptr_new(), $ ; Object locations. y0: 0, $ ; LLHC of display window from full image. zim: bytarr(szsx/4,szsx/4), $ ; Zoom image for display. zf: 4, $ ; Zoom factor for zoom window display. zx0: 0, $ ; LLHC of zoom display window from full image. zy0: 0, $ ; LLHC of zoom display window from full image. ; Widget ids blinksetid: blinksetid, $ ; ID showing current blink set curobjid: curobj, $ ; ID of label that shows current object id. drawwin: win1, $ ; ID of main draw window setid: setid, $ ; ID of label that shows current set name. flagid: flag, $ ; ID of object flag button list. visitid: visitid, $ ; ID of label that shows current image #1 basisid: basisid, $ ; ID of label that shows current image #2 initialsid: initialsid, $ ; ID of label that shows initials of scanner info1id: info1id, $ ; Image info line 1 info2id: info2id, $ ; Image info line 1 mainbase: mainbase, $ ; ID of top level base. maxsigid: maxsig, $ ; ID of text widget with display max minsigid: minsig, $ ; ID of text widget with display max nextid: nextid, $ ; ID of Next button previd: previd, $ ; ID of Previous button rateid: rate, $ ; ID of label that shows rate/dir of current runid: runid, $ ; ID of label that shows current run scorewin: win2, $ ; ID of score and pan control window timeid: timeid, $ ; Where to time of exposure for display typeid: typeid, $ ; ID of difference type zoomwin: win3 $ ; ID of zoom window }) ;Stash the state structure pointer. widget_control, mainbase, SET_UVALUE=state ;Realize the main base. widget_control, mainbase, /REALIZE ; Give control to the XMANAGER. XMANAGER, 'dlooker', mainbase, $ EVENT_HANDLER='dlooker_eve',/NO_BLOCK, $ GROUP_LEADER=mainbase, CLEANUP='dlooker_cleanup' end