Viewing contents of file '../idllib/contrib/atv/atv.pro'
;+
; NAME:
; ATV
;
; PURPOSE:
; Interactive display of 2-D images. Uses widgets and is similar
; to SAOimage and ximtool.
;
; CATEGORY:
; Image display.
;
; CALLING SEQUENCE:
; atv [,array_name] [,min = min_value] [,max=max_value]
; [,/autoscale] [,/linear] [,/log] [,/histeq]
;
; REQUIRED INPUTS:
; None. If atv is run with no inputs, the window widgets
; are realized and images can subsequently be passed to atv
; from the command line or from the pull-down file menu.
;
; OPTIONAL INPUTS:
; array_name: a 2-D data array to display
;
; KEYWORDS:
; min: minimum data value to be mapped to the color table
; max: maximum data value to be mapped to the color table
; autoscale: set min and max to show a range of data values
; around the median value
; linear: use linear stretch
; log: use log stretch
; histeq: use histogram equalization
;
; OUTPUTS:
; None.
;
; COMMON BLOCKS:
; atv_state: contains variables describing the display state
; atv_images: contains the internal copies of the display image
; atv_color: contains colormap vectors
;
; RESTRICTIONS:
; Requires the GSFC IDL astronomy library routines,
; for fits input.
; The current version only works with 8-bit color.
; For a current list of atv's bugs and weirdnesses, go to
; http://cfa-www.harvard.edu/~abarth/atv/atv.html
;
; SIDE EFFECTS:
; Modifies the color table.
;
; EXAMPLE:
; To start atv running, just enter the command 'atv' at the
; idl prompt, either with or without an array name as an input.
; Only one atv window will be created at a time, so if one
; already exists and another image is passed to atv from the
; idl command line, the new image will be displayed in the
; pre-existing atv window.
;
; MODIFICATION HISTORY:
; Written by Aaron J. Barth, first release 17 December 1998.
; This version is 1.0b3, last modified 08 June 1998.
; For the most current version, revision history, and further
; information, go to:
; http://cfa-www.harvard.edu/~abarth/atv/atv.html
;-
;----------------------------------------------------------------------
pro atv_startup
; This routine initializes the atv internal variables, and creates and
; realizes the window widgets. It is only called by the atv main
; program level, when there is no previously existing atv window.
common atv_state, state
common atv_images, $
main_image, $
display_image, $
scaled_image, $
blink_image, $
pan_image
common atv_color, r_vector, g_vector, b_vector
state = { $
base_id: 0L, $ ; id of top-level base
base_min_size: [512L, 512L], $ ; min size for top-level base
draw_base_id: 0L, $ ; id of base holding draw window
draw_window_id: 0L, $ ; window id of draw window
draw_widget_id: 0L, $ ; widget id of draw widget
track_window_id: 0L, $ ; widget id of tracking window
pan_window_id: 0L, $ ; widget id of pan window
location_bar_id: 0L, $ ; id of (x,y,value) label
min_text_id: 0L, $ ; id of min= widget
max_text_id: 0L, $ ; id of max= widget
menu_ids: lonarr(19), $ ; list of top menu items
brightness_slider_id: 0L, $ ; id of brightness widget
contrast_slider_id: 0L, $ ; id of contrast widget
keyboard_text_id: 0L, $ ; id of keyboard input widget
image_min: 0.0, $ ; min(main_image)
image_max: 0.0, $ ; max(main_image)
min_value: 0.0, $ ; min data value mapped to colors
max_value: 0.0, $ ; max data value mapped to colors
mode: 'zoom', $ ; zoom or blink
draw_window_size: [512L, 512L], $ ; size of main draw window
track_window_size: 121L, $ ; size of tracking window
pan_window_size: 121L, $ ; size of pan window
pan_scale: 0.0, $ ; magnification of pan image
image_size: [0L,0L], $ ; size of main_image
invert_colormap: 0L, $ ; 0=normal, 1=inverted
mouse: [0L, 0L], $ ; cursor position in image coords
scaling: 0L, $ ; 0=linear, 1=log, 2=histeq
offset: [0L, 0L], $ ; offset to viewport coords
base_pad: [0L, 0L], $ ; padding around draw base
pad: [0L, 0L], $ ; padding around draw widget
zoom_level: 0L, $ ; integer zoom level, 0=normal
zoom_factor: 1.0, $ ; magnification factor = 2^zoom_level
centerpix: [0L, 0L], $ ; pixel at center of viewport
pan_track: 0L, $ ; flag=1 while mouse dragging
pan_offset: [0L, 0L], $ ; image offset in pan window
lineplot_widget_id: 0L, $ ; id of lineplot widget
lineplot_window_id: 0L, $ ; id of lineplot window
lineplot_base_id: 0L, $ ; id of lineplot top-level base
lineplot_size: [600L, 450L], $ ; size of lineplot window
lineplot_pad: [0L, 0L], $ ; padding around lineplot window
cursorpos: lonarr(2), $ ; cursor x,y for photometry
centerpos: fltarr(2), $ ; centered x,y for photometry
cursorpos_id: 0L, $ ; id of cursorpos widget
centerpos_id: 0L, $ ; id of centerpos widget
centerbox_id: 0L, $ ; id of centeringboxsize widget
radius_id: 0L, $ ; id of radius widget
innersky_id: 0L, $ ; id of inner sky widget
outersky_id: 0L, $ ; id of outer sky widget
skyresult_id: 0L, $ ; id of sky widget
photresult_id: 0L, $ ; id of photometry result widget
centerboxsize: 11L, $ ; centering box size
r: 5L, $ ; aperture photometry radius
innersky: 10L, $ ; inner sky radius
outersky: 20L $ ; outer sky radius
}
; Read in a color table to initialize !d.table_size
loadct, 0, /silent
; Define the widgets. For the widgets that need to be modified later
; on, save their widget ids in state variables
base = widget_base(title = 'atv', $
/column, /base_align_right, $
app_mbar = top_menu, $
uvalue = 'atv_base', $
/tlb_size_events)
state.base_id = base
tmp_struct = {cw_pdmenu_s, flags:0, name:''}
top_menu_desc = [ $
{cw_pdmenu_s, 1, 'File'}, $ ; file menu
{cw_pdmenu_s, 0, 'ReadFits'}, $
{cw_pdmenu_s, 0, 'WriteEPS'}, $
{cw_pdmenu_s, 0, 'WriteTiff'}, $
{cw_pdmenu_s, 2, 'Quit'}, $
{cw_pdmenu_s, 1, 'ColorMap'}, $ ; color menu
{cw_pdmenu_s, 0, 'Grayscale'}, $
{cw_pdmenu_s, 0, 'Blue-White'}, $
{cw_pdmenu_s, 0, 'Red-Orange'}, $
{cw_pdmenu_s, 0, 'Rainbow'}, $
{cw_pdmenu_s, 0, 'BGRY'}, $
{cw_pdmenu_s, 2, 'ATV Special'}, $
{cw_pdmenu_s, 1, 'Scaling'}, $ ; scaling menu
{cw_pdmenu_s, 0, 'Linear'}, $
{cw_pdmenu_s, 0, 'Log'}, $
{cw_pdmenu_s, 2, 'HistEq'}, $
{cw_pdmenu_s, 1, 'Help'}, $
{cw_pdmenu_s, 2, 'ATV Help'} $
]
top_menu = cw_pdmenu(top_menu, top_menu_desc, $
ids = state.menu_ids, $
/mbar, $
/help, $
/return_id, $
uvalue = 'top_menu')
track_base = widget_base(base, /row)
track_base_1 = widget_base(track_base, /column, /align_right)
track_base_1a = widget_base(track_base_1, /row, /align_bottom)
slider_base = widget_base(track_base_1a, /column, /align_right)
minmax_base = widget_base(track_base_1a, /column, /align_right)
track_base_2 = widget_base(track_base, /row, /base_align_bottom)
button_base1 = widget_base(base, /row, /base_align_bottom)
button_base2 = widget_base(base, /row, /base_align_bottom)
mode_base = widget_base(button_base1, /row, /base_align_bottom, /exclusive)
state.draw_base_id = $
widget_base(base, $
/column, /base_align_left, $
/tracking_events, $
uvalue = 'draw_base', $
frame = 2)
state.brightness_slider_id = $
widget_slider(slider_base, $
/drag, $
minimum = 0, $
maximum = 2 * !d.table_size - 1, $
title = 'Brightness', $
uvalue = 'brightness', $
value = !d.table_size, $
/suppress_value)
state.contrast_slider_id = $
widget_slider(slider_base, $
/drag, $
minimum = 0, $
maximum = 100, $
title = 'Contrast', $
uvalue = 'contrast', $
value = 50, $
/suppress_value)
zoommode_button = $
widget_button(mode_base, $
value = 'ZoomMode', $
uvalue = 'zoom_mode')
blinkmode_button = $
widget_button(mode_base, $
value = 'BlinkMode', $
uvalue = 'blink_mode')
invert_button = $
widget_button(button_base1, $
value = 'Invert', $
uvalue = 'invert')
reset_button = $
widget_button(button_base1, $
value = 'ResetColor', $
uvalue = 'reset_color')
autoscale_button = $
widget_button(button_base1, $
uvalue = 'autoscale_button', $
value = 'AutoScale')
fullrange_button = $
widget_button(button_base1, $
uvalue = 'full_range', $
value = 'FullRange')
state.keyboard_text_id = $
widget_text(button_base2, $
/all_events, $
scr_xsize = 1, $
scr_ysize = 1, $
units = 0, $
uvalue = 'keyboard_text', $
value = '')
zoomin_button = $
widget_button(button_base2, $
value = 'ZoomIn', $
uvalue = 'zoom_in')
zoomout_button = $
widget_button(button_base2, $
value = 'ZoomOut', $
uvalue = 'zoom_out')
zoomone_button = $
widget_button(button_base2, $
value = 'Zoom1', $
uvalue = 'zoom_one')
center_button = $
widget_button(button_base2, $
value = 'Center', $
uvalue = 'center')
setblink_button = $
widget_button(button_base2, $
uvalue = 'set_blink', $
value = 'SetBlink')
done_button = $
widget_button(button_base2, $
value = 'Done', $
uvalue = 'done')
state.min_text_id = $
cw_field(minmax_base, $
uvalue = 'min_text', $
/floating, $
title = 'Min=', $
value = state.min_value, $
/return_events, $
xsize = 8)
state.max_text_id = $
cw_field(minmax_base, $
uvalue = 'max_text', $
/floating, $
title = 'Max=', $
value = state.max_value, $
/return_events, $
xsize = 8)
tmp_string = string(1000, 1000, 1.0e-10, $
format = '("(",i4,",",i4,") ",g12.5)' )
state.location_bar_id = $
widget_label (track_base_1, $
value = tmp_string, $
uvalue = 'location_bar', frame = 1)
pan_window = $
widget_draw(track_base_2, $
xsize = state.pan_window_size, $
ysize = state.pan_window_size, $
frame = 2, uvalue = 'pan_window', $
/button_events, /motion_events)
track_window = $
widget_draw(track_base_2, $
xsize=state.track_window_size, $
ysize=state.track_window_size, $
frame=2, uvalue='track_window')
state.draw_widget_id = $
widget_draw(state.draw_base_id, $
uvalue = 'draw_window', $
/motion_events, /button_events, $
scr_xsize = state.draw_window_size[0], $
scr_ysize = state.draw_window_size[1])
; Create the widgets on screen
widget_control, base, /realize
widget_control, zoommode_button, /set_button
; get the window ids for the draw widgets
widget_control, track_window, get_value = tmp_value
state.track_window_id = tmp_value
widget_control, state.draw_widget_id, get_value = tmp_value
state.draw_window_id = tmp_value
widget_control, pan_window, get_value = tmp_value
state.pan_window_id = tmp_value
; Find window padding sizes needed for resizing routines.
; Add extra padding for menu bar, since this isn't included in
; the geometry returned by widget_info.
; Also add extra padding for margin (frame) in draw base.
basegeom = widget_info(state.base_id, /geometry)
drawbasegeom = widget_info(state.draw_base_id, /geometry)
state.pad[0] = basegeom.xsize - state.draw_window_size[0]
state.pad[1] = basegeom.ysize - state.draw_window_size[1] + 30
state.base_pad[0] = basegeom.xsize - drawbasegeom.xsize $
+ (2 * basegeom.margin)
state.base_pad[1] = basegeom.ysize - drawbasegeom.ysize + 30 $
+ (2 * basegeom.margin)
state.base_min_size = [512, state.base_pad[1] + 100]
; Initialize the vectors that hold the current color table.
; See the routine atv_stretchct to see why we do it this way.
r_vector = bytarr(!d.table_size * 3)
g_vector = bytarr(!d.table_size * 3)
b_vector = bytarr(!d.table_size * 3)
tmp_array = replicate(255, !d.table_size)
r_vector[!d.table_size * 2] = tmp_array
g_vector[!d.table_size * 2] = tmp_array
b_vector[!d.table_size * 2] = tmp_array
atv_getct, 0
state.invert_colormap = 0
xmanager, 'atv', state.base_id, /no_block
end
;--------------------------------------------------------------------
pro atv_displayall
; Call the routines to scale the image, make the pan image, and
; re-display everything. Use this if the scaling changes (log/
; linear/ histeq), or if min or max are changed, or if a new image is
; passed to atv. If the display image has just been moved around or
; zoomed without a change in scaling, then just call atv_refresh
; rather than this routine.
atv_scaleimage
atv_makepan
atv_refresh
end
;--------------------------------------------------------------------
pro atv_readfits
; Read in a new image when user goes to the File->ReadFits menu.
; Can be modified to use mrdfits if fits extensions are used.
common atv_state
common atv_images
fitsfile = $
dialog_pickfile(filter = '*.fits', $
group = state.base_id, $
/must_exist, $
/read, $
title = 'Select Fits Image')
if (fitsfile NE '') then begin ; 'cancel' button returns empty string
; note: found that "readfits" chokes on some non-standard
; fits files, but "fits_read" handles them ok.
fits_read, fitsfile, tmp_image
if ( (size(tmp_image))[0] NE 2 ) then begin
mesg = 'Warning-- selected file is not a 2-D fits image!'
tmp_result = dialog_message(mesg, /error, $
dialog_parent = state.base_id)
; If the new image is valid, put it into main_image
endif else begin
main_image = temporary(tmp_image)
atv_getstats
state.zoom_level = 0
state.zoom_factor = 1.0
atv_set_minmax
atv_displayall
endelse
atv_cleartext
endif
end
;----------------------------------------------------------------------
pro atv_writetiff
; writes a tiff image of the current display
common atv_state
common atv_images
; Get filename to save image
filename = dialog_pickfile(filter = '*.tiff', $
file = 'atv.tiff', $
group = state.base_id, $
/write)
tmp_result = findfile(filename, count = nfiles)
result = ''
if (nfiles GT 0 and filename NE '') then begin
mesg = strarr(2)
mesg[0] = 'Overwrite existing file:'
tmp_string = strmid(filename, rstrpos(filename, '/') + 1)
mesg[1] = strcompress(tmp_string + '?', /remove_all)
result = dialog_message(mesg, $
/default_no, $
dialog_parent = state.base_id, $
/question)
endif
if ((nfiles EQ 0 OR result EQ 'Yes') AND filename NE '') then begin
tvlct, rr, gg, bb, /get
rn = congrid(temporary(rr), 256)
gn = congrid(temporary(gg), 256)
bn = congrid(temporary(bb), 256)
write_tiff, filename, bytscl(display_image), $
red = temporary(rn), $
green = temporary(gn), $
blue = temporary(bn)
endif
atv_cleartext
end
;----------------------------------------------------------------------
pro atv_writeps
; writes an encapsulated postscript file of the current display, set
; to a width of 6 inches
common atv_state
common atv_images
filename = dialog_pickfile(filter = '*.eps', $
file = 'atv.eps', $
group = state.base_id, $
/write)
tmp_result = findfile(filename, count = nfiles)
result = ''
if (nfiles GT 0 and filename NE '') then begin
mesg = strarr(2)
mesg[0] = 'Overwrite existing file:'
tmp_string = strmid(filename, rstrpos(filename, '/') + 1)
mesg[1] = strcompress(tmp_string + '?', /remove_all)
result = dialog_message(mesg, $
/default_no, $
dialog_parent = state.base_id, $
/question)
endif
if ((nfiles EQ 0 OR result EQ 'Yes') AND filename NE '') then begin
screen_device = !d.name
tvlct, rr, gg, bb, /get
wset, state.draw_window_id
tmp_image = bytscl(tvrd())
aspect_ratio = $
state.draw_window_size[1] / float(state.draw_window_size[0])
set_plot, 'ps'
device, $
filename = filename, $
/color, $
bits_per_pixel = 8, $
/encapsul, $
/inches, $
xsize = 6.0, $
ysize = 6.0 * aspect_ratio
rn = congrid(rr, 256)
gn = congrid(gg, 256)
bn = congrid(bb, 256)
tvlct, temporary(rn), temporary(gn), temporary(bn)
tv, temporary(tmp_image)
device, /close
set_plot, screen_device
tvlct, temporary(rr), temporary(gg), temporary(bb)
endif
atv_cleartext
end
;----------------------------------------------------------------------
pro atv_cleartext
; Routine to clear the widget for keyboard input when the mouse is in
; the text window. This de-allocates the input focus from the text
; input widget.
common atv_state
widget_control, state.draw_base_id, /clear_events
widget_control, state.keyboard_text_id, set_value = ''
end
;----------------------------------------------------------------------
pro atv_getoffset
common atv_state
; Routine to calculate the display offset for the current value of
; state.centerpix, which is the central pixel in the display window.
state.offset = $
round( state.centerpix - $
(0.5 * state.draw_window_size / state.zoom_factor) )
end
;----------------------------------------------------------------------
pro atv_zoom, zchange, recenter = recenter
common atv_state
; Routine to do zoom in/out and recentering of image
case zchange of
'in': state.zoom_level = (state.zoom_level + 1) < 6
'out': state.zoom_level = (state.zoom_level - 1) > (-6)
'one': state.zoom_level = 0
'none': ; no change to zoom level: recenter on current mouse position
else: print, 'problem in atv_zoom!'
endcase
state.zoom_factor = 2.^state.zoom_level
if (n_elements(recenter) GT 0) then begin
state.centerpix = state.mouse
atv_getoffset
endif
atv_refresh
if (n_elements(recenter) GT 0) then begin
newpos = (state.mouse - state.offset + 0.5) * state.zoom_factor
wset, state.draw_window_id
tvcrs, newpos[0], newpos[1], /device
atv_gettrack
endif
end
;----------------------------------------------------------------------
function atv_polycolor, p
; Routine to return an vector of length !d.table_size,
; defined by a 5th order polynomial. Called by atv_makect
; to define new color tables in terms of polynomial coefficients.
x = findgen(256)
y = p[0] + x * p[1] + x^2 * p[2] + x^3 * p[3] + x^4 * p[4] + x^5 * p[5]
w = where(y GT 255, nw)
if (nw GT 0) then y(w) = 255
w = where(y LT 0, nw)
if (nw GT 0) then y(w) = 0
z = congrid(y, !d.table_size)
return, z
end
;----------------------------------------------------------------------
pro atv_makect, tablename
; Define new color tables here, in terms of 5th order polynomials.
; To define a new color table, first set it up using xpalette,
; then load current color table into 3 256-element vectors, and
; do a 5th order poly_fit. Store the coefficients and name
; the color table here. Invert if necessary.
common atv_state
common atv_color
case tablename of
'ATV Special': begin
r = atv_polycolor([39.4609, $
-5.19434, $
0.128174, $
-0.000857115, $
2.23517e-06, $
-1.87902e-09])
g = atv_polycolor([-15.3496, $
1.76843, $
-0.0418186, $
0.000308216, $
-6.07106e-07, $
0.0000])
b = atv_polycolor([0.000, $
12.2449, $
-0.202679, $
0.00108027, $
-2.47709e-06, $
2.66846e-09])
end
; add more color table definitions here as needed...
else:
endcase
tvlct, r, g, b
if (state.invert_colormap EQ 1) then begin
r = abs (r - 255)
g = abs (g - 255)
b = abs (b - 255)
endif
r_vector(!d.table_size) = r
g_vector(!d.table_size) = g
b_vector(!d.table_size) = b
atv_stretchct
end
;----------------------------------------------------------------------
pro atv_getstats
; Get basic image stats: min and max, and size.
common atv_state
common atv_images
; this routine operates on main_image, which is in the
; atv_images common block
widget_control, /hourglass
state.image_size = [ (size(main_image))[1], (size(main_image))[2] ]
state.image_min = min(main_image)
state.image_max = max(main_image)
state.min_value = state.image_min
state.max_value = state.image_max
if (state.min_value GE state.max_value) then begin
state.min_value = state.min_value - 1
state.max_value = state.max_value + 1
endif
; zero the current display position on the center of the image
state.mouse = round(state.image_size / 2.)
state.centerpix = round(state.image_size / 2.)
atv_getoffset
end
;----------------------------------------------------------------------
pro atv_gettrack
; Create the image to display in the track window that tracks
; cursor movements.
common atv_state
common atv_images
; Get x and y for center of track window
zcenter = (0 > state.mouse < state.image_size)
track_image = $
rebin(scaled_image[zcenter[0]:zcenter[0]+10, $
zcenter[1]:zcenter[1]+10], $
state.track_window_size, state.track_window_size, $
/sample)
wset, state.track_window_id
tv, track_image
; Overplot an X on the central pixel in the track window, to show the
; current mouse position
device, set_graphics = 10
plots, [0.46, 0.54], [0.46, 0.54], /normal
plots, [0.46, 0.54], [0.54, 0.46], /normal
device, set_graphics = 3
; update location bar with x, y, and pixel value
loc_string = $
string(state.mouse[0], $
state.mouse[1], $
main_image[state.mouse[0], $
state.mouse[1]], $
format = '("(",i4,",",i4,") ",g12.5)')
widget_control, state.location_bar_id, $
set_value = loc_string
end
;----------------------------------------------------------------------
pro atv_event, event
; Main event loop for ATV widgets.
common atv_state
common atv_images
common atv_color, r_vector, g_vector, b_vector
widget_control, event.id, get_uvalue = uvalue
case uvalue of
'zoom_mode': state.mode = 'zoom'
'blink_mode': state.mode = 'blink'
'atv_base': begin ; main window resize: preserve display center
atv_resize, event
atv_refresh
atv_cleartext
end
'top_menu': begin ; selection from menu bar
widget_control, event.value, get_value = event_name
parent = widget_info(event.value, /parent)
widget_control, parent, get_value = parent_name
case parent_name of
'File': begin
case event_name of
'ReadFits': atv_readfits
'WriteEPS' : atv_writeps
'WriteTiff': atv_writetiff
'Quit': atv_shutdown
else:
endcase
end
'ColorMap': begin
case event_name of
'Grayscale': atv_getct, 0
'Blue-White': atv_getct, 1
'Red-Orange': atv_getct, 3
'BGRY': atv_getct, 4
'Rainbow': atv_getct, 13
'ATV Special': atv_makect, event_name
else:
endcase
end
'Scaling': begin
case event_name of
'Linear': state.scaling = 0
'Log': state.scaling = 1
'HistEq': state.scaling = 2
else:
endcase
atv_displayall
atv_cleartext
end
'Help': atv_help
else: print, 'Unknown event in file menu!'
endcase
end
; If the mouse enters the main draw base, set the input focus to
; the invisible text widget, for keyboard input.
; When the mouse leaves the main draw base, de-allocate the input
; focus by setting the text widget value.
'draw_base': begin
case event.enter of
0: begin
widget_control, state.keyboard_text_id, set_value = ''
end
1: begin
widget_control, state.keyboard_text_id, /input_focus
end
endcase
end
'draw_window': begin ; mouse movement or button press
if (event.type EQ 2) then begin ; motion event
tmp_event = [event.x, event.y]
state.mouse = $
round( (0.5 > $
((tmp_event / state.zoom_factor) + state.offset) $
< (state.image_size - 0.5) ) - 0.5)
atv_gettrack
endif
case state.mode of ; button events
'blink': begin ; button press or release in blink mode
case event.type of
0: begin ; button press: blink
wset, state.draw_window_id
if n_elements(blink_image) GT 1 then $
tv, blink_image
end
1: begin ; button release: unblink
wset, state.draw_window_id
tv, display_image
end
else:
endcase
end
'zoom': begin ; button press in zoom mode
if (event.type EQ 0) then begin
case event.press of
1: atv_zoom, 'in', /recenter
2: atv_zoom, 'none', /recenter
4: atv_zoom, 'out', /recenter
else: print, 'trouble in atv_event, mouse zoom'
endcase
endif
end
endcase
widget_control, state.keyboard_text_id, /input_focus
end
'brightness': atv_stretchct ; brightness slider move
'contrast' : atv_stretchct ; contrast slider move
'invert': begin ; invert the color table
state.invert_colormap = abs(state.invert_colormap - 1)
tvlct, r, g, b, /get
r = abs( r - 255 )
g = abs( g - 255 )
b = abs( b - 255 )
r_vector = abs( r_vector - 255 )
g_vector = abs( g_vector - 255 )
b_vector = abs( b_vector - 255 )
tvlct, r, g, b
atv_cleartext
end
'reset_color': begin ; set color sliders to default positions
widget_control, $
state.brightness_slider_id, set_value = !d.table_size
widget_control, $
state.contrast_slider_id, set_value = 50
atv_stretchct
atv_cleartext
end
'min_text': begin ; text entry in 'min = ' box
atv_get_minmax, uvalue, event.value
atv_displayall
end
'max_text': begin ; text entry in 'max = ' box
atv_get_minmax, uvalue, event.value
atv_displayall
end
'autoscale_button': begin ; autoscale the image
atv_autoscale
atv_displayall
atv_cleartext
end
'full_range': begin ; display the full intensity range
state.min_value = state.image_min
state.max_value = state.image_max
if state.min_value GE state.max_value then begin
state.min_value = state.max_value - 1
state.max_value = state.max_value + 1
endif
atv_set_minmax
atv_displayall
atv_cleartext
end
'set_blink': begin ; store current display image for blinking
blink_image = display_image
end
'keyboard_text': begin ; keyboard input with mouse in display window
eventchar = string(event.ch)
case eventchar of
'1': atv_move_cursor, eventchar
'2': atv_move_cursor, eventchar
'3': atv_move_cursor, eventchar
'4': atv_move_cursor, eventchar
'6': atv_move_cursor, eventchar
'7': atv_move_cursor, eventchar
'8': atv_move_cursor, eventchar
'9': atv_move_cursor, eventchar
'r': atv_rowplot
'c': atv_colplot
's': atv_surfplot
't': atv_contourplot
'p': atv_mapphot
else: ;any other key press does nothing
endcase
widget_control, state.keyboard_text_id, /clear_event
end
'zoom_in': atv_zoom, 'in' ; zoom buttons
'zoom_out': atv_zoom, 'out'
'zoom_one': atv_zoom, 'one'
'center': begin ; center image and preserve current zoom level
atv_drawbox
state.centerpix = round(state.image_size / 2.)
atv_getoffset
atv_drawbox
atv_getdisplay
end
'pan_window': begin ; move the box around in the pan window
case event.type of
2: begin ; motion event
if (state.pan_track EQ 1) then begin
atv_pantrack, event
endif
end
0: begin ; button press
state.pan_track = 1
atv_pantrack, event
end
1: begin ; button release
state.pan_track = 0
atv_getdisplay
end
else:
endcase
end
'done': atv_shutdown
else: print, 'No match for uvalue....' ; bad news if this happens
endcase
end
;----------------------------------------------------------------------
pro atv_drawbox
; routine to draw the box on the pan window, given the current center
; of the display image.
;
; By using device, set_graphics = 6, the same routine can be used both
; to draw the box, and to remove the box by drawing it over again at
; the same position. So, to move the box around, call this routine at
; the old position to erase the old box, then get the new box position
; and update state.centerpix, then call this routine again to draw the
; new box.
common atv_state
wset, state.pan_window_id
view_min = round(state.centerpix - $
(0.5 * state.draw_window_size / state.zoom_factor))
view_max = round(view_min + state.draw_window_size / state.zoom_factor)
; Create the vectors which contain the box coordinates
box_x = float((([view_min[0], $
view_max[0], $
view_max[0], $
view_min[0], $
view_min[0]]) * state.pan_scale) + state.pan_offset[0])
box_y = float((([view_min[1], $
view_min[1], $
view_max[1], $
view_max[1], $
view_min[1]]) * state.pan_scale) + state.pan_offset[1])
; Plot the box
device, set_graphics = 6
plots, box_x, box_y, /device, thick = 2
device, set_graphics = 3
end
;----------------------------------------------------------------------
pro atv_shutdown
; routine to kill the atv window(s) and clear variables to conserve
; memory when quitting atv. Since we can't delvar the atv internal
; variables, just set them equal to zero so they don't take up a lot
; of space. Also clear the state and the color map vectors.
common atv_images
common atv_state
common atv_color
if (xregistered ('atv')) then begin
widget_control, state.base_id, /destroy
endif
main_image = 0
display_image = 0
scaled_image = 0
blink_image = 0
pan_image = 0
r_vector = 0
g_vector = 0
b_vector = 0
state = 0
end
;----------------------------------------------------------------------
pro atv_pantrack, event
; routine to track the view box in the pan window during cursor motion
common atv_state
; erase the old box
atv_drawbox
; get the new box coords and draw the new box
tmp_event = [event.x, event.y]
newpos = state.pan_offset > tmp_event < $
(state.pan_offset + (state.image_size * state.pan_scale))
state.centerpix = round( (newpos - state.pan_offset ) / state.pan_scale)
atv_drawbox
atv_getoffset
end
;----------------------------------------------------------------------
pro atv_resize, event
; Routine to resize the draw window when a top-level resize event
; occurs.
common atv_state
tmp_event = [event.x, event.y]
window = (state.base_min_size > tmp_event)
newbase = window - state.base_pad
newsize = window - state.pad
widget_control, state.draw_base_id, $
xsize = newbase[0], ysize = newbase[1]
widget_control, state.draw_widget_id, $
xsize = newsize[0], ysize = newsize[1]
state.draw_window_size = newsize
end
;----------------------------------------------------------------------
pro atv_scaleimage
; Create a byte-scaled copy of the image, scaled according to
; the state.scaling parameter. Add a padding of 5 pixels around the
; image boundary, so that the tracking window can always remain
; centered on an image pixel even if that pixel is at the edge of the
; image.
common atv_state
common atv_images
; Since this can take some time for a big image, set the cursor
; to an hourglass until control returns to the event loop.
widget_control, /hourglass
case state.scaling of
0: tmp_image = $ ; linear stretch
bytscl(main_image, $
min=state.min_value, $
max=state.max_value, $
top = !d.table_size)
1: tmp_image = $ ; log stretch
bytscl( alog10 (bytscl(main_image, $
min=state.min_value, $
max=state.max_value, $
top = !d.table_size) + 1))
2: tmp_image = $ ; histogram equalization
bytscl(hist_equal(main_image, $
minv = state.min_value, $
maxv = state.max_value), $
top = !d.table_size)
endcase
scaled_image = bytarr(state.image_size[0] + 10, $
state.image_size[1] + 10)
scaled_image[5, 5] = temporary(tmp_image)
end
;----------------------------------------------------------------------
pro atv_getdisplay
; make the display image from the scaled image by applying the zoom
; factor and matching to the size of the draw window, and display the
; image.
common atv_state
common atv_images
display_image = $
bytarr(state.draw_window_size[0] + 2 * (round(state.zoom_factor) > 1), $
state.draw_window_size[1] + 2 * (round(state.zoom_factor) > 1))
view_min = round(state.centerpix - $
(0.5 * state.draw_window_size / state.zoom_factor))
view_max = round(view_min + state.draw_window_size / state.zoom_factor)
view_min = (0 > view_min < (state.image_size - 1)) + 5
view_max = (0 > view_max < (state.image_size - 1)) + 5
newsize = round( (view_max - view_min + 1) * state.zoom_factor) > 1
startpos = abs( round(state.offset * state.zoom_factor) < 0)
tmp_image = congrid(scaled_image[view_min[0]:view_max[0], $
view_min[1]:view_max[1]], $
newsize[0], newsize[1])
display_image[startpos[0], startpos[1]] = tmp_image
; Display the image
wset, state.draw_window_id
erase
tv, display_image
end
;--------------------------------------------------------------------
pro atv_makepan
; Make the 'pan' image that shows a miniature version of the full image.
common atv_state
common atv_images
sizeratio = state.image_size[1] / state.image_size[0]
if (sizeratio GE 1) then begin
state.pan_scale = float(state.pan_window_size) / float(state.image_size[1])
endif else begin
state.pan_scale = float(state.pan_window_size) / float(state.image_size[0])
endelse
tmp_image = $
scaled_image[5:state.image_size[0]+4, 5:state.image_size[1]+4]
pan_image = congrid(tmp_image, round(state.pan_scale * state.image_size[0]), $
round(state.pan_scale * state.image_size[1]) )
state.pan_offset[0] = round((state.pan_window_size - (size(pan_image))[1]) / 2)
state.pan_offset[1] = round((state.pan_window_size - (size(pan_image))[2]) / 2)
end
;----------------------------------------------------------------------
pro atv_move_cursor, direction
; Use keypad arrow keys to step cursor one pixel at a time.
; Get the new track image, and update the cursor position.
common atv_state
i = 1L
case direction of
'2': state.mouse[1] = max([state.mouse[1] - i, 0])
'4': state.mouse[0] = max([state.mouse[0] - i, 0])
'8': state.mouse[1] = min([state.mouse[1] + i, state.image_size[1] - i])
'6': state.mouse[0] = min([state.mouse[0] + i, state.image_size[0] - i])
'7': begin
state.mouse[1] = min([state.mouse[1] + i, state.image_size[1] - i])
state.mouse[0] = max([state.mouse[0] - i, 0])
end
'9': begin
state.mouse[1] = min([state.mouse[1] + i, state.image_size[1] - i])
state.mouse[0] = min([state.mouse[0] + i, state.image_size[0] - i])
end
'3': begin
state.mouse[1] = max([state.mouse[1] - i, 0])
state.mouse[0] = min([state.mouse[0] + i, state.image_size[0] - i])
end
'1': begin
state.mouse[1] = max([state.mouse[1] - i, 0])
state.mouse[0] = max([state.mouse[0] - i, 0])
end
endcase
newpos = (state.mouse - state.offset + 0.5) * state.zoom_factor
wset, state.draw_window_id
tvcrs, newpos[0], newpos[1], /device
atv_gettrack
; Prevent the cursor move from causing a mouse event in the draw window
widget_control, state.draw_widget_id, /clear_events
end
;----------------------------------------------------------------------
pro atv_set_minmax
; Updates the min and max text boxes with new values.
common atv_state
widget_control, state.min_text_id, set_value = string(state.min_value)
widget_control, state.max_text_id, set_value = string(state.max_value)
end
;----------------------------------------------------------------------
pro atv_get_minmax, uvalue, newvalue
; Change the min and max state variables when user inputs new numbers
; in the text boxes.
common atv_state
case uvalue of
'min_text': begin
if (newvalue LT state.max_value) then begin
state.min_value = newvalue
endif
end
'max_text': begin
if (newvalue GT state.min_value) then begin
state.max_value = newvalue
endif
end
endcase
atv_set_minmax
end
;--------------------------------------------------------------------
pro atv_refresh
; Make the display image from the scaled_image, and redisplay the pan
; image and tracking image.
common atv_state
common atv_images
atv_getoffset
atv_getdisplay
; redisplay the pan image and plot the boundary box
wset, state.pan_window_id
erase
tv, pan_image, state.pan_offset[0], state.pan_offset[1]
atv_drawbox
; redisplay the tracking image
wset, state.track_window_id
atv_gettrack
wset, state.draw_window_id
end
;--------------------------------------------------------------------
pro atv_stretchct
; Change brightness and contrast according to slider values.
; For contrast, use same algorithm as IDL 'stretch' routine.
; For brightness, want a linear 'slide' of color table.
; Store the current color table in 3 vectors of length
; (3 * !d.table_size), and when brightness slider moves,
; just 'slide' the color table along these larger vectors.
common atv_state
common atv_color, r_vector, g_vector, b_vector
widget_control, state.brightness_slider_id, $
get_value = brightness
widget_control, state.contrast_slider_id, $
get_value = contrast
gamma = 10^( (contrast/50.) - 1 )
case gamma of
1.0: p = lindgen(!d.table_size)
else: $
p = long( ((findgen(!d.table_size) / !d.table_size ) ^ gamma) $
* !d.table_size)
endcase
; use brightness slider value as zero-point of color table mapping.
r = r_vector[p + brightness]
g = g_vector[p + brightness]
b = b_vector[p + brightness]
tvlct, r, g, b
end
;--------------------------------------------------------------------
pro atv_getct, tablenum
; Read in a pre-defined color table, and invert if necessary.
common atv_color, r_vector, g_vector, b_vector
common atv_state
loadct, tablenum, /silent
tvlct, r, g, b, /get
if (state.invert_colormap EQ 1) then begin
r = abs (r - 255)
g = abs (g - 255)
b = abs (b - 255)
endif
r_vector(!d.table_size) = r
g_vector(!d.table_size) = g
b_vector(!d.table_size) = b
atv_stretchct
end
;--------------------------------------------------------------------
pro atv_autoscale
; Routine to auto-scale the image.
common atv_state
common atv_images
widget_control, /hourglass
med = median(main_image)
sig = stdev(main_image)
state.max_value = (med + (10 * sig)) < max(main_image)
state.min_value = (med - (2 * sig)) > min(main_image)
if (state.min_value LT 0 AND state.max_value GT 0) then begin
state.min_value = 0.0
endif
if (state.min_value GE state.max_value) then begin
state.min_value = state.min_value - 1
state.max_value = state.max_value + 1
endif
atv_set_minmax
end
;--------------------------------------------------------------------
pro atv_lineplot_init
; This routine creates the window for line plots
common atv_state
state.lineplot_base_id = $
widget_base(/floating, $
group_leader = state.base_id, $
/column, $
/base_align_right, $
title = 'atv plot', $
/tlb_size_events, $
uvalue = 'lineplot_base')
state.lineplot_widget_id = $
widget_draw(state.lineplot_base_id, $
frame = 0, $
scr_xsize = state.lineplot_size[0], $
scr_ysize = state.lineplot_size[1], $
uvalue = 'lineplot_window')
lbutton_base = $
widget_base(state.lineplot_base_id, $
/base_align_bottom, $
/row)
lineplot_done = $
widget_button(lbutton_base, $
value = 'Done', $
uvalue = 'lineplot_done')
widget_control, state.lineplot_base_id, /realize
widget_control, state.lineplot_widget_id, get_value = tmp_value
state.lineplot_window_id = tmp_value
basegeom = widget_info(state.lineplot_base_id, /geometry)
drawgeom = widget_info(state.lineplot_widget_id, /geometry)
state.lineplot_pad[0] = basegeom.xsize - drawgeom.xsize
state.lineplot_pad[1] = basegeom.ysize - drawgeom.ysize
xmanager, 'atv_lineplot', state.lineplot_base_id, /no_block
end
;--------------------------------------------------------------------
pro atv_rowplot
common atv_state
common atv_images
if (not (xregistered('atv_lineplot'))) then begin
atv_lineplot_init
endif
wset, state.lineplot_window_id
erase
plot, main_image[*, state.mouse[1]], $
xst = 3, yst = 3, psym = 10, $
title = strcompress('Plot of row ' + $
string(state.mouse[1])), $
xtitle = 'Column', $
ytitle = 'Pixel Value'
widget_control, state.lineplot_base_id, /clear_events
end
;--------------------------------------------------------------------
pro atv_colplot
common atv_state
common atv_images
if (not (xregistered('atv_lineplot'))) then begin
atv_lineplot_init
endif
wset, state.lineplot_window_id
erase
plot, main_image[state.mouse[0], *], $
xst = 3, yst = 3, psym = 10, $
title = strcompress('Plot of column ' + $
string(state.mouse[0])), $
xtitle = 'Row', $
ytitle = 'Pixel Value'
widget_control, state.lineplot_base_id, /clear_events
end
;--------------------------------------------------------------------
pro atv_surfplot
common atv_state
common atv_images
if (not (xregistered('atv_lineplot'))) then begin
atv_lineplot_init
endif
wset, state.lineplot_window_id
erase
plotsize = $
fix(min([50, state.image_size[0]/2., state.image_size[1]/2.]))
center = plotsize > state.mouse < (state.image_size - plotsize)
tmp_string = $
strcompress('Surface plot of ' + $
strcompress('['+string(center[0]-plotsize)+ $
':'+string(center[0]+plotsize-1)+ $
','+string(center[1]-plotsize)+ $
':'+string(center[1]+plotsize-1)+ $
']', /remove_all))
surface, $
main_image[center[0]-plotsize:center[0]+plotsize-1, $
center[1]-plotsize:center[1]+plotsize-1], $
title = temporary(tmp_string), $
xtitle = 'X', ytitle = 'Y', ztitle = 'Pixel Value'
widget_control, state.lineplot_base_id, /clear_events
end
;--------------------------------------------------------------------
pro atv_contourplot
common atv_state
common atv_images
if (not (xregistered('atv_lineplot'))) then begin
atv_lineplot_init
endif
wset, state.lineplot_window_id
erase
plotsize = $
fix(min([50, state.image_size[0]/2., state.image_size[1]/2.]))
center = plotsize > state.mouse < (state.image_size - plotsize)
contour_image = main_image[center[0]-plotsize:center[0]+plotsize-1, $
center[1]-plotsize:center[1]+plotsize-1]
if (state.scaling EQ 1) then begin
contour_image = alog10(contour_image)
logflag = 'Log'
endif else begin
logflag = ''
endelse
tmp_string = $
strcompress(logflag + $
' Contour plot of ' + $
strcompress('['+string(round(center[0]-plotsize))+ $
':'+string(round(center[0]+plotsize-1))+ $
','+string(round(center[1]-plotsize))+ $
':'+string(round(center[1]+plotsize-1))+ $
']', /remove_all))
contour, temporary(contour_image), $
nlevels = 10, $
/follow, $
title = temporary(tmp_string), $
xtitle = 'X', ytitle = 'Y'
widget_control, state.lineplot_base_id, /clear_events
end
;----------------------------------------------------------------------
pro atv_lineplot_event, event
common atv_state
widget_control, event.id, get_uvalue = uvalue
case uvalue of
'lineplot_done': widget_control, event.top, /destroy
'lineplot_base': begin ; Resize event
state.lineplot_size = [event.x, event.y]- state.lineplot_pad
widget_control, state.lineplot_widget_id, $
xsize = (state.lineplot_size[0] > 100), $
ysize = (state.lineplot_size[1] > 100)
wset, state.lineplot_window_id
end
else:
endcase
end
;----------------------------------------------------------------------
pro atv_help
common atv_state
h = strarr(45)
i = 0
h[i] = 'ATV HELP'
i = i + 1
h[i] = ''
i = i + 1
h[i] = 'MENU BAR:'
i = i + 1
h[i] = 'File->ReadFits: read in a new fits image from disk'
i = i + 1
h[i] = 'File->WriteEPS: write an encapsulated PS file of the current display'
i = i + 1
h[i] = 'File->WriteTiff: write a tiff image of the current display'
i = i + 1
h[i] = 'File->Quit: quits atv'
i = i + 1
h[i] = 'ColorMap Menu: selects color table'
i = i + 1
h[i] = 'Scaling Menu: selects linear, log, or histogram-equalized scaling'
i = i + 1
h[i] = ''
i = i + 1
h[i] = 'CONTROL PANEL ITEMS:'
i = i + 1
h[i] = 'Brightness: fairly self-explanatory'
i = i + 1
h[i] = 'Contrast: also fairly self-explanatory'
i = i + 1
h[i] = 'Min: shows minimum data value displayed; click to modify'
i = i + 1
h[i] = 'Max: shows maximum data value displayed; click to modify'
i = i + 1
h[i] = 'Pan Window: use mouse to drag the image-view box around'
i = i + 1
h[i] = ''
i = i + 1
h[i] = 'BUTTONS:'
i = i + 1
h[i] = 'ZoomMode: toggles zoom mode:'
i = i + 1
h[i] = ' button1 = zoom in & center'
i = i + 1
h[i] = ' button2 = center on current position'
i = i + 1
h[i] = ' button3 = zoom out & center'
i = i + 1
h[i] = 'BlinkMode: toggles blink mode:'
i = i + 1
h[i] = ' press mouse button in main window to show blink image'
i = i + 1
h[i] = 'Invert: inverts the current color table'
i = i + 1
h[i] = 'ResetColor: sets the sliders back to defaults'
i = i + 1
h[i] = 'AutoScale: sets min and max to show data values around histogram peak'
i = i + 1
h[i] = 'FullRange: sets min and max to show the full data range of the image'
i = i + 1
h[i] = 'ZoomIn: zooms in by x2'
i = i + 1
h[i] = 'ZoomOut: zooms out by x2'
i = i + 1
h[i] = 'Zoom1: sets zoom level to original scale'
i = i + 1
h[i] = 'Center: centers image on display window'
i = i + 1
h[i] = 'SetBlink: puts current image in blink buffer'
i = i + 1
h[i] = 'Done: quits atv'
i = i + 1
h[i] = ''
i = i + 1
h[i] = 'Keyboard commands in display window:'
i = i + 1
h[i] = ' Numeric keypad (with NUM LOCK on) moves cursor'
i = i + 1
h[i] = ' r: row plot'
i = i + 1
h[i] = ' c: column plot'
i = i + 1
h[i] = ' s: surface plot'
i = i + 1
h[i] = ' t: contour plot'
i = i + 1
h[i] = ' p: aperture photometry at current position'
if (not (xregistered('atv_help'))) then begin
help_base = widget_base(/floating, $
group_leader = state.base_id, $
/column, $
/base_align_right, $
title = 'atv help', $
uvalue = 'help_base')
help_text = widget_text(help_base, $
/scroll, $
value = h, $
xsize = 75, $
ysize = 24)
help_done = widget_button(help_base, $
value = 'Done', $
uvalue = 'help_done')
widget_control, help_base, /realize
xmanager, 'atv_help', help_base, /no_block
endif
end
;----------------------------------------------------------------------
pro atv_help_event, event
widget_control, event.id, get_uvalue = uvalue
case uvalue of
'help_done': widget_control, event.top, /destroy
else:
endcase
end
;----------------------------------------------------------------------
pro atv_mapphot_refresh
; Aperture photometry routine by W. Colley, adapted for
; inclusion in ATV by AJB
common atv_state
common atv_images
; coarse center on the star
xmin = (state.cursorpos[0] - ((state.centerboxsize - 1) / 2)) > 0
xmax = (xmin + state.centerboxsize) < (state.image_size[0] - 1)
ymin = (state.cursorpos[1] - ((state.centerboxsize - 1) / 2)) > 0
ymax = (ymin + state.centerboxsize) < (state.image_size[1] - 1)
small_image = main_image[xmin:xmax, ymin:ymax]
nx = (size(small_image))[1]
ny = (size(small_image))[2]
if (total(small_image) EQ 0.) then small_image = small_image + 1.
tt = findgen(nx)#(fltarr(ny)+1)
xcenter = round(total(tt*small_image)/float(total(small_image)))
tt = (fltarr(nx)+1)#findgen(ny)
ycenter = round(total(tt*small_image)/float(total(small_image)))
x = 0 > (xcenter + xmin) < (state.image_size[0] - 1)
y = 0 > (ycenter + ymin) < (state.image_size[1] - 1)
; calculate the sky
xmin = (x - state.outersky) > 0
xmax = (xmin + (2 * state.outersky + 1)) < (state.image_size[0] - 1)
ymin = (y - state.outersky) > 0
ymax = (ymin + (2 * state.outersky + 1)) < (state.image_size[1] - 1)
small_image = main_image[xmin:xmax, ymin:ymax]
nx = (size(small_image))[1]
ny = (size(small_image))[2]
i = lindgen(nx)#(lonarr(ny)+1)
j = (lonarr(nx)+1)#lindgen(ny)
xc = x - xmin
yc = y - ymin
w = where( (((i - xc)^2 + (j - yc)^2) GE state.innersky^2) AND $
(((i - xc)^2 + (j - yc)^2) LE state.outersky^2), nw)
if nw EQ 0 then begin
print, 'No pixels in sky!!!!'
xcent = -1.
ycent = -1.
sky = -1.
flux = -1.
goto, BADSKIP
endif
if nw GT 0 then sky = median(small_image(w))
; do the photometry
mag = 1.
s = size(main_image)
nxi = s[1]
nyi = s[2]
instr = string(0)
nx = ceil(state.r*2.)+4
pi = !pi
twopi = pi*2.
flux = float(x-x)
xcent = flux
ycent = flux
s = size(x)
i = findgen(nx)-float(nx)*0.5
ii0 = i # (i-i+1)
jj0 = (i-i+1) # i
i = (findgen(nx*mag)-(float(nx)*0.5)*mag - mag*0.5 + 0.5) / mag
ii1 = i # (i-i+1)
jj1 = (i-i+1) # i
str = string(0)
xcent = 0.
ycent = 0.
ix = floor(x)
iy = floor(y)
xi = (x-float(ix))
yi = (y-float(iy))
rx = ii0-xi
ry = jj0-yi
mask0 = (rx*rx + ry*ry le (state.r-0.5)^2)
clipmask = (rx*rx + ry*ry le (state.r+0.5)^2)
rx = ii1-xi
ry = jj1-yi
mask1 = (rx*rx + ry*ry le state.r^2)
bm0 = rebin(mask0,nx*mag,nx*mag,/sample)
mask2 = (mask1 eq 1) * (bm0 eq 0)
norm = total(mask1)
ix = floor(x)
iy = floor(y)
i1 = ix-nx/2
i2 = ix+nx/2-1
j1 = iy-nx/2
j2 = iy+nx/2-1
if ((i1 lt state.r) or (i2 gt nxi-state.r-1) or $
(j1 lt state.r) or (j2 gt nyi-state.r-1)) then begin
xcent = -1.
ycent = -1.
flux = -1.
endif else begin
marr_sml = main_image[i1:i2,j1:j2] - sky
marr = marr_sml
t = marr*mask2+rebin(mask0*marr_sml,nx*mag,nx*mag,/sample)
xcent = total(ii1*t)/total(t) + float(i1+nx/2)
ycent = total(jj1*t)/total(t) + float(j1+nx/2)
flux = total(marr_sml*mask0) + total(marr*mask2)
endelse
BADSKIP: begin
end
; output the results
state.centerpos = [xcent, ycent]
tmp_string = string(state.cursorpos[0], state.cursorpos[1], $
format = '("Cursor position: x=",i4," y=",i4)' )
tmp_string1 = string(state.centerpos[0], state.centerpos[1], $
format = '("Object centroid: x=",f6.1," y=",f6.1)' )
tmp_string2 = string(flux, $
format = '("Object counts: ",g12.6)' )
tmp_string3 = string(sky, $
format = '("Sky level: ",g12.6)' )
widget_control, state.centerbox_id, set_value = state.centerboxsize
widget_control, state.cursorpos_id, set_value = tmp_string
widget_control, state.centerpos_id, set_value = tmp_string1
widget_control, state.radius_id, set_value = state.r
widget_control, state.outersky_id, set_value = state.outersky
widget_control, state.innersky_id, set_value = state.innersky
widget_control, state.skyresult_id, set_value = tmp_string3
widget_control, state.photresult_id, set_value = tmp_string2
end
;----------------------------------------------------------------------
pro atv_mapphot_event, event
common atv_state
common atv_images
widget_control, event.id, get_uvalue = uvalue
case uvalue of
'centerbox': begin
state.centerboxsize = long(event.value) > 0
if ( (state.centerboxsize / 2 ) EQ $
round(state.centerboxsize / 2.)) then $
state.centerboxsize = state.centerboxsize + 1
atv_mapphot_refresh
end
'radius': begin
state.r = 1 > long(event.value) < state.innersky
atv_mapphot_refresh
end
'innersky': begin
state.innersky = state.r > long(event.value) < (state.outersky - 1)
atv_mapphot_refresh
end
'outersky': begin
state.outersky = long(event.value) > (state.innersky + 1)
atv_mapphot_refresh
end
'mapphot_done': widget_control, event.top, /destroy
else:
endcase
end
;----------------------------------------------------------------------
pro atv_mapphot
; aperture photometry front end
common atv_state
state.cursorpos = state.mouse
if (not (xregistered('atv_mapphot'))) then begin
mapphot_base = $
widget_base(/floating, $
/base_align_left, $
group_leader = state.base_id, $
/column, $
title = 'atv aperture photometry', $
uvalue = 'mapphot_base')
tmp_string = $
string(1000, 1000, $
format = '("Cursor position: x=",i4," y=",i4)' )
state.cursorpos_id = $
widget_label(mapphot_base, $
value = tmp_string, $
uvalue = 'cursorpos')
state.centerbox_id = $
cw_field(mapphot_base, $
/long, $
/return_events, $
title = 'Centering box size (pix):', $
uvalue = 'centerbox', $
value = state.centerboxsize, $
xsize = 5)
tmp_string1 = $
string(99999.0, 99999.0, $
format = '("Object centroid: x=",f7.1," y=",f7.1)' )
state.centerpos_id = $
widget_label(mapphot_base, $
value = tmp_string1, $
uvalue = 'centerpos')
state.radius_id = $
cw_field(mapphot_base, $
/long, $
/return_events, $
title = 'Aperture radius:', $
uvalue = 'radius', $
value = state.r, $
xsize = 5)
state.innersky_id = $
cw_field(mapphot_base, $
/long, $
/return_events, $
title = 'Inner sky radius:', $
uvalue = 'innersky', $
value = state.innersky, $
xsize = 5)
state.outersky_id = $
cw_field(mapphot_base, $
/long, $
/return_events, $
title = 'Outer sky radius:', $
uvalue = 'outersky', $
value = state.outersky, $
xsize = 5)
tmp_string3 = string(10000000.00, $
format = '("Sky level: ",g12.6)' )
state.skyresult_id = $
widget_label(mapphot_base, $
value = tmp_string3, $
uvalue = 'skyresult')
tmp_string2 = string(1000000000.00, $
format = '("Object counts: ",g12.6)' )
state.photresult_id = $
widget_label(mapphot_base, $
value = tmp_string2, $
uvalue = 'photresult', $
/frame)
mapphot_done = $
widget_button(mapphot_base, $
value = 'Done', $
uvalue = 'mapphot_done')
widget_control, mapphot_base, /realize
xmanager, 'atv_mapphot', mapphot_base, /no_block
endif
atv_mapphot_refresh
end
;----------------------------------------------------------------------
; Main program routine for ATV. If there is no current ATV session,
; then run atv_startup to create the widgets. If ATV already exists,
; then display the new image to the current ATV window.
pro atv, image, $
min = minimum, $
max = maximum, $
autoscale = autoscale, $
linear = linear, $
log = log, $
histeq = histeq
common atv_state
common atv_images
if ( (n_params() EQ 0) AND (xregistered('atv'))) then begin
print, 'USAGE: atv, array_name'
print, ' [,min = min_value] [,max=max_value]'
print, ' [,/autoscale] [,/linear] [,/log] [,/histeq]'
retall
endif
if ( (n_params() NE 0) AND (size(image))[0] NE 2) then begin
print, 'Input data must be a 2-d array!'
retall
endif
if ( (n_params() EQ 0) AND (not (xregistered('atv')))) then begin
main_image = bytscl(dist(500,500)^2 * sin(dist(500,500)/2.)^2)
endif else begin
scaled_image = 0
display_image = 0
main_image = image
endelse
if (not (xregistered('atv'))) then atv_startup
atv_getstats
; check for command line keywords
if n_elements(minimum) GT 0 then begin
state.min_value = minimum
endif
if n_elements(maximum) GT 0 then begin
state.max_value = maximum
endif
if state.min_value GE state.max_value then begin
state.min_value = state.max_value - 1.
endif
atv_set_minmax
if (keyword_set(autoscale)) then atv_autoscale
if (keyword_set(linear)) then state.scaling = 0
if (keyword_set(log)) then state.scaling = 1
if (keyword_set(histeq)) then state.scaling = 2
state.zoom_level = 0
state.zoom_factor = 1.0
atv_displayall
end