Viewing contents of file '../idllib/contrib/buie/cw_itool.pro'
;+
; 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.
; 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.
;-
; ------------------------------------------------------------------------------
; Internal Support Procedures:
;
; 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_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_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, ''
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)' )
; PRINT, ''
; MESSAGE, 'Statistics for image ' + im_parms.imfile + ':', /INFO
; PRINT, prefix + 'median ' + STRING(medvalue) + ' sigma ' + STRING(sdvalue)
; PRINT, prefix + 'stretch range ' + STRING( z1, FORMAT=f ) + ' to ' + $
; STRING( z2, FORMAT=f ) + ' (-' + dms + ' sigma to +' + $
; dps + ' sigma)'
; PRINT, prefix + 'sub-array min and max: ' + STRING(m1) + STRING(m2)
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_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=!D.N_COLORS-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=!D.N_COLORS-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=!D.N_COLORS-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=!D.N_COLORS-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=!D.N_COLORS-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=!D.N_COLORS-1 ), $
workstate.xoff, workstate.yoff
ENDELSE
WIDGET_CONTROL, draw_state.work_view, SET_UVALUE=workstate, /NO_COPY
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, '<default>' ]
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 '<DEFAULT>', 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]
;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]
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_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=!d.n_colors-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=!d.n_colors-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=!D.N_COLORS-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.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 1024 THEN BEGIN
xvisdef = 900
yvisdef = 640
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
; Initialize the main-state control structure.
state = { $
mainbase:0L, $ ; Itool base id.
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.
dispminid:0L, dispmaxid:0L, $ ; Widget id's for stretch min and max.
drawbase:0L, $
dismissid:0L, $
extrema1id:0L, $
extrema2id:0L, $
fmtg:'(G12.6)', $ ; Image info format.
fmti:'(I12)', $ ; Image info format.
font:'8x13', $ ; Font for some label and text widgets.
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, $
savplt:!p, $ ; Save area for plotting environment.
scroll:0B, $
tpmgrbase:0L, $
tempedit:0, $ ; Template edit flag.
tmplfile:'', $ ; Name of template manager file.
tmplmgrid:0L, $
trkid:0L, $
workbase:0L, $
work_view:0L, $
zoomupid:0L, $
zoomdnid:0L, $
zoomvid:0L, $
zoom_view:0L }
;Initialize the draw state structure.
draw_state = { $
cpmgrbase:0L, $
curposid:0L, $
full_view:0L, $
imparmsbase:0L, $
mainstash:0L, $
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', /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, 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, 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, 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 = 1
; 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 )
; 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
;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