;+ ; NAME: ; cw_itool ; PURPOSE: ; General purpose image display. ; DESCRIPTION: ; CATEGORY: ; Compound Widgets ; CALLING SEQUENCE: ; result = cw_itool( parent ) ; INPUTS: ; parent : The parent application base (Should be a Top Level Base). ; OPTIONAL INPUT PARAMETERS: ; image : The image array to be displayed. ; KEYWORD PARAMETERS: ; FVISIBLE : Size of the full-view window (128 pixels). ; NODISMISS : If set, the Dismiss button is not sensitive. ; PHOTPARMFILE : Optional photometry parameters file. ; TMPLFILE : Optional Photometry template file. ; XSIZE : The image X-size (required). ; YSIZE : The image Y-size (required). ; WXVISIBLE : Creates work window with explicit x-size (500). ; WYVISIBLE : Creates work window with explicit y-size (500). ; WZOOMFACT : Ceiling for work-view zoom factor (unlimited). ; ZVISIBLE : Size of the zoom window (128 pixels). ; ; OUTPUTS: ; OPTIONAL OUTPUT PARAMETERS: ; ; COMMON BLOCKS: ; ; SIDE EFFECTS: ; ; RESTRICTIONS: ; ; proCEDURE: ; ; MODIFICATION HISTORY: ; Written by Doug Loucks, Lowell Observatory, June 1994. ; This version is a major re-write, employing the compound widget design ; introduced in Version 3 of IDL. ; 94/10/27, MWB, Lowell Observatory, fixed ZOON bug on line 1144. ; 95/01/24, MWB, xcen,ycen size mismatch storing back to template if array is ; 3-d. Fixed to copy *last* position from Basphote return. ; 95/06/12, MWB, Fixed bug in stretch range computation for large cubes of ; small images. ; 95/09/07, MWB, Changed auto-stretch computation to make it more robust. ; 95/10/31, MWB, Fixed widget layout problem caused by IDL v4.0 changes. ; 96/01/06, MWB, Changed W*VISIBLE default to recognize smaller screens. ; 96/01/16, MWB, Fixed !order=1 bug in mouse event handling. ; Fixed Stretch Menu operational bugs for handling image cubes. ; 96/06/25, MWB, Added autophot support ; 97/12/12, MWB, changed display to include more image info on main window. ; 99/08/31, MWB (with help from John Mattox, Boston University), added a ; feature that overplots the aperture on the zoom window ; image after template or single-object photometry measurement. ; 2001/4/3, MWB, added plotting of active template in work window ; 2001/9/18, MWB, fixed color error in plots with 8-bit display. ;- ; ------------------------------------------------------------------------------ ; Internal Support Procedures: ; ; cw_itool_apdraw : Draw photometric aperture in zoom window. ; cw_itool_cstr : Computes a stretch range for the image. ; cw_itool_disp : Refreshes the image display label and text widgets. ; cw_itool_trk : Refreshes the cursor tracking display widgets. ; cw_itool_draw : Refreshes the draw widgets (full, zoom, and work). ; cw_itool_gvl : Gets cw_itool's value. This value is defined to be a ; structure with a single tag of type string: {msg:['']}. ; If the string is non-null, cw_itool has determined that ; it should not be killed and has placed the reasons into ; the string tag as a string array. ; cw_itool_tpdraw : Plot current template in work window. ; cw_itool_svl : Sets cw_itool's value (defined as the im_parms structure). ; cw_itool_phact : Action routine for template photometry. ; cw_itool_oneph : Do one single object photometry operation. ; cw_draw_eve : ; cw_itool_eve : Master event handler for cw_itool. ; cw_itool_tpeve : Event handler for cw_tpmgr pass-through events. ; cw_pixed_exteve : Event handler for events arriving from the pixel editor. ; ------------------------------------------------------------------------------ ; ------------------------------------------------------------------------------ ; Procedure cw_itool_cstr ; Compute the stretch range for the image. ; ------------------------------------------------------------------------------ pro cw_itool_cstr, im_parms, frame, SILENT=silent if im_parms.ready[frame] then return widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY minvalue = min( image[*,*,frame], max=maxvalue ) im_parms.minvalue[frame] = minvalue im_parms.maxvalue[frame] = maxvalue ; Compute stretch range parameters. ; Grab 101 random pixels from image and sort them. idx = randomu(seed,151) * ((im_parms.xsize*im_parms.ysize)-1) + $ im_parms.xsize*im_parms.ysize*frame timage = image[idx] s = sort( timage ) z_image = timage[ s ] l = size( s ) l = l[ 1 ] medvalue = z_image[ l / 2 ] t1 = 0.20 * l ; old value was 0.02 t2 = 0.80 * l ; old value was 0.90 sdvalue = stdev( z_image[ t1 : t2 ] ) m1 = z_image[ t1 ] m2 = z_image[ t2 ] timage = 0 z_image = 0 dm = 3 dp = 5 f = '(G0.0)' z1 = medvalue - sdvalue * dm z2 = medvalue + sdvalue * dp if z1 eq z2 then begin z1 = minvalue z2 = maxvalue endif if z1 eq z2 then $ z2 = z2 + 1 im_parms.sclmin[frame] = z1 im_parms.sclmax[frame] = z2 if im_parms.sclmin[frame] lt im_parms.minvalue[frame] then begin im_parms.sclmin[frame] = im_parms.minvalue[frame] endif if im_parms.sclmax[frame] gt im_parms.maxvalue[frame] then begin im_parms.sclmax[frame] = im_parms.maxvalue[frame] endif im_parms.curmin[frame] = im_parms.sclmin[frame] im_parms.curmax[frame] = im_parms.sclmax[frame] im_parms.ready[frame] = 1B if not keyword_set( silent ) then begin print, 'Median: ' + string( medvalue, format='(G0.0)' ) + $ ' Sigma: ' + string( sdvalue, format='(G0.0)' ) + $ ' Sub-array min, max: ' + string( m1, format='(G0.0)' ) + ', ' + $ string( m2, format='(G0.0)' ) endif widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_disp ; Update the display widgets. ; ------------------------------------------------------------------------------ pro cw_itool_disp, state widget_control, state.mainbase, UPDATE=0 widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY frame = im_parms.frame ;Compute stretch, if necessary. cw_itool_cstr, im_parms, frame maxvalue = string( im_parms.maxvalue[frame], format=state.fmtg ) minvalue = string( im_parms.minvalue[frame], format=state.fmtg ) ; Show the image min and max. widget_control, state.imagemaxid, set_value=maxvalue widget_control, state.imageminid, set_value=minvalue ; Show the frame number. widget_control, state.frameid, set_value=string( im_parms.frame, $ format=state.fmti ) ;Show the total number of frames in this image file. widget_control, state.nframesid, set_value=string( im_parms.nframes, $ format=state.fmti ) if im_parms.imfile ne '' then begin ;Show the image file name. title = im_parms.title + ' ' + im_parms.imfile widget_control, state.mainbase, TLB_SET_TITLE=title endif ;Show the object name. if im_parms.object ne '' or im_parms.filter ne '' $ or im_parms.ut ne '' then begin str1=strmid('Object: '+im_parms.object,0,20) str2=strmid('Filter: '+im_parms.filter,0,20) str3=string('Airmas: ',im_parms.airmass,format='(a,f5.3)') str4=strcompress(string('ExpTim: ',im_parms.exptime, $ format='(a,f10.3," sec")')) jdstr,im_parms.jd,0,jds str5=' UT: '+strmid(jds,0,10) str6='midtim: '+strmid(jds,11,8) endif else begin str1='' str2='' str3='' str4='' str5='' str6='' endelse widget_control, state.objectid, set_value=str1 widget_control, state.filterid, set_value=str2 widget_control, state.airmasid, set_value=str3 widget_control, state.exptimid, set_value=str4 widget_control, state.utdateid, set_value=str5 widget_control, state.uttimeid, set_value=str6 ;Set some button sensitivities. widget_control, state.auto2id, SENSITIVE=(im_parms.nframes gt 1) widget_control, state.disp2id, SENSITIVE=(im_parms.nframes gt 1) widget_control, state.extrema2id, SENSITIVE=(im_parms.nframes gt 1) widget_control, state.animateid, SENSITIVE=(im_parms.nframes gt 1) widget_control, state.frameid, SENSITIVE=(im_parms.nframes gt 1) widget_control, state.nextframeid, SENSITIVE=(im_parms.nframes gt 1) curmin = string( im_parms.curmin[frame], format=state.fmtg ) curmax = string( im_parms.curmax[frame], format=state.fmtg ) ;Close access to the image parameters structure. widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ; Show the stretch range for the display. widget_control, state.dispminid, set_value=curmin widget_control, state.dispmaxid, set_value=curmax ;Update the image parameters widget. child = widget_info( state.imparmsbase, /CHILD ) if child ne 0L then begin ;Refresh the image parameters widget. widget_control, child, set_value=0 endif widget_control, state.mainbase, UPDATE=1 end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_apdraw ; Draw photometry aperture in the zoom window ; ------------------------------------------------------------------------------ pro cw_itool_apdraw, draw_state ;Open access to data. widget_control, draw_state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY widget_control, draw_state.zoom_view, get_uvalue=zoomstate, /NO_COPY widget_control, zoomstate.id, get_value=winnum widget_control, draw_state.phparmsbase, get_uvalue=ph_parms, /NO_COPY curwin = !d.window wset, winnum ; Draw photometry aperture. npts=500 xrad=0.5+ph_parms.radius*sin(2*!pi*findgen(npts+1)/float(npts))/zoomstate.dx yrad=0.5+ph_parms.radius*cos(2*!pi*findgen(npts+1)/float(npts))/zoomstate.dx seg=15 ; breaks up the circle into segments every SEG degrees. ang= fix( (findgen(npts+1)/npts*360.0) / seg) if draw_state.eightbit then begin color=bytarr(npts+1) ; alternate between color 0 and top color. color[where(ang eq (ang/2)*2)] = draw_state.ncolors-1 thick=2 endif else begin color = '0000ff'xl thick=1 endelse plots,xrad,yrad,color=color,thick=thick,/normal ;Restore the previous window number. wset, curwin ;Close access to data. widget_control, draw_state.phparmsbase, set_uvalue=ph_parms, /NO_COPY widget_control, draw_state.zoom_view, set_uvalue=zoomstate, /NO_COPY widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, draw_state.imparmsbase, set_uvalue=im_parms, /NO_COPY end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_tpdraw ; Draw template aperture in the work window ; ------------------------------------------------------------------------------ pro cw_itool_tpdraw, draw_state ;Get id of the Template Manager. tpmgrid = widget_info( draw_state.tpmgrbase, /CHILD ) ;Retrieve the 'value' of the template manager, which is the template list ;array. if tpmgrid ne 0L then begin widget_control, tpmgrid, get_value=tp_list selected = where( tp_list[*].selected eq 1B, count ) endif else begin count = 0 endelse if count eq 1 then begin widget_control, tp_list[selected].tpid, get_value=tplate if tplate.numobj gt 0 then begin widget_control, draw_state.work_view, get_uvalue=workstate, /NO_COPY widget_control, workstate.id, get_value=winnum wset, winnum if draw_state.eightbit then begin color=draw_state.ncolors-1 endif else begin if tplate.mode eq 0 then color='2f00ff'xl else color='00ff2f'xl endelse ; setup plotting coordinate system. plot,[0],[1],/nodata,xmargin=[0,0],ymargin=[0,0], $ xr=[0,workstate.xsize-1],yr=[0,workstate.ysize-1], $ xstyle=5,ystyle=5,/noerase setusym,-1 oplot,[tplate.x],[tplate.y],psym=8,color=color,symsize=2.0 oplot,[tplate.x[0]],[tplate.y[0]],psym=8,color=color,symsize=3.0 setusym,1 widget_control, draw_state.work_view, set_uvalue=workstate, /NO_COPY endif endif end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_trk ; Update the cursor tracking widgets. ; ------------------------------------------------------------------------------ pro cw_itool_trk, draw_state, in_x, in_y x = fix(in_x+0.5) y = fix(in_y+0.5) widget_control, draw_state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY count = image[ x, y, im_parms.frame ] widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, draw_state.imparmsbase, set_uvalue=im_parms, /NO_COPY curpos = string('xloc= ', x, ' yloc= ', y, $ ' count= ', count, format='(A,I4,A,I4,A,G0.0)' ) widget_control, draw_state.curposid, UPDATE=0 widget_control, draw_state.curposid, set_value=curpos widget_control, draw_state.curposid, UPDATE=1 end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_draw ; Update one or more of the draw widgets. ; ------------------------------------------------------------------------------ ; pro cw_itool_draw, draw_state, FULL=full, WorK=work, ZOOM=zoom, $ ZXCEN=zxcen, ZYCEN=zycen ;Optional zoom center update is provided via the keywords. ;Open access to data. widget_control, draw_state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY frame = im_parms.frame curmin = im_parms.curmin[frame] curmax = im_parms.curmax[frame] curwin = !d.window if keyword_set( full ) then begin ;Process the full window. widget_control, draw_state.full_view, get_uvalue=fullstate, /NO_COPY widget_control, fullstate.id, get_value=winnum wset, winnum if fullstate.zfact ne 1 then begin tv,bytscl(rebin(image[fullstate.spx:fullstate.spx+fullstate.dx-1, $ fullstate.spy:fullstate.spy+fullstate.dy-1, $ frame], $ fullstate.dx*fullstate.zfact, $ fullstate.dy*fullstate.zfact, $ /SAMPLE ), $ min=curmin,max=curmax,top=fullstate.ncolors-1 ), $ fullstate.xoff, fullstate.yoff endif else begin tv,bytscl(image[fullstate.spx:fullstate.spx+fullstate.dx-1, $ fullstate.spy:fullstate.spy+fullstate.dy-1,frame], $ min=curmin,max=curmax,top=fullstate.ncolors-1 ), $ fullstate.xoff, fullstate.yoff endelse widget_control, draw_state.full_view, set_uvalue=fullstate, /NO_COPY endif if keyword_set( zoom ) then begin ;Process the zoom window. widget_control, draw_state.zoom_view, get_uvalue=zoomstate, /NO_COPY widget_control, zoomstate.id, get_value=winnum wset, winnum if keyword_set( zxcen ) then zoomstate.xcen = fix(zxcen+0.5) if keyword_set( zycen ) then zoomstate.ycen = fix(zycen+0.5) ;Compute zoom window parameters. zoomstate.dx = zoomstate.xvisible / zoomstate.zfact if zoomstate.dx gt im_parms.xsize then zoomstate.dx=im_parms.xsize if zoomstate.dx gt im_parms.ysize then zoomstate.dx=im_parms.ysize zoomstate.dy = zoomstate.dx zoomstate.spx = zoomstate.xcen - ( zoomstate.dx / 2 ) zoomstate.spy = zoomstate.ycen - ( zoomstate.dy / 2 ) if (zoomstate.spx + zoomstate.dx) ge im_parms.xsize then begin zoomstate.spx = im_parms.xsize - zoomstate.dx - 1 zoomstate.xcen = zoomstate.spx + ( zoomstate.dx / 2 ) endif if (zoomstate.spy + zoomstate.dy) ge im_parms.ysize then begin zoomstate.spy = im_parms.ysize - zoomstate.dy - 1 zoomstate.ycen = zoomstate.spy + ( zoomstate.dy / 2 ) endif if zoomstate.spx lt 0 then zoomstate.spx = 0 if zoomstate.spy lt 0 then zoomstate.spy = 0 zoomstate.xsize = zoomstate.dx * zoomstate.zfact zoomstate.ysize = zoomstate.dy * zoomstate.zfact zoomstate.xoff = ( zoomstate.xvisible - zoomstate.xsize ) / 2 zoomstate.yoff = ( zoomstate.yvisible - zoomstate.ysize ) / 2 if zoomstate.zfact ne 1 then begin tv,bytscl(rebin(image[zoomstate.spx:zoomstate.spx+zoomstate.dx-1, $ zoomstate.spy:zoomstate.spy+zoomstate.dy-1, $ frame], $ zoomstate.zfact*zoomstate.dx, $ zoomstate.zfact*zoomstate.dy, $ /SAMPLE ), $ min=curmin,max=curmax,top=zoomstate.ncolors-1), $ zoomstate.xoff,zoomstate.yoff endif else begin tv,bytscl(image[zoomstate.spx:zoomstate.spx+zoomstate.dx-1, $ zoomstate.spy:zoomstate.spy+zoomstate.dy-1,frame], $ min=curmin,max=curmax,top=zoomstate.ncolors-1 ), $ zoomstate.xoff,zoomstate.yoff endelse widget_control, draw_state.zoom_view, set_uvalue=zoomstate, /NO_COPY endif if keyword_set( work ) then begin widget_control, draw_state.work_view, get_uvalue=workstate, /NO_COPY widget_control, workstate.id, get_value=winnum wset, winnum if workstate.zfact ne 1 then begin tv,bytscl(rebin(image[workstate.spx:workstate.spx+workstate.dx-1, $ workstate.spy:workstate.spy+workstate.dy-1, $ frame], $ workstate.zfact*workstate.dx, $ workstate.zfact*workstate.dy, $ /SAMPLE ), $ min=curmin,max=curmax,top=workstate.ncolors-1), $ workstate.xoff,workstate.yoff endif else begin tv,bytscl(image[workstate.spx:workstate.spx+workstate.dx-1, $ workstate.spy:workstate.spy+workstate.dy-1,frame], $ min=curmin,max=curmax,top=workstate.ncolors-1), $ workstate.xoff,workstate.yoff endelse widget_control, draw_state.work_view, set_uvalue=workstate, /NO_COPY cw_itool_tpdraw, draw_state endif ;Restore the previous window number. wset, curwin ;Refresh any profiles widgets that may be active. ;Open access to the profiles instances array. widget_control, draw_state.pfilesid, get_uvalue=instances, /NO_COPY v = widget_info( instances, /VALID_ID ) w = where( v ne 0, count ) if count ne 0 then begin ;There is at least one profiles widget active. frame = im_parms.frame widget_control, draw_state.zoom_view, get_uvalue=zoomstate, /NO_COPY spx = zoomstate.spx spy = zoomstate.spy dx = zoomstate.dx dy = zoomstate.dy widget_control, draw_state.zoom_view, set_uvalue=zoomstate, /NO_COPY array = image[spx:spx+dx-1, spy:spy+dy-1, frame] for j=0, count-1 do begin child = widget_info( instances[w[j]], /CHILD ) if child ne 0L then begin ;Found an active profile. Request an update by using the set_value ;keyword to widget_control (The profiles widget will ignore the ;update request if the display is locked). widget_control, child, set_value={image:array, xset:spx, yset:spy} endif endfor endif ;Close access to the profiles instances array. widget_control, draw_state.pfilesid, set_uvalue=instances, /NO_COPY ;Close access to data. widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, draw_state.imparmsbase, set_uvalue=im_parms, /NO_COPY end ; ------------------------------------------------------------------------------ ; Function cw_itool_gvl ; ------------------------------------------------------------------------------ function cw_itool_gvl, id stash = widget_info( id, /CHILD ) widget_control, stash, get_uvalue=state, /NO_COPY widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY lasttype = im_parms.lasttype lastpos = im_parms.lastpos object = im_parms.object lastmag = im_parms.lastmag lastfwhm = im_parms.lastfwhm widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY widget_control, state.phparmsbase, get_uvalue=ph_parms, /NO_COPY phedit = ph_parms.edtflg widget_control, state.phparmsbase, set_uvalue=ph_parms, /NO_COPY tpmgrid = widget_info( state.tpmgrbase, /CHILD ) if tpmgrid ne 0L then begin widget_control, tpmgrid, get_value=tp_list nplates = N_ELEMENTS( tp_list ) endif else begin nplates = 0 endelse modified = 0B if nplates gt 0 then begin for j=0, nplates-1 do begin if tp_list[j].tlbid ne 0L then begin widget_control, tp_list[j].tpid, get_value=tplate modified = modified or tplate.modified endif endfor endif msg = [''] if phedit then begin msg = [ msg, $ 'Itool PHOTOMETRY parameter changes have not been saved.' ] endif if modified then begin msg = [ msg, $ 'Itool TEMPLATE changes have not been saved.' ] endif flag = phedit or modified widget_control, stash, set_uvalue=state, /NO_COPY return, {flag:flag, msg:msg, lasttype:lasttype, lastpos:lastpos, $ object:object, lastfwhm:lastfwhm, lastmag:lastmag} end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_svl ; The 'set value' procedure for cw_itool. ; ------------------------------------------------------------------------------ pro cw_itool_svl, id, im_parms stash = widget_info( id, /CHILD ) widget_control, stash, get_uvalue=state, /NO_COPY cw_itool_cstr, im_parms, 0 if not im_parms.autophot then im_parms.lasttype=0 ;Put the new image parameters into the holding area. widget_control, state.imparmsbase, set_uvalue=im_parms cw_itool_disp, state cw_itool_draw, state, /FULL, /ZOOM, /WorK widget_control, state.phparmsbase, get_uvalue=ph_parms, /NO_COPY ph_parms.objnum = 0 widget_control, state.phparmsbase, set_uvalue=ph_parms, /NO_COPY if state.scroll then begin widget_control, state.work_view, get_uvalue=workstate, /NO_COPY xoff = max( [0, (im_parms.xsize-workstate.xvisible)/2 ] ) yoff = max( [0, (im_parms.ysize-workstate.yvisible)/2 ] ) widget_control, state.work_view, SET_DRAW_VIEW=[xoff, yoff] widget_control, state.work_view, set_uvalue=workstate, /NO_COPY endif if im_parms.autophot then begin widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY if im_parms.lasttype eq 1 then begin cw_itool_oneph, draw_state, im_parms.lastpos[0], im_parms.lastpos[1] endif else if im_parms.lasttype eq 2 then begin cw_itool_phact, draw_state, im_parms.lastpos[0], im_parms.lastpos[1] endif widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY endif widget_control, stash, set_uvalue=state, /NO_COPY end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_phact ; Action routine for Template Photometry. ; ------------------------------------------------------------------------------ pro cw_itool_phact, draw_state, x, y bel = string(7B) ;Get id of the Template Manager. tpmgrid = widget_info( draw_state.tpmgrbase, /CHILD ) ;Retrieve the 'value' of the template manager, which is the template list ;array. if tpmgrid ne 0L then begin widget_control, tpmgrid, get_value=tp_list selected = where( tp_list[*].selected eq 1B, count ) endif else begin count = 0 endelse if count eq 1 then begin ;Template is selected. widget_control, tp_list[selected].tpid, get_value=tplate endif else begin ;Template not selected. message, 'Error. Template must be selected.'+bel, /INFO return endelse case tplate.mode of 0 : begin ;Add mode. if tplate.numobj eq 0 then begin ;This is the first (anchor) position. tplate.new[0] = 1B tplate.x[0] = x tplate.y[0] = y tplate.numobj = 1 endif else begin ;This is a position to be added. numobj = tplate.numobj + 1 mode = tplate.mode modified = tplate.modified new = [tplate.new, 1B] objnam = [tplate.objnam, '' ] nx = [tplate.x, x] ny = [tplate.y, y] tplate = {numobj:numobj, mode:mode, modified:modified, new:new, $ objnam:objnam, x:nx, y:ny} endelse tplate.modified = 1B widget_control, tp_list[selected].tpid, set_value=tplate cw_itool_trk, draw_state, x, y widget_control,draw_state.imparmsbase,get_uvalue=im_parms,/NO_COPY im_parms.lasttype=0 widget_control,draw_state.imparmsbase,set_uvalue=im_parms,/NO_COPY end 1 : begin ;Left-button photometry mode. if tplate.numobj eq 0 then begin message, 'Error. No objects in this template.'+string(7B), /INFO return endif ;The values of x and y are assumed to be the new anchor coordinates. if tplate.new[0] eq 1B then begin xguess = tplate.x yguess = tplate.y endif else begin dx = x - tplate.x[0] dy = y - tplate.y[0] xguess = tplate.x yguess = tplate.y w = where( tplate.new eq 0B, count ) if count gt 0 then begin xguess[w] = xguess[w] + dx[w] yguess[w] = yguess[w] + dy[w] endif endelse ;Offset of mouse position from last known position. axoff = xguess[0]-tplate.x[0] ayoff = yguess[0]-tplate.y[0] ;Check if first position is within tolerance of the anchor. if (abs(axoff) gt 20) or (abs(ayoff) gt 20) then begin t = [ $ ' The location of the first object, as supplied by the left mouse', $ 'button, is more than twenty pixels away from its last known', $ 'location.', $ ' The template could become corrupted if this starting location', $ 'is used.', $ ' The requested starting location, last known location, and', $ 'differences are shown below:', $ ' ', $ '------ Requested (x,y) ----- Last known (x,y) ---- differences', $ ' (' + string( x, format='(F10.3)' ) + ',' + $ string( y, format='(F8.3)' ) + ')' + $ ' (' + string( tplate.x[0], format='(F10.3)' ) + ',' + $ string( tplate.y[0], format='(F8.3)') + ')' + $ ' (' + string( x-tplate.x[0], format='(F10.3)' ) + ',' + $ string( y-tplate.y[0], format='(F8.3)' ) + ')' ] con = qannounc( t, TITLE='First Object Location Status', $ FALSE='Cancel this request', TRUE='Ok, start photometry', $ XSIZE=80, YSIZE=12 ) if not con then return endif tpn = tplate.objnam widget_control, draw_state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, draw_state.phparmsbase, get_uvalue=ph_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY ;Check for header substitution of object name. w = where( STRUPcase(tpn) eq '', count ) if count ne 0 then tpn[w]=im_parms.object objnum = ph_parms.objnum basphote, ph_parms.gain, image, $ im_parms.exptime, xguess, yguess, ph_parms.radius, $ ph_parms.sky1, ph_parms.sky2, ph_parms.logfile, objnum, $ AIRMASS=im_parms.airmass, /AltLOG, BOXMRAD=ph_parms.boxmrad, $ EXACT=ph_parms.exact, FWHM=fwhm, MAG=mag, NAME=tpn, $ NOMEXT=ph_parms.nomext, FIltER=im_parms.filter, $ FNAME=im_parms.imfile, JD=im_parms.jd, DT=im_parms.expdelta, $ ONCHIP=onchip, PSCALE=ph_parms.pscale, $ XCEN=xcen, YCEN=ycen, ZPOINT=ph_parms.zpoint ph_parms.objnum = objnum im_parms.lasttype=2 im_parms.lastpos=[fix(xcen[0]+0.5),fix(ycen[0]+0.5)] im_parms.lastmag=mag[0] im_parms.lastfwhm=fwhm[0] widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, draw_state.imparmsbase, set_uvalue=im_parms, /NO_COPY widget_control, draw_state.phparmsbase, set_uvalue=ph_parms, /NO_COPY ;Re-draw the zoom window at the new center. cw_itool_draw, draw_state, /ZOOM, ZXCEN=xcen[0], ZYCEN=ycen[0] cw_itool_trk, draw_state, xcen[0], ycen[0] ;Draw photometry aperture. cw_itool_apdraw, draw_state ;Locate the objects found by Basphote that are not new. found = where( (onchip eq 1B) and (tplate.new eq 0B), count ) ;Locate the objects not found (off chip). lost = where( onchip eq 0B, lostcount ) if count gt 3 then begin ;Compute the difference vectors to be used for the stats.. dx = xcen[found] - xguess[found] dy = ycen[found] - yguess[found] sigmadx = STDEV( dx[1 : count-1], meandx ) sigmady = STDEV( dy[1 : count-1], meandy ) endif else begin ;Too few positions to obtain stats. meandx = 0 meandy = 0 sigmadx = 0 sigmady = 0 endelse print, 'Template sigmas: ', sigmadx, sigmady if lostcount gt 0 then begin ;Fix the positions of the lost object(s} by adjusting the last known ;position(s). xcen[lost] = xguess[lost] + meandx ycen[lost] = yguess[lost] + meandy endif ;Old position. oldx = tplate.x[1:tplate.numobj-1] oldy = tplate.y[1:tplate.numobj-1] ;New position. newx = xcen[1:tplate.numobj-1] newy = ycen[1:tplate.numobj-1] ;Differencees. dx = newx - oldx dy = newy - oldy ;Make a sequence string vector. seqnum = string( indgen(tplate.numobj), format='(I2)' ) seqnum = seqnum[ 1:tplate.numobj-1 ] newpos = where( tplate.new eq 1B, newcount ) ;Make a flags string vector. flags = replicate( ' ', tplate.numobj ) if lostcount gt 0 then flags[lost]='*' if newcount gt 0 then flags[newpos]='+' flags = flags[ 1:tplate.numobj-1 ] ; Define a threshold value for the computed sigmas. sigmathresh = 0.5 ; Test for sigmas greater than this threshold. if sigmadx gt sigmathresh or sigmady gt sigmathresh then begin t = [ $ ' The positions of objects in the active template have changed,', $ 'relative to each other, by an amount which may be too large.', $ 'Template corruption is possible.', $ ' Please review the following table of positions and decide', $ 'whether to accept or ignore the new positions.', $ ' The table lists the last known locations, the new locations,', $ 'and their differences.', $ ' ', $ ' ------ Last known (x,y) ----- New (x,y) --------- differences', $ ' (' + string( tplate.x[0], format='(F10.3)' ) + ',' + $ string( tplate.y[0], format='(F8.3)' ) + ')' + $ ' (' + string( xcen[0], format='(F10.3)' ) + ',' + $ string( ycen[0], format='(F8.3)' ) + ')' + $ ' (' + string( xcen[0]-tplate.x[0], format='(F10.3)' ) + ',' + $ string( ycen[0]-tplate.y[0], format='(F8.3)' ) + $ ') (anchor)', $ ' ', $ seqnum + ' ' + $ ' (' + string( oldx, format='(F10.3)' ) + ',' + $ string( oldy, format='(F8.3)' ) + ')' + $ ' (' + string( newx, format='(F10.3)' ) + ',' + $ string( newy, format='(F8.3)' ) + ')' + $ ' (' + string( dx, format='(F10.3)' ) + ',' + $ string( dy, format='(F8.3)' ) + ') ' + flags, $ ' ', $ ' Legend: * offchip, + new object' ] con = qannounc( t, TITLE='Template Object Verification', $ FALSE='Ignore, avoid template corruption', $ TRUE='Accept new object locations', $ XSIZE=90, ysize=16 ) if not con then begin widget_control,draw_state.imparmsbase,get_uvalue=im_parms,/NO_COPY im_parms.lasttype=0 widget_control,draw_state.imparmsbase,set_uvalue=im_parms,/NO_COPY return endif endif ;Update the template to the new positions. csz = size(xcen) if csz[0] ne 2 then begin tplate.x = xcen tplate.y = ycen endif else begin tplate.x = xcen[*,csz[2]-1] tplate.y = ycen[*,csz[2]-1] endelse tplate.modified = 1B tplate.new = 0B widget_control, tp_list[selected].tpid, set_value=tplate end endcase end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_oneph ; Do single object photometry with display update. ; ------------------------------------------------------------------------------ pro cw_itool_oneph, draw_state, x, y widget_control, draw_state.imparmsbase, get_uvalue=im_parms, $ /NO_COPY widget_control, draw_state.phparmsbase, get_uvalue=ph_parms, $ /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY objnum = ph_parms.objnum basphote, ph_parms.gain, image, $ im_parms.exptime, x, y, ph_parms.radius, $ ph_parms.sky1, ph_parms.sky2, ph_parms.logfile, objnum, $ AIRMASS=im_parms.airmass, /AltLOG, BOXMRAD=ph_parms.boxmrad, $ EXACT=ph_parms.exact, FWHM=fwhm, MAG=mag, NAME=im_parms.object, $ NOMEXT=ph_parms.nomext, FIltER=im_parms.filter, $ FNAME=im_parms.imfile, JD=im_parms.jd, DT=im_parms.expdelta, $ PSCALE=ph_parms.pscale, $ XCEN=xcen, YCEN=ycen, ZPOINT=ph_parms.zpoint ph_parms.objnum = objnum im_parms.lasttype=1 im_parms.lastpos=[fix(xcen[0]+0.5),fix(ycen[0]+0.5)] im_parms.lastmag=mag[0] im_parms.lastfwhm=fwhm[0] widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, draw_state.imparmsbase, set_uvalue=im_parms, $ /NO_COPY widget_control, draw_state.phparmsbase, set_uvalue=ph_parms, $ /NO_COPY ;Re-draw the zoom window at the new center. cw_itool_draw, draw_state, /ZOOM, ZXCEN=xcen[0], ZYCEN=ycen[0] ;Update the cursor tracking widgets. cw_itool_trk, draw_state, xcen[0], ycen[0] ;Draw photometry aperture. cw_itool_apdraw, draw_state end ; ------------------------------------------------------------------------------ ; Function cw_draw_eve ; Draw event handler. ; ------------------------------------------------------------------------------ function cw_draw_eve, event widget_control, event.id, /HOURGLASS widget_control, event.handler, get_uvalue=draw_state, /NO_COPY bel = string(7B) out_event = 0 case event.id of draw_state.full_view : begin widget_control, event.id, get_uvalue=fullstate, /NO_COPY if fullstate.zfact ne 1.0 then begin x = fullstate.spx + ( event.x - fullstate.xoff ) / fullstate.zfact y = fullstate.spy + ( event.y - fullstate.yoff ) / fullstate.zfact endif else begin x = fullstate.spx + ( event.x - fullstate.xoff ) y = fullstate.spy + ( event.y - fullstate.yoff ) endelse if !order ne 0 then begin y = fullstate.ysize - 1 - y endif case event.press of 2 : begin if (draw_state.scroll) then begin widget_control, draw_state.work_view, get_uvalue=workstate, $ /NO_COPY xoff = x - workstate.xvisible / 2 yoff = y - workstate.yvisible / 2 if !order ne 0 then begin widget_control, draw_state.imparmsbase, get_uvalue=im_parms, $ /NO_COPY yoff = im_parms.ysize - ( y + workstate.yvisible / 2 ) widget_control, draw_state.imparmsbase, set_uvalue=im_parms, $ /NO_COPY endif if xoff lt 0 then xoff = 0 if yoff lt 0 then yoff = 0 widget_control, draw_state.work_view, SET_DRAW_VIEW=[xoff, yoff] widget_control, draw_state.work_view, set_uvalue=workstate, $ /NO_COPY endif end else : begin end endcase widget_control, event.id, set_uvalue=fullstate, /NO_COPY ;Don't want to do anything else after the full-view event. widget_control, event.handler, set_uvalue=draw_state, /NO_COPY return, 0 end draw_state.work_view : begin widget_control, event.id, get_uvalue=workstate, /NO_COPY if !order ne 0 then $ eventy = workstate.ysize-event.y-1 $ else $ eventy = event.y if workstate.zfact ne 1 then begin x = workstate.spx + ( event.x - workstate.xoff ) / workstate.zfact y = workstate.spy + ( eventy - workstate.yoff ) / workstate.zfact endif else begin x = workstate.spx + ( event.x - workstate.xoff ) y = workstate.spy + ( eventy - workstate.yoff ) endelse widget_control, event.id, set_uvalue=workstate, /NO_COPY end draw_state.zoom_view : begin widget_control, event.id, get_uvalue=zoomstate, /NO_COPY if !order ne 0 then $ eventy = zoomstate.ysize-event.y-1 $ else $ eventy = event.y if zoomstate.zfact ne 1 then begin x = zoomstate.spx + ( event.x - zoomstate.xoff ) / zoomstate.zfact y = zoomstate.spy + ( eventy - zoomstate.yoff ) / zoomstate.zfact endif else begin x = zoomstate.spx + ( event.x - zoomstate.xoff ) y = zoomstate.spy + ( eventy - zoomstate.yoff ) endelse widget_control, event.id, set_uvalue=zoomstate, /NO_COPY end else : begin ;This was an event from one of the Zoom+ or Zoom- buttons. Restore ;the image state and pass the event up to the next highest event ;handler (cw_itool_eve). widget_control, event.handler, set_uvalue=draw_state, /NO_COPY return, event end endcase ;Check for x,y out of array bounds. This is necessary, because the draw ;windows may be larger than requested. widget_control, draw_state.imparmsbase, get_uvalue=im_parms, /NO_COPY if x ge im_parms.xsize then x=im_parms.xsize-1 if y ge im_parms.ysize then y=im_parms.ysize-1 widget_control, draw_state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;At this point, x and y have been transformed to the actual image array ;coordinates (from the work or zoom draw window). case event.type of 0 : begin ;Mouse button pressed. case event.press of 1 : begin ;Left Button (template or comet photometry). widget_control, draw_state.tpmgrbase, get_uvalue=tpstatus widget_control, draw_state.cpmgrbase, get_uvalue=cpstatus if tpstatus.active eq 1B then begin ;Template photometry. cw_itool_phact, draw_state, x, y ; widget_control, draw_state.zoom_view, get_uvalue=zoomstate, $ ; /NO_COPY ; widget_control, draw_state.imparmsbase, get_uvalue=im_parms, $ ; /NO_COPY ; cw_itool_trk, draw_state, zoomstate.xcen, zoomstate.ycen ; im_parms.lasttype=2 ; im_parms.lastpos=[zoomstate.xcen,zoomstate.ycen] ; widget_control, draw_state.imparmsbase, set_uvalue=im_parms, $ ; /NO_COPY ; widget_control, draw_state.zoom_view, set_uvalue=zoomstate, $ ; /NO_COPY endif if cpstatus.active eq 1B then begin ;Comet photometry. cpmgrid = widget_info( draw_state.cpmgrbase, /CHILD ) ;Pass the x,y coordinates to thw Comet Photometry Manager. widget_control, cpmgrid, set_value={x:x, y:y} widget_control, draw_state.imparmsbase, get_uvalue=im_parms, $ /NO_COPY im_parms.lasttype=0 widget_control, draw_state.imparmsbase, set_uvalue=im_parms, $ /NO_COPY endif end 2 : begin ;Middle button (zoom at new center). cw_itool_draw, draw_state, /ZOOM, ZXCEN=x, ZYCEN=y widget_control, draw_state.zoom_view, get_uvalue=zoomstate, $ /NO_COPY cw_itool_trk, draw_state, zoomstate.xcen, zoomstate.ycen widget_control, draw_state.zoom_view, set_uvalue=zoomstate, $ /NO_COPY end 4 : begin ;Right button (single object photometry). cw_itool_oneph,draw_state,x,y end else : begin end endcase end 2 : begin ;Motion event. if draw_state.trkflg then begin ;Refresh the cursor tracking widgets. cw_itool_trk, draw_state, x, y endif if event.press eq 2 then begin ;Re-draw the zoom window at the new center. cw_itool_draw, draw_state, /ZOOM, ZXCEN=x, ZYCEN=y endif end else : begin end endcase widget_control, event.handler, set_uvalue=draw_state, /NO_COPY return, out_event end ; ------------------------------------------------------------------------------ ; Procedure cw_itool_tpeve ; ; This is the external event handler for cw_tmpgr. It is designed to ; support events from a compound widget which 'hangs' on a Top Level Base. ; ------------------------------------------------------------------------------ pro cw_itool_tpeve, event print,'tpeve event' widget_control, event.top, get_uvalue=topstate widget_control, topstate.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /work widget_control, topstate.drawbase, set_uvalue=draw_state, /NO_COPY end ; ------------------------------------------------------------------------------ ; Procedure cw_pixed_exteve ; ; This is the external event handler for cw_pixed. It is designed to ; support events from a compound widget which 'hangs' on a Top Level Base. ; The method used differs from the usual in that the 'state' structure ; is stored in the user-value of the TLB instead of in the first child ; base. ; ------------------------------------------------------------------------------ pro cw_pixed_exteve, event ;The structure contained in the TLB user-value is: ; {imparmsbase:0L, work_view:0L, zoom_view:0L} ;These tags are copies of pointers within cw_itool. These allow access ;to data which are needed to update the work and zoom draw windows with ;the modified pixel values. widget_control, event.top, get_uvalue=topstate, /NO_COPY widget_control, topstate.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY widget_control, topstate.work_view, get_uvalue=workstate, /NO_COPY widget_control, topstate.work_view, get_value=work_win widget_control, topstate.zoom_view, get_uvalue=zoomstate, /NO_COPY widget_control, topstate.zoom_view, get_value=zoom_win curmin = im_parms.curmin[im_parms.frame] curmax = im_parms.curmax[im_parms.frame] case event.type of 1 : begin for j=0, event.count-1 do begin image[ event.x[j], event.y[j], im_parms.frame ] = event.value[j] t = rebin([event.value[j]], zoomstate.zfact, zoomstate.zfact, /SAMPLE) t = bytscl( t, min=curmin, max=curmax, TOP=state.ncolors-1 ) dx = event.x[j] - zoomstate.spx dy = event.y[j] - zoomstate.spy wset, zoom_win tv, t, zoomstate.xoff+dx*zoomstate.zfact, $ zoomstate.yoff+dy*zoomstate.zfact t = rebin([event.value[j]], workstate.zfact, workstate.zfact, /SAMPLE) t = bytscl( t, min=curmin, max=curmax, TOP=state.ncolors-1 ) dx = event.x[j] * workstate.zfact dy = event.y[j] * workstate.zfact wset, work_win tv, t, dx, dy endfor end else : begin message, 'Unknown event:', /INFO HELP, event, /STRUCTURE end endcase widget_control, topstate.zoom_view, set_uvalue=zoomstate, /NO_COPY widget_control, topstate.work_view, set_uvalue=workstate, /NO_COPY widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, topstate.imparmsbase, set_uvalue=im_parms, /NO_COPY widget_control, event.top, set_uvalue=topstate, /NO_COPY end ; ------------------------------------------------------------------------------ ; Function cw_itool_eve ; Event handler for cw_itool main procedure. ; ------------------------------------------------------------------------------ function cw_itool_eve, event widget_control, event.id, /HOURGLASS bel = string( 7B ) out_event = 0 stash = widget_info( event.handler, /CHILD ) widget_control, stash, get_uvalue=state, /NO_COPY case event.id of state.animateid : begin ;Start animation procedure. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY imfile = im_parms.imfile nframes = im_parms.nframes xsize = im_parms.xsize ysize = im_parms.ysize widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY widget_control, state.work_view, get_uvalue=workstate, /NO_COPY xs = workstate.zfact * xsize ys = workstate.zfact * ysize widget_control, state.work_view, set_uvalue=workstate, /NO_COPY title = 'Itool Animation' if imfile ne '' then title = title + ' - image file ' + imfile xinteranimate, GROUP=event.top, SET=[xs, ys, nframes], /SHOWLOAD, $ TITLE=title for j=0, nframes-1 do begin widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY if im_parms.asis[j] eq 0 then cw_itool_cstr, im_parms, j, /SILENT widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY xinteranimate, FRAME=j, GROUP=event.top, IMAge=$ bytscl(rebin(image[*,*,j], xs, ys, /SAMPLE), $ min=im_parms.curmin[j], max=im_parms.curmax[j], $ TOP=state.ncolors-1 ) widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY endfor xinteranimate, 50, GROUP=event.top end state.auto1id : begin ;Set display stretch to computed values (current frame). widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY frame = im_parms.frame cw_itool_cstr, im_parms, frame, /SILENT im_parms.asis[frame] = 0B im_parms.curmin[frame] = im_parms.sclmin[frame] im_parms.curmax[frame] = im_parms.sclmax[frame] widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all of the widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.auto2id : begin ;Set display stretch to computed values (all frames). widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY for frame=0, im_parms.nframes-1 do begin cw_itool_cstr, im_parms, frame, /SILENT im_parms.asis[frame] = 0B im_parms.curmin[frame] = im_parms.sclmin[frame] im_parms.curmax[frame] = im_parms.sclmax[frame] endfor widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.colpalid : begin xpalette, GROUP=event.top end state.coltabid : begin xloadct, GROUP=event.top end state.cpmgrid : begin widget_control, state.tpmgrbase, get_uvalue=tpstatus if tpstatus.active eq 0B then begin ;All clear to start. ;Set the active flag. widget_control, state.cpmgrbase, get_uvalue=status, /NO_COPY status.active = 1B widget_control, state.cpmgrbase, set_uvalue=status, /NO_COPY ;Get image pointer. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY imageptr = im_parms.imageptr widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY if not widget_info( state.cpmgrbase, /REALIZED ) then begin w1 = cw_cpmgr( state.cpmgrbase, IMAgePTR=imageptr, $ IMPARMSPTR=state.imparmsbase, $ PHPARMSPTR=state.phparmsbase ) widget_control, state.cpmgrbase, /REALIZE endif widget_control, state.cpmgrbase, MAP=1 endif else begin message, 'Error. Template Photometry is active.' + bel, /INFO endelse end state.disp2id : begin ;Copy display stretch to all frames. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY frame = im_parms.frame for j=0, im_parms.nframes-1 do begin im_parms.curmin[j] = im_parms.curmin[frame] im_parms.curmax[j] = im_parms.curmax[frame] im_parms.asis[j] = 1B endfor widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.dispmaxid : begin widget_control, event.id, get_value=value widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY im_parms.curmax[im_parms.frame] = value[0] im_parms.asis[im_parms.frame] = 1B widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.dispminid : begin widget_control, event.id, get_value=value widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY im_parms.curmin[im_parms.frame] = value[0] im_parms.asis[im_parms.frame] = 1B widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.dismissid : begin widget_control, event.top, MAP=0 end state.extrema1id : begin ;Set display stretch to image extrema (current frame). widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY j = im_parms.frame im_parms.curmin[j] = im_parms.minvalue[j] im_parms.curmax[j] = im_parms.maxvalue[j] im_parms.asis[j] = 1B widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.extrema2id : begin ;Set display stretch to image extrema (all frames). widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY for j=0, im_parms.nframes-1 do begin cw_itool_cstr, im_parms, j, /SILENT im_parms.curmin[j] = im_parms.minvalue[j] im_parms.curmax[j] = im_parms.maxvalue[j] im_parms.asis[j] = 1B endfor widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.frameid : begin widget_control, event.id, get_value=value ;Requested frame. frame = long( value[0] ) ;Get total number of frames. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY nframes = im_parms.nframes widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY if ( frame ge 0 ) and ( frame le nframes-1 ) then begin ;The requested frame is legal. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY im_parms.frame = frame widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY endif else begin ;The requested frame is bunk. Put the current frame number back ;into the text widget. widget_control, state.frameid, set_value=string( im_parms.frame, $ format=state.fmti ) endelse end state.hdcpyid : begin ; Make a hard copy of the current image. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY frame = im_parms.frame title = im_parms.object + ' ' + im_parms.imfile + ' ' + im_parms.ut hardim, image[*,*,frame], im_parms.curmin[frame], $ im_parms.curmax[frame], TITLE=title, WIDTH=18, AUTOSIZE=1, /negative widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY end state.imparmsid : begin if widget_info( state.ipmgrid, /VALID_ID ) eq 0 then begin ;The image parameters widget is inactive. state.ipmgrid = cw_ipmgr( state.imparmsbase ) widget_control, state.imparmsbase, /REALIZE, /MAP endif end state.nextframeid : begin widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY im_parms.frame = (im_parms.frame+1) MOD im_parms.nframes widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Refresh all widgets. cw_itool_disp, state widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /FULL, /ZOOM, /WORK widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.pfilesid : begin ;Retrive some structures. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY widget_control, state.phparmsbase, get_uvalue=ph_parms, /NO_COPY widget_control, state.zoom_view, get_uvalue=zoomstate, /NO_COPY ;Get the set-point and size of the zoom-window piece of the image. xs = zoomstate.spx ys = zoomstate.spy dx = zoomstate.dx dy = zoomstate.dy ;Piece together the title for the TLB. title = '' if (im_parms.object ne '') then title = im_parms.object if (im_parms.imfile ne '') then title = title +' '+ im_parms.imfile if(im_parms.ut ne '') then title = title + ' ' + im_parms.ut ;Extract the zoomed piece. array = image[xs:xs+dx-1, ys:ys+dy-1, im_parms.frame] ;Get the Plate Scale. pscale = ph_parms.pscale ;Restore the structures. widget_control, state.zoom_view, set_uvalue=zoomstate, /NO_COPY widget_control, state.phparmsbase, set_uvalue=ph_parms, /NO_COPY widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY ;Get the list of TLB instances. widget_control, state.pfilesid, get_uvalue=instances ;Check to see if any of the existing slots have a profiles widget ;active (valid TLB). active = widget_info( instances, /VALID_ID ) f = where( active eq 0L, count ) if count ne 0 then begin ;At least one of the slots is available for use. Take the ;first available. base = widget_base( TITLE='Itool Profiles ' + title ) xmanager, '', base, GROUP_LEADER=state.mainbase, /JUST_REG instances[f] = base endif else begin ;All of the slots are currently active. Add a new slot. base = widget_base( TITLE='Itool Profiles ' + title ) xmanager, '', base, GROUP_LEADER=state.mainbase, /JUST_REG instances = [ instances, base ] endelse ;Put the instances vector back into the user-value of the holding base. widget_control, state.pfilesid, set_uvalue=instances pfbase = cw_pfile( base, PLATESCALE=pscale, HCTITLE=title ) widget_control, base, /REALIZE, /MAP ;Use the set_value call to display the profile. widget_control, pfbase, set_value={image:array, xset:xs, yset:ys} end state.phparmsid : begin child = widget_info( state.phparmsbase, /CHILD ) if child eq 0L then begin ;The photometry parameters widget is inactive. state.ppmgrid = cw_ppmgr( state.phparmsbase ) widget_control, state.phparmsbase, /REALIZE, /MAP endif end state.pixedid : begin child = widget_info( state.pixedbase, /CHILD ) if child eq 0L then begin ;Pixel editor is not active. Invoke it. widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY widget_control, state.zoom_view, get_uvalue=zoomstate, /NO_COPY state.pixedevid = cw_pixed( state.pixedbase, image, $ zoomstate.xcen, zoomstate.ycen ) widget_control, state.pixedbase, /REALIZE, /MAP widget_control, state.zoom_view, set_uvalue=zoomstate, /NO_COPY widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY endif end state.ptraceid : begin widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY widget_control, draw_state.phparmsbase, get_uvalue=ph_parms, /NO_COPY widget_control, state.imparmsbase, get_uvalue=im_parms, /NO_COPY widget_control, draw_state.zoom_view, get_uvalue=zoomstate, /NO_COPY widget_control, im_parms.imageptr, get_uvalue=image, /NO_COPY x = zoomstate.xcen y = zoomstate.ycen d_name = !d.name portrait !p.multi=[0,2,3] portrait ; mag, snr vs. objrad r1 = 2 r2 = ph_parms.sky1 dr = 1 npts = fix((r2-r1)/dr) r = findgen(npts)/dr+r1 sky1 = ph_parms.sky1 sky2 = ph_parms.sky2 basphote,ph_parms.gain,image,im_parms.exptime,x,y,r,sky1,sky2, $ boxmrad=ph_parms.boxmrad,/nolog,/silent, $ err=magerr,fwhm=fwhm,mag=mag,skymean=skymean,skyerr=skyerr plot,r,magerr,psym=8, $ xtitle='Object aperture radius',ytitle='Mag Uncertainty', $ title=im_parms.imfile+' '+im_parms.object+' '+im_parms.filter ploterror,r,mag,magerr,psym=8,yr=maxmin([mag+magerr,mag-magerr]), $ xtitle='Object aperture radius',ytitle='Instrumental Magnitude', $ title=im_parms.imfile+' sky1,sky2='+strn(sky1)+','+strn(sky2) ; sky,mag vs. sky1 r1 = ph_parms.radius r2 = ph_parms.sky2-5 dr = 1 npts = fix((r2-r1)/dr) r = findgen(npts)/dr+r1 objrad = ph_parms.radius sky2 = ph_parms.sky2 basphote,ph_parms.gain,image,im_parms.exptime,x,y,objrad,r,sky2, $ boxmrad=ph_parms.boxmrad,/nolog,/silent, $ err=magerr,fwhm=fwhm,mag=mag,skymean=skymean,skyerr=skyerr ploterror,r,skymean,skyerr,psym=8, $ xtitle='Inner sky radius',ytitle='Sky signal (counts/pixel)', $ title=im_parms.imfile+' '+strn(im_parms.exptime,format='(f10.1)')+ $ 'sec (x,y)='+strn(x)+','+strn(y) ploterror,r,mag,magerr,psym=8,yr=maxmin([mag+magerr,mag-magerr]), $ xtitle='Inner sky radius',ytitle='Instrumental Magnitude', $ title=im_parms.imfile+' objrad='+strn(objrad)+' sky2='+strn(sky2) ; list of stuff in im_parms is in it_init.pro ; sky,mag vs. sky2 r1 = ph_parms.sky1+5 r2 = ph_parms.sky2 dr = 1 npts = fix((r2-r1)/dr) r = findgen(npts)/dr+r1 objrad = ph_parms.radius sky1 = ph_parms.sky1 basphote,ph_parms.gain,image,im_parms.exptime,x,y,objrad,sky1,r, $ boxmrad=ph_parms.boxmrad,/nolog,/silent, $ err=magerr,fwhm=fwhm,mag=mag,skymean=skymean,skyerr=skyerr jdstr,im_parms.jd,0,str ploterror,r,skymean,skyerr,psym=8, $ xtitle='Outer sky radius',ytitle='Sky signal (counts/pixel)', $ title=im_parms.imfile+' '+str ploterror,r,mag,magerr,psym=8,yr=maxmin([mag+magerr,mag-magerr]), $ xtitle='Outer sky radius',ytitle='Instrumental Magnitude', $ title=im_parms.imfile+' objrad='+strn(objrad)+' sky1='+strn(sky1) hardcopy !p.multi=0 set_plot,d_name widget_control, im_parms.imageptr, set_uvalue=image, /NO_COPY widget_control, draw_state.zoom_view, set_uvalue=zoomstate, /NO_COPY widget_control, state.imparmsbase, set_uvalue=im_parms, /NO_COPY widget_control, draw_state.phparmsbase, set_uvalue=ph_parms, /NO_COPY widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.tmplmgrid : begin widget_control, state.cpmgrbase, get_uvalue=cpstatus if cpstatus.active eq 0B then begin ;All clear to start. Set the active flag. widget_control, state.tpmgrbase, get_uvalue=status, /NO_COPY status.active = 1B widget_control, state.tpmgrbase, set_uvalue=status, /NO_COPY if not widget_info( state.tpmgrbase, /REALIZED ) then begin base = cw_tpmgr( state.tpmgrbase, TMPLFILE=state.tmplfile ) widget_control, state.tpmgrbase, /REALIZE endif widget_control, state.tpmgrbase, MAP=1 endif else begin message, 'Error. Comet Photometry is active.' + bel, /INFO endelse end state.trkid : begin widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY case event.value of 0 : draw_state.trkflg = 0 1 : draw_state.trkflg = 1 else : message, '(tracking) unknown event.nt.', /INFO endcase widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end state.zoomdnid : begin widget_control, state.zoom_view, get_uvalue=zoomstate if zoomstate.zfact gt 1 then begin zoomstate.zfact = zoomstate.zfact - 1 widget_control, state.zoom_view, set_uvalue=zoomstate newzoom = string( zoomstate.zfact, format='(I3)' ) widget_control, state.zoomvid, set_value=newzoom widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /ZOOM widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY endif end state.zoomupid : begin widget_control, state.zoom_view, get_uvalue=zoomstate zoomstate.zfact = zoomstate.zfact + 1 widget_control, state.zoom_view, set_uvalue=zoomstate newzoom = string( zoomstate.zfact, format='(I3)' ) widget_control, state.zoomvid, set_value=newzoom widget_control, state.drawbase, get_uvalue=draw_state, /NO_COPY cw_itool_draw, draw_state, /ZOOM widget_control, state.drawbase, set_uvalue=draw_state, /NO_COPY end else : begin message, 'Oops. Unknown event.nt.', /INFO HELP, event /STRUCTURE end endcase widget_control, stash, set_uvalue=state, /NO_COPY return, out_event end ; ------------------------------------------------------------------------------ ; Function cw_itool ; ------------------------------------------------------------------------------ function cw_itool, parent, FVISIBLE=fvisible, NODISMISS=nodismiss, $ PHOTPARMFILE=photparmfile, $ TMPLFILE=tmplfile, $ XSIZE=xsize, YSIZE=ysize, WXVISIBLE=wxvisible, WYVISIBLE=wyvisible, $ WZOOMFACT=wzoomfact, $ ZVISIBLE=zvisible if (!d.flags and 256) eq 0 then begin message, 'Error. No windowing device. cw_itool cannot be started.', /INFO return, 0L endif DEVICE,geT_SCREEN_SIZE=scrsize if scrsize[0] gt 1152 then begin xvisdef = 900 yvisdef = 640 endif else if scrsize[0] gt 1024 then begin xvisdef = 800 yvisdef = 550 endif else if scrsize[0] gt 768 then begin xvisdef = 500 yvisdef = 500 endif else begin xvisdef = 400 yvisdef = 400 endelse if (not keyword_set( xsize )) or (not KEYWorD_SET( ysize )) then begin message, 'Keywords XSIZE and YSIZE must be specified.', /INFO return, 0L endif if not keyword_set( fvisible ) then fvisible=128 if fvisible eq 0 then fvisible=128 if not keyword_set( wxvisible ) then wxvisible=xvisdef if wxvisible eq 0 then wxvisible=xvisdef if not keyword_set( wyvisible ) then wyvisible=yvisdef if wyvisible eq 0 then wyvisible=yvisdef if not keyword_set( zvisible ) then zvisible=128 if zvisible eq 0 then zvisible=128 if !d.n_colors le 256 then begin ncolors=!d.n_colors eightbit = 1 endif else begin ncolors=256 eightbit = 0 endelse ; Initialize the main-state control structure. state = { $ ncolors: ncolors, $ ; Number of colors for display eightbit: eightbit, $ ; Flag, if true, 8-bit display fmtg:'(G12.6)', $ ; Image info format. fmti:'(I12)', $ ; Image info format. font:'8x13', $ ; Font for some label and text widgets. savplt:!p, $ ; Save area for plotting environment. scroll:0B, $ tempedit:0, $ ; Template edit flag. tmplfile:'', $ ; Name of template manager file. animateid:0L, $ ; Animate button id. auto1id:0L, auto2id:0L, $ ; Stretch control menu button id. colpalid:0L, coltabid:0L, $ cpmgrbase:0L, $ cpmgrid:0L, $ debugid:0L, $ disp2id:0L, $ ; Stretch control menu button id. dispmaxid:0L, $ ; Widget id's for stretch min and max. dispminid:0L, $ drawbase:0L, $ dismissid:0L, $ extrema1id:0L, $ extrema2id:0L, $ frameid:0L, $ ; Frame number widget id. full_view:0L, $ hdcpyid:0L, $ imageminid:0L, imagemaxid:0L, $ imfileid:0L, $ ; Image file name widget id. imparmsbase:0L, $ imparmsid:0L, $ ipmgrid:0L, $ nextframeid:0L, $ ; ID of NextFrame button. nframesid:0L, $ objectid:0L, $ ; Object label widget id. filterid:0L, $ ; Filter label widget id. airmasid:0L, $ ; Airmass label widget id. exptimid:0L, $ ; Exposure time label widget id. utdateid:0L, $ ; UT Date label widget id. uttimeid:0L, $ ; UT Time label widget id. parent:parent, $ pfilesid:0L, $ phparmsbase:0L, $ phparmsid:0L, $ pixedbase:0L, $ ; Pixel Editor TLB. pixedevid:0L, $ pixedid:0L, $ ppmgrid:0L, $ ptraceid: 0L, $ tpmgrbase:0L, $ tmplmgrid:0L, $ trkid:0L, $ workbase:0L, $ work_view:0L, $ zoomupid:0L, $ zoomdnid:0L, $ zoomvid:0L, $ zoom_view:0L, $ mainbase:0L} ; Itool base id. ;Initialize the draw state structure. draw_state = { $ cpmgrbase:0L, $ curposid:0L, $ eightbit: eightbit, $ full_view:0L, $ imparmsbase:0L, $ mainstash:0L, $ ncolors: ncolors, $ pfilesid:0L, $ phparmsbase:0L, $ scroll:0B, $ tpmgrbase:0L, $ trkflg:0B, $ work_view:0L, $ zoom_view:0L } ; Initialize the photometry parameters structure. ph_parms = { $ boxmrad:10.0, $ edtflg:0B, $ exact:0, $ gain:1.0, $ logfile:'phot.log', $ nomext:0.0, $ objnum:0, $ parmfile:'', $ parmfilever:'phot_parms_v01', $ pscale:0.726, $ radius:5.0, $ sky1:10.0, $ sky2:50.0,$ zpoint:0.0 } ; ***************************************************************************** if keyword_set( photparmfile ) then ph_parms.parmfile=photparmfile if keyword_set( tmplfile ) then state.tmplfile=tmplfile ; Create the main base. ; if keyword_set( in_uvalue ) then begin mainbase = widget_base( parent, COLUMN=1, EVENT_FUNC='cw_itool_eve', $ FUNC_get_value='cw_itool_gvl', pro_set_value='cw_itool_svl', $ UVALUE=in_uvalue ) endif else begin mainbase = widget_base( parent, COLUMN=1, EVENT_FUNC='cw_itool_eve', $ FUNC_get_value='cw_itool_gvl', pro_set_value='cw_itool_svl' ) endelse state.mainbase = mainbase ;Define the top-level bases for itool applications. state.imparmsbase = widget_base( TITLE='Itool Image Parameters', $ GROUP_LEADER=parent ) xmanager, '', state.imparmsbase, /JUST_REG draw_state.imparmsbase = state.imparmsbase state.phparmsbase = widget_base( TITLE='Itool Photometry Parameters', $ GROUP_LEADER=parent ) xmanager, '', state.phparmsbase, /JUST_REG draw_state.phparmsbase = state.phparmsbase state.cpmgrbase = widget_base( TITLE='Itool Comet Photometry Manager', $ GROUP_LEADER=parent, UVALUE={active:0B} ) xmanager, '', state.cpmgrbase, /JUST_REG draw_state.cpmgrbase = state.cpmgrbase state.tpmgrbase = widget_base( TITLE='Itool Photometry Template Manager', $ GROUP_LEADER=parent, UVALUE={active:0B} ) xmanager, '', state.tpmgrbase, event_handler='cw_itool_tpeve', $ group_leader=mainbase, /JUST_REG draw_state.tpmgrbase = state.tpmgrbase ;This is the Top Level Base for the Pixel Editor. Events arriving from the ;Pixel Editor compound widget are routed to the handler associated with this ;base. These events have an integer field called 'type.' A value of 0 is ;returned if the Exit button was pressed. A value of 1 means update the ;pixel value at specified location. state.pixedbase = widget_base( TITLE='Itool Zoom-Window Pixel Editor' ) xmanager, '', state.pixedbase, EVENT_HandLER='cw_pixed_exteve', $ GROUP_LEADER=mainbase, /JUST_REG ; Main button section. mbbase = widget_base( mainbase, COLUMN=5 ) ; --------------------- state.phparmsid = widget_button( mbbase, VALUE='Photometry Params' ) state.cpmgrid = widget_button( mbbase, VALUE='Comet Phot Mgr' ) ; --------------------- state.imparmsid = widget_button( mbbase, VALUE='Image Params' ) state.tmplmgrid = widget_button( mbbase, VALUE='Template Mgr' ) ; --------------------- ;This base is the holding area for the Top Level Bases used to manage ;one, or more, copies of the Profiles widget. The TLB's are stored in ;a longword vector and placed in the user-value. state.pfilesid = widget_button( mbbase, VALUE='Profiles', UVALUE=[0L] ) draw_state.pfilesid = state.pfilesid state.pixedid = widget_button( mbbase, VALUE='Pixel Editor' ) ; --------------------- state.coltabid = widget_button( mbbase, VALUE='Color Table' ) state.colpalid = widget_button( mbbase, VALUE='Edit Palette' ) ; --------------------- state.hdcpyid = widget_button( mbbase, VALUE='Hard Copy' ) state.dismissid = widget_button( mbbase, VALUE='Dismiss' ) if keyword_set( nodismiss ) then begin widget_control, state.dismissid, SENSITIVE=0 endif ; --------------------- ;state.debugid = widget_button( mbbase, VALUE='Debug' ) ;Image stats section. maxvalue = string( 0.0, format=state.fmtg ) minvalue = string( 0.0, format=state.fmtg ) curmax = string( 0.0, format=state.fmtg ) curmin = string( 0.0, format=state.fmtg ) nframes = string( 0L, format=state.fmti ) framen = string( 0L, format=state.fmti ) imstatbase = widget_base( mainbase, ROW=1 ) wbc = widget_base( imstatbase, COLUMN=2, FRAME=1 ) ; --------------------- w1 = widget_label( wbc, VALUE='Image Max: ' ) w1 = widget_label( wbc, VALUE='Image Min: ' ) w1 = widget_label( wbc, VALUE='Total Frames:' ) ; --------------------- w1 = widget_label( wbc, VALUE=maxvalue ) state.imagemaxid = w1 w1 = widget_label( wbc, VALUE=minvalue ) state.imageminid = w1 w1 = widget_label( wbc, VALUE=nframes ) state.nframesid = w1 ; --------------------- wbc = widget_base( imstatbase, COLUMN=3, FRAME=1 ) w1 = widget_label( wbc, VALUE='Display Max: ' ) w1 = widget_label( wbc, VALUE='Display Min: ' ) w1 = widget_label( wbc, VALUE='Display Frame:' ) ; --------------------- state.dispmaxid = WIDgeT_TEXT( wbc, VALUE=curmax, /EDITABLE, XSIZE=12 ) state.dispminid = WIDgeT_TEXT( wbc, VALUE=curmin, /EDITABLE, XSIZE=12 ) state.frameid = WIDgeT_TEXT( wbc, VALUE=framen, /EDITABLE, XSIZE=12 ) widget_control, state.frameid, SENSITIVE=0 ; --------------------- ;Stretch control pull-down menu. wbr = wbc w1 = widget_button( wbr, VALUE='Stretch Menu', MENU=2 ) state.auto1id = widget_button( w1, $ VALUE='Set display stretch to computed values (current frame)' ) state.extrema1id = widget_button( w1, $ VALUE='Set display stretch to image extrema (current frame)' ) state.extrema2id = widget_button( w1, $ VALUE='Set display stretch to image extrema (all frames)' ) state.auto2id = widget_button( w1, $ VALUE='Set display stretch to computed values (all frames)' ) state.disp2id = widget_button( w1, VALUE='Copy display stretch to all frames' ) state.animateid = widget_button( wbr, VALUE='Animation' ) state.nextframeid = widget_button( wbr, VALUE='Next Frame' ) ; scan through all the items in this base and find the max x and y sizes. max_xs=0 max_ys=0 t_b = widget_info(wbc, /CHILD) ; gets first child while (t_b ne 0L) do begin geo = widget_info(t_b, /geOMETRY) max_xs=max([max_xs,geo.scr_xsize]) max_ys=max([max_ys,geo.scr_ysize]) t_b = widget_info(t_b, /SIBLING) ; gets next child (0=no more) endwhile t_b = widget_info(wbc, /CHILD) while (t_b ne 0L) do begin widget_control, t_b, SCR_XSIZE=max_xs, SCR_YSIZE=max_ys t_b = widget_info(t_b, /SIBLING) endwhile ; Cursor-tracking base. wb = widget_base( mainbase, /ROW, /FRAME ) w1 = widget_label( wb, VALUE='Cursor: ' ) state.trkid = CW_BGROUP( wb, ['Freeze','Track' ], /EXCLUSIVE, /NO_RELEASE, $ /ROW, set_value=draw_state.trkflg ) draw_state.curposid = widget_label( wb, VALUE='', /DYNAMIC_RESIZE ) ;The image state structure will be stored in this base. maindrawbase = widget_base( mainbase, EVENT_FUNC='cw_draw_eve', /ROW ) state.drawbase = maindrawbase ;Compute the full draw window parameters. fullstate = { name:'full', $ id:0L, $ dx:0, $ dy:0, $ eightbit: eightbit, $ ncolors: ncolors, $ spx:0, $ spy:0, $ xcen:0, $ ycen:0, $ xoff:0, $ yoff:0, $ xsize:xsize, $ ysize:ysize, $ xvisible:fvisible, $ yvisible:fvisible, $ zfact:1.0 } sf = max( [xsize/fvisible, ysize/fvisible] ) + 1 nx = xsize / sf ny = ysize / sf fullstate.dx = nx * sf fullstate.dy = ny * sf fullstate.zfact = 1.0 / sf fullstate.xoff = ( fvisible - nx ) / 2 fullstate.yoff = ( fvisible - ny ) / 2 ;Compute the work window parameters. workstate = { name:'work', $ id:0L, $ dx:xsize, $ dy:ysize, $ eightbit: eightbit, $ ncolors: ncolors, $ spx:0, $ spy:0, $ xcen:0, $ ycen:0, $ xoff:0, $ yoff:0, $ xsize:xsize, $ ysize:ysize, $ xvisible:wxvisible, $ yvisible:wyvisible, $ zfact:1 } zfact = max( [xsize/wxvisible, ysize/wyvisible] ) if zfact lt 1 then begin ;The image size is less than the default size of the viewport. ;Determine if the image should be expanded (not more than a factor of ;3, unless fixed by WZOOMFACT keyword). zfact = min( [wxvisible/xsize, wyvisible/ysize] ) if zfact gt 6 then zfact=6 if keyword_set( wzoomfact ) then begin if wzoomfact gt 0 then zfact=wzoomfact endif if zfact lt 1 then zfact=1 workstate.xsize = zfact * xsize workstate.ysize = zfact * ysize workstate.xvisible = workstate.xsize workstate.yvisible = workstate.ysize workstate.zfact = zfact endif ;Compute the zoom draw window parameters. zoomstate = { name:'zoom', $ id:0L, $ dx:0, $ dy:0, $ eightbit: eightbit, $ ncolors: ncolors, $ spx:0, $ spy:0, $ xcen:0, $ ycen:0, $ xoff:0, yoff:0, $ xsize:xsize, $ ysize:ysize, $ xvisible:zvisible, $ yvisible:zvisible, $ zfact:workstate.zfact*2 } zoomstate.xcen = xsize / 2 zoomstate.ycen = ysize / 2 retain = 2 ; Define the full-view draw window. wb1 = widget_base( maindrawbase, /COLUMN ) state.full_view = widget_draw( wb1, /BUTTON_EVENTS, $ RETAIN=retain, XSIZE=fvisible, YSIZE=fvisible ) draw_state.full_view = state.full_view fullstate.id = state.full_view widget_control, state.full_view, set_uvalue=fullstate ;Define the zoom draw window. state.zoom_view = widget_draw( wb1, /BUTTON_EVENTS, $ /MOTION_EVENTS, RETAIN=retain, $ XSIZE=zvisible, YSIZE=zvisible ) draw_state.zoom_view = state.zoom_view zoomstate.id = state.zoom_view widget_control, state.zoom_view, set_uvalue=zoomstate state.zoomupid = widget_button( wb1, VALUE='Zoom+' ) state.zoomdnid = widget_button( wb1, VALUE='Zoom-' ) ; zoombase = widget_base( wb1, /ROW ) zlabel = widget_label( zoombase, VALUE='Zoom factor:' ) state.zoomvid = widget_label( zoombase, $ VALUE=string( zoomstate.zfact, format='(I3)' ) ) dummy1 = widget_label( wb1, VALUE=' ' ) state.objectid = widget_label( wb1, VALUE=' ', /ALIGN_LEFT ) state.filterid = widget_label( wb1, VALUE=' ', /ALIGN_LEFT ) state.airmasid = widget_label( wb1, VALUE=' ', /ALIGN_LEFT ) state.exptimid = widget_label( wb1, VALUE=' ', /ALIGN_LEFT ) state.utdateid = widget_label( wb1, VALUE=' ', /ALIGN_LEFT ) state.uttimeid = widget_label( wb1, VALUE=' ', /ALIGN_LEFT ) dummy1 = widget_label( wb1, VALUE=' ' ) state.ptraceid = widget_button( wb1, VALUE='Profile Trace' ) ; Define the work draw window. state.scroll = (workstate.xsize gt workstate.xvisible) or $ (workstate.ysize gt workstate.yvisible) draw_state.scroll = state.scroll if workstate.xvisible gt workstate.xsize then workstate.xvisible=workstate.xsize if workstate.yvisible gt workstate.ysize then workstate.yvisible=workstate.ysize state.workbase = widget_base( maindrawbase, /COLUMN ) if state.scroll then begin state.work_view = widget_draw( state.workbase, /BUTTON_EVENTS, $ /MOTION_EVENTS, RETAIN=retain, $ /SCROLL, $ XSIZE=workstate.xsize, $ YSIZE=workstate.ysize, $ X_SCROLL_SIZE=workstate.xvisible, $ Y_SCROLL_SIZE=workstate.yvisible ) endif else begin state.work_view = widget_draw( state.workbase, /BUTTON_EVENTS, $ /MOTION_EVENTS, RETAIN=retain, $ XSIZE=workstate.xsize, $ YSIZE=workstate.ysize ) endelse draw_state.work_view = state.work_view workstate.id = state.work_view widget_control, state.work_view, set_uvalue=workstate ; Label the work window with its zoom factor and image file name. wb = widget_base( state.workbase, /ROW ) w1 = widget_label( wb, VALUE='Zoom factor:' ) w1 = widget_label( wb, VALUE=string( workstate.zfact, format='(I3)' ) ) ;Load photometry parameters from a file? if ph_parms.parmfile ne '' then begin it_pplod, ph_parms endif ;if state.scroll then begin ; xoff = max( [0, (xsize-workstate.xvisible)/2 ] ) ; yoff = max( [0, (ysize-workstate.yvisible)/2 ] ) ; widget_control, state.work_view, SET_DRAW_VIEW=[xoff, yoff] ;endif widget_control, draw_state.phparmsbase, set_uvalue=ph_parms ;Put some pointers into a 'state' structure and store it in the Top Level ;Base of the Pixel Editor. This provides the external event handler for ;the Pixel Editor with information it needs to access some of cw_itool's ;control data. widget_control, state.pixedbase, set_uvalue={imparmsbase:state.imparmsbase, $ work_view:state.work_view, zoom_view:state.zoom_view}, /NO_COPY ; do the same for the template manager widget_control, state.tpmgrbase, set_uvalue={active:0L, $ drawbase: state.drawbase}, /NO_COPY ;Store the main state structure. stash = widget_info( mainbase, /CHILD ) draw_state.mainstash = stash widget_control, state.drawbase, set_uvalue=draw_state widget_control, stash, set_uvalue=state, /NO_COPY return, mainbase end