; $Id$ ;+ ; NAME: ; EXAMDISPLAY ; ; PURPOSE: ; Object-oriented image display widget for image display and for ; numerical examination via plots and listings. ; ; EXPLANATION: ; These routines set up an object-oriented widget for image display ; and examination. The object orientation is in the programming ; method, not the graphics, which are traditional IDL direct graphics. ; For arguments, see the individual routines below, especially the ; init method, and also imgdisplay__define.pro, which sets up the ; object from which this one inherits. ; ; INHERITS: ; imgdisplay ; ; CATEGORY: ; Widgets. ; ; CALLING SEQUENCE FOR INITIALIZATION: ; new = obj_new('examdisplay', parent, keywords=.....) ; ; ARGUMENT: ; parent: widget ID of parent base widget ; ; KEYWORD INPUTS: ; See imgdisplay__define.pro ; Also there are the following: ; header: Image header ; ; RESTRICTIONS: ; 8-bit displays only. ; ; MODIFICATION HISTORY: ; Written by R. S. Hill, Raytheon ITSS, 4 Aug 99 ; Various upgrades and bugfixes. RSH, 15 Sep 99 ; Add logging of output data. RSH, 21 Mar 2000 ; Square brackets for subscripts. Initial log filename tag ; is an input. RSH, 27 June 2000 ; Destroy help button when exam subwidget morphs. Fixed font ; for dataset listings. RSH, 20 Aug 2000 ; Aperture photometry. Style altered so the you don't have ; to keep pressing the EXAMINE button. More subwidgets ; stay in existence until dismissed. RSH, 31 Aug 2000 ; Aperture growth curve photometry. Whole-image statistics. ; RSH, 6 Sep 2000 ; Fixed small image display in growth curve phot for big ; radii. RSH, 20 Sep 2000 ; /NOEXAMINE added. RSH, 6 Oct 2000 ; Log file changed to printing to standard output. RSH, 8 Nov 2000 ; If logging is on, simple text display widgets are not opened ; and the use must scroll back in the regular text window. ; Logging is turned on at entry. ROI photometry save file ; names differentiated by window number. RSH, 15 Nov 2000 ; XDISPSTR substituted for XDISPLAYFILE. RSH, 17 Nov 2000 ; Corrected attempt to use invalid sexagesimal display. RSH, ; 23 Apr 2004 ;- PRO EXAMDISPLAY::DESTROYBUTTONS, Info ; ; Destroy buttons in exam overview widget when reusing the same ; base (for functions that use current cursor position). ; nml = n_elements((*info).misc_labels) FOR i=0,nml-1 DO widget_control, (*info).misc_labels[i], /destroy RETURN END PRO EXAMDISPLAY::IMLIST, Info ; ; Generate simple 11 X 11 pixel value listing. Uses current cursor ; position. ; ;; self->destroybuttons, info imlist, *self.image, self.xcursor>0, self.ycursor>0, $ textout='_examdisplay_tmp.prt', descrip='EXAMDISPLAY' readstring, '_examdisplay_tmp.prt', strarray widget_control, self.maindisp, get_value=mw IF self.logging THEN BEGIN print, ' ' print, '---------- (X,Y) = (', strn(self.xcursor), ',', $ strn(self.ycursor), ') ------------------------------' $ + '----- Window ' + strn(mw) FOR i=0,n_elements(strarray)-1 DO print, strarray[i] ENDIF ELSE BEGIN title = 'Pixel Listing (Window '+strn(mw)+')' xdispstr, strarray, title=title, $ group=(*info).maintlb, $ font=*self.fixedfont,width=80,height=24 ENDELSE RETURN END PRO EXAMDISPLAY::RSTATS, Info ; ; Generate listing of Tukey's robust statistics, useful for ; getting a handle on outliers. Uses pixels in current zoom box. ; Test for valid subscripts. RSH, 21 Mar 2000 ; ;; self->destroybuttons, info x0 = self.xzstart x1 = self.xzend y0 = self.yzstart y1 = self.yzend IF x0 GE 0 AND x1 GE 0 AND y0 GE 0 AND y1 GE 0 THEN BEGIN rstat, (*self.image)[x0:x1,y0:y1], $ textout='_examdisplay_tmp.prt', descrip='EXAMDISPLAY' readstring, '_examdisplay_tmp.prt', strarray widget_control, self.maindisp, get_value=mw IF self.logging THEN BEGIN print, ' ' print, '---------- (X,Y) = (', strn(x0)+':'+strn(x1), ',', $ strn(y0)+':'+strn(y1), $ ') -------------------------' $ + '---- Window ' + strn(mw) FOR i=0,n_elements(strarray)-1 DO print, strarray[i] ENDIF ELSE BEGIN title = 'Outlier Statistics in Zoom Box (Window '+strn(mw)+')' xdispstr, strarray, title=title, $ group=(*info).maintlb, $ font=*self.fixedfont,width=65,height=25 ENDELSE ENDIF RETURN END PRO EXAMDISPLAY::ALLRSTATS, Info ; ; Generate listing of Tukey's robust statistics, useful for ; getting a handle on outliers. Uses whole image as input. ; RSH, 6 Sep 2000 ; ;; self->destroybuttons, info x0 = self.xzstart x1 = self.xzend y0 = self.yzstart y1 = self.yzend IF ptr_valid(self.image) THEN BEGIN rstat, *self.image, $ textout='_examdisplay_tmp.prt', descrip='EXAMDISPLAY' readstring, '_examdisplay_tmp.prt', strarray widget_control, self.maindisp, get_value=mw IF self.logging THEN BEGIN print, ' ' print, '---------- Whole Image', $ ' ------------------------------' $ + '--------- Window ' + strn(mw) FOR i=0,n_elements(strarray)-1 DO print, strarray[i] ENDIF ELSE BEGIN title = 'Outlier Statistics in Whole Image (Window '+strn(mw)+')' xdispstr, strarray, title=title, $ group=(*info).maintlb, $ font=*self.fixedfont,width=65,height=25 ENDELSE ENDIF RETURN END PRO EXAMDISPLAY::STATS, Info ; ; Generate listing of the usual statistics: mean, std dev, etc. ; Includes a simple little histogram by sigma-sized bins. Uses ; pixels in current zoom box. ; Test for valid subscripts. RSH, 21 Mar 2000 ; ;; self->destroybuttons, info x0 = self.xzstart x1 = self.xzend y0 = self.yzstart y1 = self.yzend IF x0 GE 0 AND x1 GE 0 AND y0 GE 0 AND y1 GE 0 THEN BEGIN qstat, (*self.image)[x0:x1,y0:y1], $ textout='_examdisplay_tmp.prt', descrip='EXAMDISPLAY' readstring, '_examdisplay_tmp.prt', strarray widget_control, self.maindisp, get_value=mw IF self.logging THEN BEGIN print, ' ' print, '---------- (X,Y) = (', strn(x0)+':'+strn(x1), ',', $ strn(y0)+':'+strn(y1), $ ') -------------------------' $ + '---- Window ' + strn(mw) FOR i=0,n_elements(strarray)-1 DO print, strarray[i] ENDIF ELSE BEGIN title = 'Statistics in Zoom Box (Window '+strn(mw)+')' xdispstr, strarray, title=title, $ group=(*info).maintlb, $ font=*self.fixedfont,width=80,height=21 ENDELSE ENDIF RETURN END PRO EXAMDISPLAY::ALLSTATS, Info ; ; Generate listing of the usual statistics: mean, std dev, etc. ; on the whole image. Includes a simple little histogram by ; sigma-sized bins. ; RSH, 6 Sep 2000 ; IF ptr_valid(self.image) THEN BEGIN qstat, *self.image, $ textout='_examdisplay_tmp.prt', descrip='EXAMDISPLAY' readstring, '_examdisplay_tmp.prt', strarray widget_control, self.maindisp, get_value=mw IF self.logging THEN BEGIN print, ' ' print, '---------- Whole Image', $ ' ------------------------------' $ + '--------- Window ' + strn(mw) FOR i=0,n_elements(strarray)-1 DO print, strarray[i] ENDIF ELSE BEGIN title = 'Statistics in Whole Image (Window '+strn(mw)+')' xdispstr, strarray, title=title, $ group=(*info).maintlb, $ font=*self.fixedfont,width=80,height=21 ENDELSE ENDIF RETURN END PRO EXAMDISPLAY::PROFILE2, Event ; ; One of the routines to generate an profile whereby the user clicks ; the endpoints. This one gets the last point and puts up the plot. ; IF event.type NE 0 THEN BEGIN self->xy_sensitive, 'examdisplay::profile2' RETURN ENDIF info = self.popup_info ;; text = widget_info((*info).results, /child) text = (*info).instruc widget_control, text, /destroy ; Code adapted from RSI's profile.pro sz = size(*self.image) sx = sz[1] & sy = sz[2] dx = float(self.xpos-(*info).x0) ;delta x dy = float(self.ypos-(*info).y0) n = abs(dx) > abs(dy) IF n EQ 0 THEN BEGIN junk = dialog_message('Zero length line.') RETURN ENDIF ; r = fltarr(n+1) ; IF abs(dx) GT abs(dy) THEN BEGIN IF self.xpos GE (*info).x0 THEN s=1 ELSE s=-1 sy = (self.ypos-(*info).y0)/abs(dx) ENDIF ELSE BEGIN IF self.ypos GE (*info).y0 THEN sy=1 ELSE sy=-1 s = (self.xpos-(*info).x0)/abs(dy) ENDELSE ; xx = long(findgen(n+1l)*s+(*info).x0) ;X values, make into longwords. yy = long(findgen(n+1l)*sy+(*info).y0) ;Y values pp = (*self.image)[long(yy)*sx + xx] pd = sqrt((xx-xx[0])^2 + (yy-yy[0])^2) n_e = n_elements(xx) xtitle='Relative Pixel Distance' ytitle='Pixel Value' title='['+strn(xx[0])+','+strn(yy[0])+'] - ' $ +'['+strn(xx[n_e-1])+','+strn(yy[n_e-1])+']' widget_control, self.maindisp, get_value=mw wtitle = 'Profile (Window '+strn(mw)+')' adjplot, pd, pp, top_id=top_id, group_leader=(*info).maintlb, $ wtitle=wtitle, title=title, ytitle=ytitle, xtitle=xtitle, $ charsize=1 wset, (*info).maingraph device, copy=[0, 0, $ self.xzend-self.xzstart+1, $ self.yzend-self.yzstart+1, $ self.xzstart, self.yzstart, $ self.main_shad] plots, self.xpos, self.ypos, psym=1, symsize=1, /dev, $ color=self.boxcolor plots, [(*info).x0,self.xpos],[(*info).y0,self.ypos], /dev, $ color=self.boxcolor wset, self.main_shad device, copy=[self.xzstart,self.yzstart,self.xzend-self.xzstart+1, $ self.yzend-self.yzstart+1,0,0,(*info).maingraph] ;; widget_control, (*info).tlb, /destroy RETURN END PRO EXAMDISPLAY::PROFILE1, Event ; ; One of the routines to generate an profile whereby the user clicks ; the endpoints. This one gets the first point and sets up to get the ; second point. ; IF event.type NE 0 THEN RETURN info = self.popup_info (*info).x0 = self.xpos (*info).y0 = self.ypos widget_control, self.maindisp, get_value=maingraph wset, maingraph device, copy=[0, 0, $ self.xzend-self.xzstart+1, $ self.yzend-self.yzstart+1, $ self.xzstart, self.yzstart, $ self.main_shad] (*info).maingraph = maingraph plots, (*info).x0, (*info).y0, psym=1, symsize=1, /dev, $ color=self.boxcolor wset, self.main_shad device, copy=[self.xzstart,self.yzstart,self.xzend-self.xzstart+1, $ self.yzend-self.yzstart+1,0,0,(*info).maingraph] self->xy_sensitive, 'examdisplay::profile2' RETURN END PRO EXAMDISPLAY::PROFILE, Info ; ; One of the routines to plot an interactive profile whereby the ; user clicks on the endpoints. This one sets up to get the first ; point. ; ;; self->destroybuttons, info self->xy_sensitive, 'examdisplay::profile1' instruc = [ $ 'Click on each end of the profile in turn', $ 'in either the zoom or the main window.'] IF widget_info((*info).instruc,/valid) THEN $ widget_control, (*info).instruc, /destroy base = widget_base(group=(*info).maintlb,col=1) junk = widget_text(base, value=instruc, xsize=42, ysize=2, $ font=*self.fixedfont) (*info).instruc = base widget_control, base, /realize ;; text = widget_text((*info).results, value=instruc, xsize=42, ysize=2) RETURN END PRO EXAMDISPLAY::ROWCOL_TOTAL, Rc, X0, Y0, Wid, Xx, Tot, TITLE=title ; ; Totals up a strip of rows or columns. ; ; Input Positional Parameters: ; Rc: 0 for rows or 1 for columns. ; X0, Y0: Position of cursor. ; Wid: Width of strip in pixels. ; Output Positional Parameters: ; Xx: Abscissa vector giving pixel number. ; Tot: Total of wid rows or columns. ; Output Keyword Parameter: ; TITLE: Plot title. ; sz = size(*self.image) xdim = sz[1] & ydim = sz[2] IF rc EQ 0 THEN BEGIN xx = indgen(xdim) y1 = ((y0 - long(wid/2.0))>0)<(ydim-1) y2 = ((y1 + long(wid) - 1)>y1)<(ydim-1) IF y1 NE y2 THEN tot = total((*self.image)[*, y1:y2], 2) $ ELSE tot = (*self.image)[*, y1:y2] title = 'Rows ' + strn(y1) + ':' + strn(y2) ENDIF ELSE BEGIN xx = indgen(ydim) x1 = ((x0 - long(wid/2.0))>0)<(xdim-1) x2 = ((x1 + long(wid) - 1)>x1)<(xdim-1) IF x1 NE x2 THEN tot = total((*self.image)[x1:x2, *], 1) $ ELSE tot = transpose((*self.image)[x1:x2, *]) title = 'Cols ' + strn(x1) + ':' + strn(x2) ENDELSE RETURN END PRO EXAMDISPLAY_ROWCOL_CLEANUP, Tlb ; ; Deallocates info structure from row/column plot subwidget. ; widget_control, tlb, get_uvalue=info IF ptr_valid(info) THEN ptr_free, info RETURN END PRO EXAMDISPLAY::ROWCOL_EVENT, Event, Pinfo ; ; Object event handler for row/column plot widget. Called by ; widget event handler. ; widget_control, (*pinfo).width_text, get_value=wstring wid = long(wstring[0]) widget_control, (*pinfo).rowcol_bgroup, get_value=rc IF rc THEN BEGIN ; ; Column sum. right = (*pinfo).xdim-(*pinfo).x0 left = (*pinfo).x0 ; ; Compute maximum allowed width of strip. IF left LE right THEN BEGIN maxw = left * 2 ENDIF ELSE BEGIN maxw = (right-1)*2 + 1 ENDELSE ENDIF ELSE BEGIN ; ; Row sum. top = (*pinfo).ydim-(*pinfo).y0 bot = (*pinfo).y0 ; ; Compute maximum allowed width of strip. IF bot LE top THEN BEGIN maxw = bot * 2 ENDIF ELSE BEGIN maxw = (top-1)*2 + 1 ENDELSE ENDELSE yrel = 0b CASE event.id OF (*pinfo).width_text: BEGIN ; ; User has enter a width using text. text_number, (*pinfo).width_text, wid, /long, $ minv=1, maxv=maxw yrel = 1b END (*pinfo).incr_button: BEGIN ; ; User has incremented width with button. wid = (wid + 1)1 widget_control, (*pinfo).width_text, set_value=strn(wid) yrel = 1b END ELSE: wid = (wid>1)rowcol_total, rc, (*pinfo).x0, (*pinfo).y0, wid, xx, tot, $ title=title ; ; Replot. adjplot_replot, (*pinfo).plot_id, xx, tot, title=title, $ /xstatic, yrel=yrel, charsize=1 RETURN END PRO EXAMDISPLAY_ROWCOL_EVENT, Event ; ; Widget event handler for row/column plot widget. Calls ; object event handler. ; widget_control, event.top, get_uvalue=pinfo (*pinfo).this->rowcol_event, event, pinfo RETURN END PRO EXAMDISPLAY::ROWCOL, Info ; ; Generates row/column plot subwidget. ; (*info).x0 = self.xcursor (*info).y0 = self.ycursor sz = size(*self.image) xdim = sz[1] & ydim = sz[2] widget_control, self.maindisp, get_value=mw wtitle = 'Row/Column Plot (Window '+strn(mw)+')' tlb = widget_base(/col, title=wtitle, group=(*info).maintlb) row1 = widget_base(tlb, /row) rowcol_bgroup = cw_bgroup(row1, ['ROW','COLUMN'], set_value=0, $ /no_rel, /exclusive, /row) width_label = widget_label(row1, value='Width:') width_text = widget_text(row1, xsize=6, value='1', /editable) incr_button = widget_button(row1, value='+1', /no_rel) decr_button = widget_button(row1, value='-1', /no_rel) self->rowcol_total, 0, (*info).x0, (*info).y0, 1, xx, tot, $ title=title adjplot, xx, tot, top_id=plot_id, base_id=tlb, title=title, $ charsize=1 popup_info = ptr_new({tlb:tlb, plot_id:plot_id, $ this:(*info).this, x0:(*info).x0, $ y0:(*info).y0, $ xdim:xdim, ydim:ydim, $ rowcol_bgroup:rowcol_bgroup, $ width_text:width_text, incr_button:incr_button, $ decr_button:decr_button}) widget_control, tlb, set_uvalue=popup_info xmanager, 'examdisplay_rowcol', tlb, $ event_handler='examdisplay_rowcol_event', $ cleanup='examdisplay_rowcol_cleanup', /no_block ;; widget_control, (*info).tlb, /destroy RETURN END PRO EXAMDISPLAY_ROIPHOT_CLEANUP, Tlb ; ; Deallocates info structure for r.o.i. photometry subwidget. ; widget_control, tlb, get_uvalue=info IF ptr_valid((*info).sky_roi) THEN ptr_free, (*info).sky_roi IF ptr_valid((*info).obj_roi) THEN ptr_free, (*info).obj_roi IF ptr_valid(info) THEN ptr_free, info RETURN END PRO EXAMDISPLAY::ROIPHOT_EVENT, Event, Pinfo ; ; Event handler for region-of-interest photometry. ; destroy=0b change=0b CASE event.id OF (*pinfo).meas_sky_button: BEGIN widget_control, (*pinfo).msg_text, $ set_value='Define sky region' IF ptr_valid((*pinfo).sky_roi) THEN $ ptr_free,(*pinfo).sky_roi self->id, drawid (*pinfo).sky_roi $ = ptr_new(cw_defroi2(drawid,$ image_size=[(*pinfo).xdim, (*pinfo).ydim], $ group_leader=event.top,/floating)) widget_control, (*pinfo).msg_text, $ set_value='Just measured a sky region' change=1b END (*pinfo).meas_obj_button: BEGIN widget_control, (*pinfo).msg_text, $ set_value='Define object' IF ptr_valid((*pinfo).obj_roi) THEN $ ptr_free,(*pinfo).obj_roi self->id, drawid (*pinfo).obj_roi $ = ptr_new(cw_defroi2(drawid,$ image_size=[(*pinfo).xdim, (*pinfo).ydim], $ group_leader=event.top,/floating)) widget_control, (*pinfo).msg_text, $ set_value='Just measured an object' change=1b END (*pinfo).save_button: BEGIN widget_control, (*pinfo).object_text, get_value=tmp objtot = float(tmp[0]) widget_control, (*pinfo).sky_text, get_value=tmp skyavg = float(tmp[0]) widget_control, (*pinfo).objsky_text, get_value=tmp objsky = float(tmp[0]) widget_control, (*pinfo).net_text, get_value=tmp objnet = float(tmp[0]) widget_control, (*pinfo).avnet_text, get_value=tmp avobjnet = float(tmp[0]) widget_control, (*pinfo).save_text, get_value=savetag self.log_count = self.log_count + 1 log_count = self.log_count sky_roi = *(*pinfo).sky_roi obj_roi = *(*pinfo).obj_roi save_filename = 'save_' + savetag[0] + '_' + strn(log_count) $ + '.idl' save, log_count, objtot, skyavg, $ objsky, objnet, avobjnet, $ sky_roi, obj_roi, $ file=save_filename msg = 'SAVED IN ' + save_filename widget_control, (*pinfo).msg_text, set_value=msg widget_control, self.maindisp, get_value=maingraph print, ' ' print, '----------------------', $ '-------------------------------' $ + '--------- Window ' + strn(maingraph) print, 'R.O.I. Photometry' print, msg sky_roi = 0 obj_roi = 0 END (*pinfo).quit_button: BEGIN destroy=1b END ELSE: ENDCASE valid_obj = 0b valid_sky = 0b IF ptr_valid((*pinfo).obj_roi) THEN BEGIN IF (*(*pinfo).obj_roi)[0] NE -1 THEN valid_obj = 1b ENDIF IF ptr_valid((*pinfo).sky_roi) THEN BEGIN IF (*(*pinfo).sky_roi)[0] NE -1 THEN valid_sky = 1b ENDIF IF change THEN BEGIN IF valid_obj THEN BEGIN objtot = total((*self.image)[*(*pinfo).obj_roi]) nobjpix = n_elements(*(*pinfo).obj_roi) ENDIF ELSE BEGIN objtot = 0 nobjpix = 0L ENDELSE IF valid_sky THEN BEGIN nskypix = n_elements(*(*pinfo).sky_roi) skyavg = total((*self.image)[*(*pinfo).sky_roi]) $ / nskypix objsky = skyavg*nobjpix ENDIF ELSE BEGIN skyavg = 0 objsky = 0 nskypix = 0 ENDELSE objnet = objtot - objsky IF nobjpix GT 0 THEN avobjnet = objnet/nobjpix ELSE avobjnet = 0 IF valid_obj AND (NOT destroy) THEN BEGIN multi_sub, [(*pinfo).xdim, (*pinfo).ydim], *(*pinfo).obj_roi, xyroi avx = mean(xyroi[*,0]) avy = mean(xyroi[*,1]) IF self.logging THEN BEGIN widget_control, self.maindisp, get_value=maingraph print, ' ' print, '----------------------', $ '-------------------------------' $ + '--------- Window ' + strn(maingraph) print, 'R.O.I. Photometry' print, 'Mean X of object = ',avx print, 'Mean Y of object = ',avy print, 'Number of obj pixels = ',nobjpix print, 'Number of sky pixels = ',nskypix print, 'Object total = ',objtot print, 'Sky average = ',skyavg print, 'Sky in object = ',objsky print, 'Net in object = ',objnet print, 'Average net in object = ',avobjnet ENDIF ENDIF widget_control, (*pinfo).object_text, set_value=strn(objtot) widget_control, (*pinfo).sky_text, set_value=strn(skyavg) widget_control, (*pinfo).objsky_text, set_value=strn(objsky) widget_control, (*pinfo).net_text, set_value=strn(objnet) widget_control, (*pinfo).avnet_text, set_value=strn(avobjnet) ENDIF IF destroy THEN widget_control, event.top, /destroy RETURN END PRO EXAMDISPLAY_ROIPHOT_EVENT, Event widget_control, event.top, get_uvalue=pinfo (*pinfo).this->roiphot_event, event, pinfo RETURN END PRO EXAMDISPLAY::ROIPHOT, Info ; ; Popup for region-of-interest photometry. ; (*info).x0 = self.xcursor (*info).y0 = self.ycursor sz = size(*self.image) xdim = sz[1] & ydim = sz[2] widget_control, self.maindisp, get_value=mw wtitle = 'ROI Photometry (Window '+strn(mw)+')' tlb = widget_base(/col, title=wtitle, group=(*info).maintlb, /floating) row2 = widget_base(tlb, /row) row3 = widget_base(tlb, /row) row4 = widget_base(tlb, /row) row5 = widget_base(tlb, /row) row6 = widget_base(tlb, /row) row7 = widget_base(tlb, /row) row8 = widget_base(tlb, /row) row9 = widget_base(tlb, /row) sky_label = widget_label(row2, value='Sky average:') sky_text = widget_text(row2, xsize=20, value='0') object_label = widget_label(row3, value='Object total:') object_text = widget_text(row3, xsize=20, value='0') objsky_label = widget_label(row4, value='Sky in object:') objsky_text = widget_text(row4, xsize=20, value='0') net_label = widget_label(row5, value='Net in object:') net_text = widget_text(row5, xsize=20, value='0') avnet_label = widget_label(row6, value='Mean net in object:') avnet_text = widget_text(row6, xsize=20, value='0') meas_sky_button = widget_button(row7, value='Measure sky', /no_rel) meas_obj_button = widget_button(row7, value='Measure object', /no_rel) msg_text = widget_text(row8, xsize=30,ysize=1) save_lab = widget_label(row9, value='Save Tag:') svtag = 'roiph' + strn(mw[0]) save_text = widget_text(row9, xsize=10,ysize=1, value=svtag, /edit) save_button = widget_button(row9, value='Save Data', /no_rel) quit_button = widget_button(row9, value='DISMISS', /no_rel) widget_control, tlb, /realize popup_info = ptr_new({tlb:tlb, $ this:(*info).this, $ xdim:xdim, ydim:ydim, $ sky_text:sky_text, $ object_text:object_text, $ objsky_text:objsky_text, $ net_text:net_text, $ avnet_text:avnet_text, $ meas_sky_button:meas_sky_button, $ meas_obj_button:meas_obj_button, $ save_button:save_button, $ save_text:save_text, $ quit_button:quit_button, $ msg_text:msg_text, $ sky_roi:ptr_new(), $ obj_roi:ptr_new() }) widget_control, tlb, set_uvalue=popup_info xmanager, 'examdisplay_roiphot', tlb, $ event_handler='examdisplay_roiphot_event', $ cleanup='examdisplay_roiphot_cleanup', /no_block ;; widget_control, (*info).tlb, /destroy RETURN END PRO EXAMDISPLAY_APERGROWTH_CLEANUP, Tlb ; ; Deallocates info structure for r.o.i. photometry subwidget. ; widget_control, tlb, get_uvalue=info IF ptr_valid(info) THEN ptr_free, info RETURN END PRO EXAMDISPLAY::APERGROWTH_EVENT, Event, Pinfo ; ; Event handler for aperture photometry. ; destroy=0b IF event.id EQ (*pinfo).curs_button THEN BEGIN widget_control, (*pinfo).x_text, $ set_value=strn(self.xcursor,format='(F10.2)') widget_control, (*pinfo).y_text, $ set_value=strn(self.ycursor,format='(F10.2)') ENDIF IF event.id EQ (*pinfo).cntrd_button $ OR event.id EQ (*pinfo).cntrd_text THEN BEGIN text_number, (*pinfo).cntrd_text, cbox, format='(F10.2)' text_number, (*pinfo).x_text, xcoo, format='(F10.2)' text_number, (*pinfo).y_text, ycoo, format='(F10.2)' cntrd, *self.image, xcoo, ycoo, xcen, ycen, (cbox-1)/(0.637*2) IF xcen GT 0 AND ycen GE 0 THEN BEGIN xcoo=xcen ycoo=ycen ENDIF widget_control, (*pinfo).x_text, set_value=strn(xcoo,format='(F10.2)') widget_control, (*pinfo).y_text, set_value=strn(ycoo,format='(F10.2)') ENDIF IF event.id EQ (*pinfo).cntrd_button $ OR event.id EQ (*pinfo).cntrd_text $ OR event.id EQ (*pinfo).x_text $ OR event.id EQ (*pinfo).y_text $ OR event.id EQ (*pinfo).minrad_text $ OR event.id EQ (*pinfo).curs_button $ OR event.id EQ (*pinfo).badmax $ OR event.id EQ (*pinfo).badmin $ OR event.id EQ (*pinfo).gain $ OR event.id EQ (*pinfo).fskyval $ OR event.id EQ (*pinfo).iskyann $ OR event.id EQ (*pinfo).oskyann THEN BEGIN text_number, (*pinfo).iskyann, sky1, format='(F10.2)' text_number, (*pinfo).oskyann, sky2, format='(F10.2)' text_number, (*pinfo).minrad_text, minrad, format='(F10.2)' text_number, (*pinfo).gain, gain, format='(F10.2)' text_number, (*pinfo).badmin, badmin, format='(G15.7)' text_number, (*pinfo).badmax, badmax, format='(G15.7)' text_number, (*pinfo).x_text, xcoo, format='(F10.2)' text_number, (*pinfo).y_text, ycoo, format='(F10.2)' force_sky = 0 widget_control, (*pinfo).fskyval, get_value=fskyval fskytrim = strtrim(fskyval[0],2) If fskytrim NE '' THEN BEGIN text_number, (*pinfo).fskyval, fsky, format='(E20.7)' force_sky = 1 ENDIF widget_control, (*pinfo).fskyval, get_value=fskyval fskytrim = strtrim(fskyval[0],2) IF fskytrim EQ '' THEN fskytrim = 'none' sz = size(*self.image) xdim = sz[1] & ydim = sz[2] half = round(1.1*max([sky1,sky2,minrad])) x0 = (round(xcoo)-half)>0 x1 = (round(xcoo)+half-1)<(xdim-1) y0 = (round(ycoo)-half)>0 y1 = (round(ycoo)+half-1)<(ydim-1) xdim2 = x1-x0+1 ydim2 = y1-y0+1 dsz = float((*pinfo).dispsize) fac = min(dsz/[xdim2,ydim2]) xredim = round(xdim2*fac) & yredim = round(ydim2*fac) (*pinfo).objdisp->resize, xytotal=[xredim, yredim] (*pinfo).objdisp->draw, frebin((*self.image)[x0:x1,y0:y1],xredim,yredim) svwin = !D.window wset,(*pinfo).gwin xcen = (xcoo-x0+0.5)*fac - 0.5 ycen = (ycoo-y0+0.5)*fac - 0.5 tvcircle, fac*sky1, xcen, ycen, color=self.boxcolor, thick=2 tvcircle, fac*sky2, xcen, ycen, color=self.boxcolor, thick=2 IF svwin GE 0 THEN wset, svwin skyvec = [sky1sky2] IF skyvec[1] LE skyvec[0] THEN skyvec[1] = skyvec[0] + 1 widget_control, (*pinfo).iskyann, set_value=strn(skyvec[0],form='(F10.2)') widget_control, (*pinfo).oskyann, set_value=strn(skyvec[1],form='(F10.2)') badvec = [badminbadmax] grorad = indgen(minrad>(skyvec[1]+1))+1 skyvecx = skyvec aper, *self.image, xcoo, ycoo, mags, $ errap, sky, skyerrx, gain, grorad, skyvecx, badvec, $ /exact, /flux, /silent, setskyval=0 wsky = where(grorad GE skyvec[0] AND grorad LE skyvec[1], nsky) npix = !DPI*grorad^2 coeff = linfit(npix[wsky], mags[wsky]) IF fskytrim EQ 'none' THEN BEGIN skyval = coeff[1] ENDIF ELSE BEGIN skyval = float(fskytrim) ENDELSE magscorr = mags - npix*skyval wset, (*pinfo).plot1 nm = n_elements(mags) sb = (mags[1:nm-1]-mags[0:nm-2])/(npix[1:nm-1]-npix[0:nm-2]) sb = [mags[0]/npix[0], sb] plot, grorad, sb>(max(sb)/1e5), xtitle='Outer Radius', $ ytitle='Surface Brightness', $ title=' ', /ynoz oplot, [skyvec[0],skyvec[0]], !y.crange, line=2 oplot, [skyvec[1],skyvec[1]], !y.crange, line=2 wset, (*pinfo).plot2 plot, grorad, magscorr, xtitle='Radius', ytitle='Net', title=' ' oplot, [skyvec[0],skyvec[0]], !y.crange, line=2 oplot, [skyvec[1],skyvec[1]], !y.crange, line=2 nn = max(where(grorad LE skyvec[0])) IF nn GE 0 THEN BEGIN objnet = magscorr[nn] skyvecx = skyvec aper, *self.image, xcoo, ycoo, mags2, $ errap2, sky2, skyerr2, gain, grorad[nn], skyvecx, badvec, $ /exact, /flux, /silent skyerr = skyerr2[0] objerr = errap2[0] ENDIF ELSE BEGIN objnet = -1 objerr = -1 skyerr = -1 ENDELSE widget_control, (*pinfo).object_text, set_value=strn(objnet) widget_control, (*pinfo).sky_text, set_value=strn(skyval) widget_control, (*pinfo).objerr_text, set_value=strn(objerr) widget_control, (*pinfo).skyerr_text, set_value=strn(skyerr) log_count = self.log_count IF self.logging THEN BEGIN widget_control, self.maindisp, get_value=maingraph print, ' ' print, '----------------------', $ '-------------------------------' $ + '--------- Window ' + strn(maingraph) print, 'APERTURE GROWTH PHOTOMETRY' print, 'X coordinate = ',xcoo print, 'Y coordinate = ',ycoo print, 'Inner sky radius = ',skyvec[0] print, 'Outer sky radius = ',skyvec[1] print, 'Bad pixel limit (low) = ',badvec[0] print, 'Bad pixel limit (high) = ',badvec[1] print, 'Gain (PHPADU) = ',gain print, 'Object net = ',objnet print, 'Error in object net = ',objerr print, 'Sky average = ',skyval print, 'Error in sky average = ',skyerr ENDIF ENDIF IF event.id EQ (*pinfo).quit_button THEN BEGIN destroy=1b ENDIF IF destroy THEN widget_control, event.top, /destroy RETURN END PRO EXAMDISPLAY_APERGROWTH_EVENT, Event widget_control, event.top, get_uvalue=pinfo (*pinfo).this->apergrowth_event, event, pinfo RETURN END PRO EXAMDISPLAY::APERGROWTH, Info ; ; Popup for aperture photometry. ; dispsize = 200 widget_control, self.maindisp, get_value=mw wtitle = 'Aperture Growth Photometry (Window '+strn(mw)+')' tlb = widget_base(/row, title=wtitle, group=(*info).maintlb, floating=0) col1 = widget_base(tlb, /col) col2 = widget_base(tlb, /col) rowy = widget_base(col1, /row) rowz = widget_base(col1, /row) rowa = widget_base(col1, /row) rowb = widget_base(col1, /row) rowb1 = widget_base(col1, /row) rowc = widget_base(col1, /row) rowc1 = widget_base(col1, /row) rowc2 = widget_base(col1, /row) rowd = widget_base(col1, /row) x_label = widget_label(rowy, value='X:') x_text = widget_text(rowy, xsize=8, value=strn(self.xcursor), /edit) y_label = widget_label(rowy, value='Y:') y_text = widget_text(rowy, xsize=8, value=strn(self.ycursor), /edit) curs_button = widget_button(rowy, value='READ CURSOR', /no_rel) cntrd_button = widget_button(rowz, value='ADJUST CENTROID', /no_rel) cntrd_label = widget_label(rowz, value='using box size = ') cntrd_text = widget_text(rowz, xsize=8, value='7', /edit) oskyann_label = widget_label(rowb, value='Sky Radii [px]:') iskyann = widget_text(rowb, xsize=8, value='15', /edit) oskyann = widget_text(rowb, xsize=8, value='20', /edit) minrad_label = widget_label(rowb1, value='Outermost Radius (minimum) [px]:') minrad_text = widget_text(rowb1, xsize=8, value='25', /edit) fsky_label = widget_label(rowc, value='Force Sky Value: ') fskyval = widget_text(rowc, xsize=15, value=' ',/edit) gain_label = widget_label(rowc1, value='Gain [e- per ADU]:') IF ptr_valid(self.header) THEN BEGIN par = strmid(*self.header, 0, 8) gainpar = where(strpos(par, 'GAIN') GE 0 $ OR strpos(par, 'PHPADU') GE 0, npar) gval = 1.0 kk=npar WHILE kk GT 0 DO BEGIN kk = kk - 1 useg = par[gainpar[kk]] gval2 = sxpar(*self.header, useg) IF gval2 GT 0 THEN BEGIN kk=-1 gval = gval2 ENDIF ENDWHILE ENDIF ELSE gval = 1.0 gain = widget_text(rowc1, xsize=12, value=strn(gval), /edit) badmin_label = widget_label(rowc2, value='Bad pixel limits:') badmin = widget_text(rowc2, value='-32765', xsize=12, /edit) badmax = widget_text(rowc2, value='32767', xsize=12, /edit) objdisp = obj_new('IMGDISPLAY', rowd, xsize=dispsize, ysize=dispsize, $ /ps_dialog) objdisp->psfile, '_examdisplay_aper.ps', 'APERTURE GROWTH PHOTOMETRY' row3 = widget_base(col1, /row) row4 = widget_base(col1, /row) row5 = widget_base(col1, /row) col6 = widget_base(col1, /col) object_label = widget_label(row3, value='Object net:') object_text = widget_text(row3, xsize=10, value='0', /edit) objerr_label = widget_label(row3, value='Error:') objerr_text = widget_text(row3, xsize=10, value='0') sky_label = widget_label(row4, value='Sky:') sky_text = widget_text(row4, xsize=10, value='0') skyerr_label = widget_label(row4, value='Error:') skyerr_text = widget_text(row4, xsize=10, value='0') quit_button = widget_button(row5, value='DISMISS', /no_rel) plot1_draw = widget_draw(col2, xsize=300, ysize=300) plot2_draw = widget_draw(col2, xsize=300, ysize=300) widget_control, tlb, /realize widget_control, plot1_draw, get_value=plot1 widget_control, plot2_draw, get_value=plot2 objdisp->id, mainid widget_control, mainid, get_value=gwin popup_info = ptr_new({tlb:tlb, $ this:(*info).this, $ x_text:x_text, $ y_text:y_text, $ curs_button:curs_button, $ cntrd_button:cntrd_button, $ cntrd_text:cntrd_text, $ oskyann:oskyann, $ iskyann:iskyann, $ minrad_text:minrad_text, $ fskyval:fskyval, $ gain:gain, $ badmin:badmin, $ badmax:badmax, $ objdisp:objdisp, $ dispsize:dispsize, $ gwin:gwin, $ object_text:object_text, $ objerr_text:objerr_text, $ sky_text:sky_text, $ skyerr_text:skyerr_text, $ plot1_draw:plot1_draw, $ plot2_draw:plot2_draw, $ plot1:plot1, $ plot2:plot2, $ quit_button:quit_button }) widget_control, tlb, set_uvalue=popup_info xmanager, 'examdisplay_apergrowth', tlb, $ event_handler='examdisplay_apergrowth_event', $ cleanup='examdisplay_apergrowth_cleanup', /no_block pseudo = {id:oskyann, top:tlb, handler:tlb} widget_control, oskyann, send_event=pseudo RETURN END PRO EXAMDISPLAY_APERPHOT_CLEANUP, Tlb ; ; Deallocates info structure for r.o.i. photometry subwidget. ; widget_control, tlb, get_uvalue=info IF ptr_valid(info) THEN ptr_free, info RETURN END PRO EXAMDISPLAY::APERPHOT_EVENT, Event, Pinfo ; ; Event handler for aperture photometry. ; destroy=0b IF event.id EQ (*pinfo).curs_button THEN BEGIN widget_control, (*pinfo).x_text, $ set_value=strn(self.xcursor,format='(F10.2)') widget_control, (*pinfo).y_text, $ set_value=strn(self.ycursor,format='(F10.2)') ENDIF IF event.id EQ (*pinfo).cntrd_button $ OR event.id EQ (*pinfo).cntrd_text THEN BEGIN text_number, (*pinfo).cntrd_text, cbox, format='(F10.2)' text_number, (*pinfo).x_text, xcoo, format='(F10.2)' text_number, (*pinfo).y_text, ycoo, format='(F10.2)' cntrd, *self.image, xcoo, ycoo, xcen, ycen, (cbox-1)/(0.637*2) IF xcen GT 0 AND ycen GE 0 THEN BEGIN xcoo=xcen ycoo=ycen ENDIF widget_control, (*pinfo).x_text, set_value=strn(xcoo,format='(F10.2)') widget_control, (*pinfo).y_text, set_value=strn(ycoo,format='(F10.2)') ENDIF IF event.id EQ (*pinfo).cntrd_button $ OR event.id EQ (*pinfo).cntrd_text $ OR event.id EQ (*pinfo).x_text $ OR event.id EQ (*pinfo).y_text $ OR event.id EQ (*pinfo).curs_button $ OR event.id EQ (*pinfo).objrad $ OR event.id EQ (*pinfo).badmax $ OR event.id EQ (*pinfo).badmin $ OR event.id EQ (*pinfo).gain $ OR event.id EQ (*pinfo).fskyval $ OR event.id EQ (*pinfo).iskyann $ OR event.id EQ (*pinfo).oskyann THEN BEGIN text_number, (*pinfo).iskyann, sky1, format='(F10.2)' text_number, (*pinfo).oskyann, sky2, format='(F10.2)' text_number, (*pinfo).objrad, objr, format='(F10.2)' text_number, (*pinfo).gain, gain, format='(F10.2)' text_number, (*pinfo).badmin, badmin, format='(G15.7)' text_number, (*pinfo).badmax, badmax, format='(G15.7)' text_number, (*pinfo).x_text, xcoo, format='(F10.2)' text_number, (*pinfo).y_text, ycoo, format='(F10.2)' force_sky = 0 widget_control, (*pinfo).fskyval, get_value=fskyval fskytrim = strtrim(fskyval[0],2) If fskytrim NE '' THEN BEGIN text_number, (*pinfo).fskyval, fsky, format='(E20.7)' force_sky = 1 ENDIF widget_control, (*pinfo).fskyval, get_value=fskyval fskytrim = strtrim(fskyval[0],2) IF fskytrim EQ '' THEN fskytrim = 'none' sz = size(*self.image) xdim = sz[1] & ydim = sz[2] half = round(1.1*max([sky1,sky2,objr])) x0 = (round(xcoo)-half)>0 x1 = (round(xcoo)+half-1)<(xdim-1) y0 = (round(ycoo)-half)>0 y1 = (round(ycoo)+half-1)<(ydim-1) xdim2 = x1-x0+1 ydim2 = y1-y0+1 fac = floor(min(float((*pinfo).dispsize/[xdim2,ydim2]))) xredim = xdim2*fac yredim = ydim2*fac (*pinfo).objdisp->resize, xytotal=[xredim, yredim] (*pinfo).objdisp->draw, frebin((*self.image)[x0:x1,y0:y1],xredim,yredim) svwin = !D.window wset,(*pinfo).gwin xcen = (xcoo-x0+0.5)*fac - 0.5 ycen = (ycoo-y0+0.5)*fac - 0.5 tvcircle, fac*objr, xcen, ycen, color=self.boxcolor, thick=2 tvcircle, fac*sky1, xcen, ycen, color=self.boxcolor, thick=2 tvcircle, fac*sky2, xcen, ycen, color=self.boxcolor, thick=2 IF svwin GE 0 THEN wset, svwin skyvec = [sky1sky2] badvec = [badminbadmax] IF force_sky THEN BEGIN aper, *self.image, xcoo, ycoo, mags, $ errap, sky, skyerr, gain, objr, skyvec, badvec, $ /exact, /flux, /silent, setskyval=fsky ENDIF ELSE BEGIN aper, *self.image, xcoo, ycoo, mags, $ errap, sky, skyerr, gain, objr, skyvec, badvec, $ /exact, /flux, /silent ENDELSE widget_control, (*pinfo).object_text, set_value=strn(mags[0]) widget_control, (*pinfo).sky_text, set_value=strn(sky[0]) widget_control, (*pinfo).objerr_text, set_value=strn(errap[0]) widget_control, (*pinfo).skyerr_text, set_value=strn(skyerr[0]) log_count = self.log_count IF self.logging THEN BEGIN widget_control, self.maindisp, get_value=maingraph print, ' ' print, '----------------------', $ '-------------------------------' $ + '--------- Window ' + strn(maingraph) print, 'APERTURE PHOTOMETRY' print, 'X coordinate = ',xcoo print, 'Y coordinate = ',ycoo print, 'Object radius = ',objr print, 'Inner sky radius = ',skyvec[0] print, 'Outer sky radius = ',skyvec[1] print, 'Bad pixel limit (low) = ',badvec[0] print, 'Bad pixel limit (high) = ',badvec[1] print, 'Gain (PHPADU) = ',gain print, 'Object net = ',mags[0] print, 'Error in object net = ',errap[0] print, 'Sky average = ',sky[0] print, 'Error in sky average = ',skyerr[0] ENDIF ENDIF IF event.id EQ (*pinfo).quit_button THEN BEGIN destroy=1b ENDIF IF destroy THEN widget_control, event.top, /destroy RETURN END PRO EXAMDISPLAY_APERPHOT_EVENT, Event widget_control, event.top, get_uvalue=pinfo (*pinfo).this->aperphot_event, event, pinfo RETURN END PRO EXAMDISPLAY::APERPHOT, Info ; ; Popup for aperture photometry. ; dispsize = 200 widget_control, self.maindisp, get_value=mw wtitle = 'Aperture Photometry (Window '+strn(mw)+')' tlb = widget_base(/col, title=wtitle, group=(*info).maintlb, floating=0) rowy = widget_base(tlb, /row) rowz = widget_base(tlb, /row) rowa = widget_base(tlb, /row) rowb = widget_base(tlb, /row) rowc = widget_base(tlb, /row) rowc1 = widget_base(tlb, /row) rowc2 = widget_base(tlb, /row) rowd = widget_base(tlb, /row) x_label = widget_label(rowy, value='X:') x_text = widget_text(rowy, xsize=8, value=strn(self.xcursor), /edit) y_label = widget_label(rowy, value='Y:') y_text = widget_text(rowy, xsize=8, value=strn(self.ycursor), /edit) curs_button = widget_button(rowy, value='READ CURSOR', /no_rel) cntrd_button = widget_button(rowz, value='ADJUST CENTROID', /no_rel) cntrd_label = widget_label(rowz, value='using box size = ') cntrd_text = widget_text(rowz, xsize=8, value='7', /edit) objrad_label = widget_label(rowa, value='Object Radius (px):') objrad = widget_text(rowa, xsize=8, value='5', /edit) oskyann_label = widget_label(rowb, value='Sky Radii (px):') iskyann = widget_text(rowb, xsize=8, value='15', /edit) oskyann = widget_text(rowb, xsize=8, value='20', /edit) fsky_label = widget_label(rowc, value='Forced Sky Value: ') fskyval = widget_text(rowc, xsize=15, value=' ',/edit) gain_label = widget_label(rowc1, value='Gain (e- per ADU):') IF ptr_valid(self.header) THEN BEGIN par = strmid(*self.header, 0, 8) gainpar = where(strpos(par, 'GAIN') GE 0 $ OR strpos(par, 'PHPADU') GE 0, npar) gval = 1.0 kk=npar WHILE kk GT 0 DO BEGIN kk = kk - 1 useg = par[gainpar[kk]] gval2 = sxpar(*self.header, useg) IF gval2 GT 0 THEN BEGIN kk=-1 gval = gval2 ENDIF ENDWHILE ENDIF ELSE gval = 1.0 gain = widget_text(rowc1, xsize=12, value=strn(gval), /edit) badmin_label = widget_label(rowc2, value='Bad pixel limits:') badmin = widget_text(rowc2, value='-32765', xsize=12, /edit) badmax = widget_text(rowc2, value='32767', xsize=12, /edit) objdisp = obj_new('IMGDISPLAY', rowd, xsize=dispsize, ysize=dispsize, $ /ps_dialog) objdisp->psfile, '_examdisplay_aper.ps', 'APERTURE PHOTOMETRY' row3 = widget_base(tlb, /row) row4 = widget_base(tlb, /row) row5 = widget_base(tlb, /row) object_label = widget_label(row3, value='Object net:') object_text = widget_text(row3, xsize=10, value='0', /edit) objerr_label = widget_label(row3, value='Error:') objerr_text = widget_text(row3, xsize=10, value='0') sky_label = widget_label(row4, value='Sky:') sky_text = widget_text(row4, xsize=10, value='0') skyerr_label = widget_label(row4, value='Error:') skyerr_text = widget_text(row4, xsize=10, value='0') quit_button = widget_button(row5, value='DISMISS', /no_rel) widget_control, tlb, /realize objdisp->id, mainid widget_control, mainid, get_value=gwin popup_info = ptr_new({tlb:tlb, $ this:(*info).this, $ x_text:x_text, $ y_text:y_text, $ curs_button:curs_button, $ cntrd_button:cntrd_button, $ cntrd_text:cntrd_text, $ objrad:objrad, $ oskyann:oskyann, $ iskyann:iskyann, $ fskyval:fskyval, $ gain:gain, $ badmin:badmin, $ badmax:badmax, $ objdisp:objdisp, $ dispsize:dispsize, $ gwin:gwin, $ object_text:object_text, $ objerr_text:objerr_text, $ sky_text:sky_text, $ skyerr_text:skyerr_text, $ quit_button:quit_button }) widget_control, tlb, set_uvalue=popup_info xmanager, 'examdisplay_aperphot', tlb, $ event_handler='examdisplay_aperphot_event', $ cleanup='examdisplay_aperphot_cleanup', /no_block pseudo = {id:objrad, top:tlb, handler:tlb} widget_control, objrad, send_event=pseudo RETURN END PRO EXAMDISPLAY::WORLD_COO_UPDATE IF self.wcs THEN BEGIN xyad, *self.header, self.xcursor, self.ycursor, $ coo1, coo2 ENDIF ELSE BEGIN xc = self.xcursor + 1 yc = self.ycursor + 1 dx = xc - sxpar(*self.header, 'CRPIX1') dy = yc - sxpar(*self.header, 'CRPIX2') d1 = dx*sxpar(*self.header, 'CD1_1') + dy*sxpar(*self.header,'CD1_2') d2 = dy*sxpar(*self.header, 'CD2_1') + dy*sxpar(*self.header,'CD2_2') coo1 = d1 + sxpar(*self.header, 'CRVAL1') coo2 = d2 + sxpar(*self.header, 'CRVAL2') ENDELSE widget_control, self.x_world_text, set_value=strn(coo1,format='(F15.7)') widget_control, self.y_world_text, set_value=strn(coo2,format='(F15.7)') IF widget_info(self.x_world_60_text, /valid) THEN BEGIN ast = adstring(coo1,coo2, 3) sign = strpos(ast, '+') IF sign LT 0 THEN sign = strpos(ast,'-') scoo1 = strmid(ast,0,sign) scoo2 = strmid(ast,sign,strlen(ast)-strlen(scoo1)) widget_control, self.x_world_60_text, set_value=scoo1 widget_control, self.y_world_60_text, set_value=scoo2 ENDIF RETURN END PRO EXAMDISPLAY_WORLD_COO_CLEANUP, Tlb widget_control, tlb, get_uvalue=pinfo IF ptr_valid(pinfo) THEN ptr_free, pinfo RETURN END PRO EXAMDISPLAY::WORLD_COO_EVENT, Event, Pinfo CASE event.id OF (*pinfo).log_button: BEGIN IF self.logging THEN BEGIN widget_control, self.maindisp, get_value=maingraph print, ' ' print, '---------- (X,Y) = (', strn(self.xcursor), ',', $ strn(self.ycursor), ') ------------------------------' $ + '----- Window ' + strn(maingraph) print, 'Pixel value = ', $ (*self.image)[self.xcursor, self.ycursor] widget_control, self.x_world_text, get_value=tmp widget_control, self.x_world_type, get_value=tmp2 print, tmp2[0], ' = ', tmp[0] widget_control, self.y_world_text, get_value=tmp widget_control, self.y_world_type, get_value=tmp3 print, tmp3[0], ' = ', tmp[0] IF widget_info(self.x_world_60_text, /valid) THEN BEGIN widget_control, self.x_world_60_text, get_value=tmp print, tmp2[0], ' = ', tmp[0] widget_control, self.y_world_60_text, get_value=tmp print, tmp3[0], ' = ', tmp[0] ENDIF ENDIF ELSE BEGIN junk = dialog_message('Logging not on') ENDELSE END (*pinfo).quit_button: BEGIN self.x_world_type = -1L self.y_world_type = -1L self.x_world_text = -1L self.y_world_text = -1L self.x_world_60_text = -1L self.y_world_60_text = -1L widget_control, (*pinfo).tlb, /destroy END ENDCASE RETURN END PRO EXAMDISPLAY_WORLD_COO_EVENT, Event widget_control, event.top, get_uvalue=pinfo (*pinfo).this->world_coo_event, event, pinfo RETURN END PRO EXAMDISPLAY::WORLD_COO, Info IF 1b - ptr_valid(self.header) THEN RETURN IF widget_info(self.x_world_text, /valid) THEN BEGIN widget_control, self.x_world_text, /show RETURN ENDIF widget_control, self.maindisp, get_value=mw wtitle = 'World Coords (Window '+strn(mw)+')' tlb = widget_base(/col, title=wtitle, group=(*info).maintlb, /floating) row2 = widget_base(tlb, /row) row3 = widget_base(tlb, /row) row4 = widget_base(tlb, /row) row5 = widget_base(tlb, /row) row6 = widget_base(tlb, /row) row7 = widget_base(tlb, /row) row8 = widget_base(tlb, /row) row9 = widget_base(tlb, /row) row10 = widget_base(tlb, /row) row11 = widget_base(tlb, /row) row12 = widget_base(tlb, /row) row99 = widget_base(tlb, /row) ; ; What kind of coordinates? ctype1 = strtrim(sxpar(*self.header, 'CTYPE1'),2) ctype2 = strtrim(sxpar(*self.header, 'CTYPE2'),2) t1 = ctype1 t2 = ctype2 t1a = strtrim(strupcase(gettok(t1,'-')),2) t2a = strtrim(strupcase(gettok(t2,'-')),2) equatorial = t1a EQ 'RA' AND t2a EQ 'DEC' galactic = t1a EQ 'GLON' AND t2a EQ 'GLAT' ecliptic = t1a EQ 'ELON' AND t2a EQ 'ELAT' skycoords = equatorial OR galactic OR ecliptic use_60 = equatorial ; ; Get plate scales. getrot, *self.header, rot, cdelt IF skycoords THEN BEGIN IF cdelt[0] LT 1./60. THEN BEGIN cdelt[0] = cdelt[0] * 3600 cunit1 = 'ARCSEC/PIXEL' ENDIF ELSE BEGIN cdelt[0] = cdelt[0] * 60 cunit1 = 'ARCMIN/PIXEL' ENDELSE IF cdelt[1] LT 1./60. THEN BEGIN cdelt[1] = cdelt[1] * 3600 cunit2 = 'ARCSEC/PIXEL' ENDIF ELSE BEGIN cdelt[1] = cdelt[1] * 60 cunit2 = 'ARCMIN/PIXEL' ENDELSE equinox = sxpar(*self.header, 'EQUINOX') epoch = '' IF strtrim(equinox,2) EQ '0' THEN BEGIN equinox = '' epoch = sxpar(*self.header, 'EPOCH') IF strtrim(epoch,2) EQ '0' THEN epoch = '' ENDIF ENDIF ELSE BEGIN cunit1 = 'PER PIXEL' cunit2 = 'PER PIXEL' ENDELSE scale1 = strn(abs(cdelt[0]),format='(G14.6)') + ' ' + cunit1 scale2 = strn(abs(cdelt[1]),format='(G14.6)') + ' ' + cunit2 t1 = ctype1 t2 = ctype2 t1a = strtrim(strupcase(gettok(t1,'-')),2) t2a = strtrim(strupcase(gettok(t2,'-')),2) equatorial = t1a EQ 'RA' AND t2a EQ 'DEC' use_60 = equatorial ; xaxis_label = widget_label(row2, value='X Axis Type: ') ; xaxis_text = widget_text(row2, xsize=12, value=ctype1) ; yaxis_label = widget_label(row3, value='Y Axis Type: ') ; yaxis_text = widget_text(row3, xsize=12, value=ctype2) xscale_label = widget_label(row4, value='X Scale: ') xscale_text = widget_text(row4, xsize=25, value=scale1) yscale_label = widget_label(row5, value='Y Scale: ') yscale_text = widget_text(row5, xsize=25, value=scale2) xvalue_label = widget_label(row6, value=ctype1 + ': ') xvalue_text = widget_text(row6, xsize=20, value='-999') IF use_60 THEN $ xvalue_60_text = widget_text(row7, xsize=20, value='-999') yvalue_label = widget_label(row8, value=ctype2 + ': ') yvalue_text = widget_text(row8, xsize=20, value='-999') IF use_60 THEN $ yvalue_60_text = widget_text(row9, xsize=20, value='-999') equinox = '' epoch = '' IF skycoords THEN BEGIN IF equatorial THEN lab = 'EQUATORIAL' IF galactic THEN lab = 'GALACTIC' IF ecliptic THEN lab = 'ECLIPTIC' arrow_label_frame = widget_base(row10,col=1) arrow_label1 = widget_label(arrow_label_frame, value='ORIENTATION IN') arrow_label2 = widget_label(arrow_label_frame, value=lab) arrow_label3 = widget_label(arrow_label_frame, value='SYSTEM') arrow_draw = widget_draw(row10, xsize=110, ysize=110) ENDIF IF equinox NE '' THEN BEGIN equinox_label = widget_label(row11, value='EQUINOX: ') equinox_text = widget_text(row11, xsize=15, value=strn(equinox)) ENDIF ELSE IF epoch NE '' THEN BEGIN epoch_label = widget_label(row11, value='EPOCH: ') epoch_text = widget_text(row11, xsize=15, value=strn(epoch)) ENDIF log_button = widget_button(row12, value='LOG CURRENT VALUES', /no_rel) quit_button = widget_button(row99, value='DISMISS', /no_rel) widget_control, tlb, /realize IF skycoords THEN BEGIN widget_control, arrow_draw, get_value=arrow_win svwin = !D.window wset, arrow_win arrows, *self.header, 55, 55, /notvertex IF svwin GE 0 THEN wset, svwin ENDIF popup_info = ptr_new({tlb:tlb, $ this:(*info).this, $ log_button:log_button, $ quit_button:quit_button }) self.x_world_text = xvalue_text self.y_world_text = yvalue_text self.x_world_type = xvalue_label self.y_world_type = yvalue_label IF use_60 THEN BEGIN self.x_world_60_text = xvalue_60_text self.y_world_60_text = yvalue_60_text ENDIF widget_control, tlb, set_uvalue=popup_info xmanager, 'examdisplay_world_coo', tlb, $ event_handler='examdisplay_world_coo_event', $ cleanup='examdisplay_world_coo_cleanup', /no_block ;; widget_control, (*info).tlb, /destroy RETURN END PRO EXAMDISPLAY::LISTING, Info IF 1b - ptr_valid(self.header) THEN RETURN widget_control, self.maindisp, get_value=mw IF self.logging THEN BEGIN print, ' ' print, '----------------------', $ '-------------------------------' $ + '---------- Window ' + strn(mw) FOR i=0,n_elements(*self.header)-1 DO $ print, strtrim((*self.header)[i]) ENDIF ELSE BEGIn title = 'Header Listing (Window '+strn(mw)+')' xdispstr, *self.header, title=title, $ group=self.baseid, $ font=*self.fixedfont ENDELSE ;; widget_control, (*info).tlb, /destroy RETURN END PRO EXAMDISPLAY::LOGGING, Info self.logging = widget_info((*info).log_droplist, /droplist_select) RETURN END PRO EXAMDISPLAY::HELP helptext=[ $ 'Examining the Displayed Image', $ ' ', $ 'Summary of Capabilities:', $ ' (1) Pixel listing', $ ' (2) Statistics of whole image', $ ' (3) Statistics of region within zoom box', $ ' (4) Various plots', $ ' (5) Region-of-interest photometry', $ ' (6) Aperture photometry', $ ' (7) Aperture growth photometry', $ ' (8) World coordinate display', $ ' (9) Header display', $ ' (10) Printing of outputs', $ ' (11) Some history', $ ' ',$ 'Details:', $ ' ',$ ' (1) Pixel listing', $ ' ',$ ' First position the zoom box where you want the listing', $ ' centered. Then click on the "pixel listing" button.', $ ' An 11x11 area of the image will be listed.', $ ' ',$ ' (2) Statistics of image', $ ' ',$ ' There are two choices, selected by clicking on the', $ ' following buttons:', $ ' ',$ ' "ordinary statistics": Mean, standard deviation, min, max, ',$ ' median, and a little low-resolution ',$ ' histogram will be displayed.', $ ' ',$ ' "outlier statistics": Statistics based on quantiles', $ ' will be displayed. The terminology', $ ' of Tukey is used (hinges, fences,', $ ' and so on) and is defined in the', $ ' listing itself.', $ ' ',$ ' (3) Statistics of region within zoom box', $ ' There are two choices, selected by clicking on the', $ ' following buttons:', $ ' ',$ ' "ordinary statistics": see above ',$ ' "outlier statistics": see above', $ ' ',$ ' (4) Various plots', $ ' ',$ ' There are two choices, selected by clicking on the', $ ' following buttons:', $ ' ',$ ' "row/column plot": This is a cut centered on where the zoom', $ ' box happens to be before you hit the button.', $ ' A new widget pops up with sliders to adjust', $ ' the plot limits and blanks in which plot', $ ' limits may be typed directly (better than', $ ' sliders for some situations, e.g., log plots).', $ ' The new widget also has buttons to switch', $ ' between row and column mode and a blank', $ ' to fill in the width in pixels of the cut.', $ ' There are also buttons to switch between ',$ ' log and linear axis scaling, and buttons to', $ ' increment or decrement the width of the cut.', $ ' For widths greater than 1 pixel, a sum, not', $ ' an average, is plotted. A simple postscript', $ ' output capability can be invoked by pushing', $ ' the "Postscript" button at the bottom.', $ ' ',$ ' "profile": Instructions will appear. They say just', $ ' to click at either end of the desired profile.', $ ' The plot appears in a new widget similar to', $ ' one described under "row/column plot" above.', $ ' ', $ ' (5) Region-of-interest photometry', $ ' ', $ ' Click on the button marked "r.o.i. photometry". A popup appears', $ ' with buttons you click when you want to measure object and when', $ ' you want to measure sky. The object and sky regions are actually', $ ' picked using a routine only slightly altered from CW_DEFROI that', $ ' comes with IDL. This is a pretty straightforward r.o.i. defining', $ ' routine, and you can get to know any peculiarities just by trying', $ ' it out. The results of the photometry are displayed in text ', $ ' fields within the subsidiary widget. The sky and object ', $ ' region must be selected within the main image window.', $ ' ', $ ' Photometry results can be stored in save files by pushing the', $ ' "write save file" button in the photometry pop-up. Files are named', $ ' using a tag string specified via a text field in the photometry ', $ ' pop-up, combined with a counter incremented for each source ', $ ' (for uniqueness). The contents of the save file are as follows: ', $ ' AVOBJNET average net flux per pixel in object', $ ' LOG_COUNT unique counter for object', $ ' OBJNET net flux in entire object', $ ' OBJSKY background flux in object aperture', $ ' OBJTOT total flux in object aperture', $ ' OBJ_ROI (POINTER) subscripts of object pixels', $ ' SKYAVG average value of sky pixels', $ ' SKY_ROI (POINTER) subscripts of sky pixels', $ ' ', $ ' (6) Aperture photometry', $ ' ', $ ' Click on the button marked "aperture photometry". A popup', $ ' appears that shows a small region around the cursor and allows', $ ' you to change photometry parameters. If you move the cursor', $ ' on the main widget, you can do photometry at the new position', $ ' by pushing the READ CURSOR button. The coordinates can be ', $ ' refined with the ADJUST CENTROID button. IDLAstro library', $ ' routines do the work: CNTRD for centroiding and APER for ', $ ' photometry. The idea of including a small image display in ', $ ' this popup came from ATV by Barth et al.', $ ' ', $ ' (7) Aperture growth photometry', $ ' ', $ ' Similar to plain aperture photometry except that sky is obtained', $ ' by fitting between two radii, plots are shown, and the object', $ ' aperture is always the same as the inner sky radius. Error', $ ' estimates are obtained from APER for the appropriate sky and', $ ' object radii although the actual sky value comes from a different', $ ' algorithm.', $ ' ', $ ' (8) World coordinate display', $ ' ', $ ' If you click on "world coordinates", you will get a little ', $ ' subsidiary widget that gives a continuous display of the cursor ',$ ' position in the world coordinate frame. This is available ', $ ' only if a FITS header has been supplied.', $ ' ', $ ' (9) Header display', $ ' ', $ ' Straightforward: if a FITS header has been supplied, you can ', $ ' click on the "header listing" button and a simple file display', $ ' widget will come up showing the header text.', $ ' ', $ ' (10) Printing of outputs', $ ' ', $ ' This is controlled by a droplist you can use to toggle between', $ ' a state where image examination outputs appear in the usual IDL', $ ' command line window, and a state where a new text display widget', $ ' pops up to receive each result. This widget allows simple text ', $ ' searches.', $ ' ', $ ' (11) Some history', $ ' ', $ ' There are several agendas incorporated into this program. One ', $ ' was to incorporate routines from the Ultraviolet Imaging Telescope', $ ' (UIT) software library called MOUSSE into a widget. One was to', $ ' write an image display that could be incorporated easily into', $ ' special-purpose analysis widgets while automatically including', $ ' a lot of general image examination tools. Object-oriented IDL', $ ' coding is used (though not "object graphics" as such).' ] xdispstr, helptext, title='Help on Image Examination', $ group=(*self.popup_info).tlb, $ font=*self.fixedfont END PRO EXAMDISPLAY::POPUP_EVENT, Event, Info ; 5 Apr 2000 - Dummy event for log_filename. RSH destroy = 0b CASE event.id OF (*info).allstats_button: BEGIN self->allstats, info END (*info).allrstats_button: BEGIN self->allrstats, info END (*info).stats_button: BEGIN self->stats, info END (*info).rstats_button: BEGIN self->rstats, info END (*info).imlist_button: BEGIN self->imlist, info END (*info).profile_button: BEGIN self->profile, info END (*info).rowcol_button: BEGIN self->rowcol, info END (*info).roiphot_button: BEGIN self->roiphot, info END (*info).aperphot_button: BEGIN self->aperphot, info END (*info).apergrowth_button: BEGIN self->apergrowth, info END (*info).world_coo_button: BEGIN self->world_coo, info END (*info).listing_button: BEGIN self->listing, info END (*info).log_droplist: BEGIN self->logging, info END (*info).help_button: BEGIN self->help END (*info).quit_button: BEGIN destroy = 1b END ENDCASE IF destroy THEN widget_control, event.top, /destroy RETURN END PRO EXAMDISPLAY_POPUP_EVENT, Event widget_control, event.top, get_uvalue=info (*info).this->popup_event, event, info RETURN END PRO EXAMDISPLAY_POPUP_CLEANUP, Tlb widget_control, tlb, get_uvalue=info IF ptr_valid(info) THEN ptr_free, info RETURN END PRO EXAMDISPLAY::POPUP, Event ; Changed where frame3 is added to misclabels array. RSH, 8 Oct. 1999 IF ptr_valid(self.popup_info) THEN BEGIN tlb = (*self.popup_info).tlb iml = (*self.popup_info).imlist_button IF widget_info(tlb, /valid) $ AND widget_info(iml, /valid) THEN BEGIN widget_control, tlb, /show RETURN ENDIF ENDIF widget_control, self.maindisp, get_value=mw title = 'EXAMINE (Window ' + strn(mw) + ')' tlb = widget_base(title=title, col=1, group_leader=event.top) exam_buttons = widget_base(tlb, col=1) top_row = widget_base(tlb, row=1) frame4 = widget_base(tlb, col=1) log_droplist = widget_droplist(frame4, $ value=['Print to Separate Window', 'Print in IDL Window']) widget_control, log_droplist, set_droplist_select=self.logging ;log_fileblock = widget_base(frame4,row=1) ;log_filelab = widget_label(log_fileblock, value='Log Tag: ') ;log_filename = widget_text(log_fileblock, xsize=10, ysize=1, $ ;value=*self.log_tag, /editable) ;IF self.logging THEN widget_control, log_filename, editable=0 frame0 = widget_base(tlb,col=1,frame=2) label0 = widget_label(frame0, value='WHOLE IMAGE:') allstats_button = widget_button(frame0, value='ordinary statistics') allrstats_button = widget_button(frame0, value='outlier statistics') frame1 = widget_base(tlb,col=1,frame=2) label1 = widget_label(frame1, value='CURRENT CURSOR OR BOX:') imlist_button = widget_button(frame1, value='pixel listing') rowcol_button = widget_button(frame1, value='row/column plot') stats_button = widget_button(frame1, value='ordinary statistics') rstats_button = widget_button(frame1, value='outlier statistics') frame2 = widget_base(tlb,col=1,frame=2) label2 = widget_label(frame2, value='INTERACTIVE:') roiphot_button = widget_button(frame2, value='r.o.i. photometry') aperphot_button = widget_button(frame2, value='aperture photometry') apergrowth_button = widget_button(frame2, value='aperture growth photometry') profile_button = widget_button(frame2, value='profile') misc_labels = [frame4, frame1, frame2] world_coo_button = -1L listing_button = -1L wcs = 0b coo = 0b IF ptr_valid(self.header) THEN BEGIN frame3 = widget_base(tlb,col=1,frame=2) label3 = widget_label(frame3, value='INFORMATION FROM HEADER:') listing_button = widget_button(frame3, value='header listing') extast, *self.header, aststruc szast = size(aststruc) ast_ok = szast[szast[0]+1] EQ 8 IF ast_ok THEN BEGIN map_types=['DEF','AZP','TAN','SIN','STG', $ 'ARC','ZPN','ZEA','AIR','CYP', $ 'CAR','MER','CEA','COP','COD', $ 'COE','COO','BON','PCO','GLS', $ 'PAR','AIT','MOL','CSC','QSC', $ 'TSC'] ctype = strtrim(sxpar(*self.header, 'CTYPE1'),2) IF strlen(ctype) LT 8 THEN ctype = strmid(ctype+' ',0,8) mtype = strmid(ctype,5,3) junk = where(mtype EQ map_types, count) IF count EQ 1 THEN BEGIN wcs = 1b coo = 1b ENDIF ELSE BEGIN IF ctype NE '0 ' THEN BEGIN wcs = 0b coo = 1b ENDIF ENDELSE IF coo THEN BEGIN world_coo_button = widget_button(frame3, value='world coordinates') ENDIF ENDIF misc_labels = [misc_labels, frame3] ENDIF self.wcs = wcs quit_button = widget_button(top_row, value='DISMISS') help_button = widget_button(top_row, value=' Help ') misc_labels = [misc_labels, help_button] results = widget_base(tlb,col=1) widget_control, tlb, /realize info = ptr_new({maintlb:event.top, $ tlb:tlb, imlist_button:imlist_button, $ profile_button:profile_button, $ allstats_button:allstats_button, $ stats_button:stats_button, $ allrstats_button:allrstats_button, $ rstats_button:rstats_button, $ rowcol_button:rowcol_button, $ roiphot_button:roiphot_button, $ aperphot_button:aperphot_button, $ apergrowth_button:apergrowth_button, $ world_coo_button:world_coo_button, $ listing_button:listing_button, $ misc_labels:misc_labels, $ x0:0L, y0:0L, $ maingraph:-1L, $ log_droplist:log_droplist, $ quit_button:quit_button, $ help_button:help_button, $ instruc:-1L, $ ;results:results, $ this:self}) self.popup_info = info widget_control, tlb, set_uvalue=info xmanager, 'examdisplay_popup', tlb, $ event_handler='examdisplay_popup_event', $ cleanup='examdisplay_popup_cleanup', /no_block RETURN END PRO EXAMDISPLAY::HOTKEYS_CLEANUP IF ptr_valid(self.popup_info) THEN BEGIN tlb = (*(self.popup_info)).tlb IF widget_info(tlb, /valid) THEN $ widget_control, (*self.popup_info).tlb, /destroy ENDIF IF ptr_valid(self.popup_info) THEN ptr_free, self.popup_info RETURN END PRO EXAMDISPLAY::HOTKEYS_HELP helptext=[ $ 'Examining the Displayed Image', $ ' ', $ 'Summary of Capabilities:', $ ' (l) Pixel listing', $ ' (S) Ordinary statistics of whole image', $ ' (s) Ordinary statistics of region within zoom box', $ ' (X) Outlier statistics of whole image', $ ' (x) Outlier statistics of region within zoom box', $ ' (c) Row or column plot', $ ' (p) Profile plot', $ ' (r) Region-of-interest photometry', $ ' (a) Aperture photometry', $ ' (A) Aperture growth photometry', $ ' (w) World coordinate display', $ ' (H) Header display', $ ' ', $ 'For more complete help see HELP button on EXAMINE popup.' ] xdispstr, helptext, title='Help on Examination Hotkeys', $ group=(*self.popup_info).maintlb, $ font=*self.fixedfont END PRO EXAMDISPLAY::HOTKEYS, Event ; 21 Oct 2000 self->hotkeys_cleanup IF event.type EQ 0 THEN BEGIN let = string(event.ch) ENDIF ELSE BEGIN let = '' ENDELSE widget_control, self.maindisp, get_value=maingraph info = ptr_new({maintlb:event.top, $ tlb:-1L, $ x0:0L, y0:0L, $ maingraph:maingraph, $ instruc:-1L, $ this:self}) self.popup_info = info CASE let OF 'S': BEGIN self->allstats, info END 'X': BEGIN self->allrstats, info END 's': BEGIN self->stats, info END 'x': BEGIN self->rstats, info END 'l': BEGIN self->imlist, info END 'p': BEGIN self->profile, info END 'c': BEGIN self->rowcol, info END 'r': BEGIN self->roiphot, info END 'a': BEGIN self->aperphot, info END 'A': BEGIN self->apergrowth, info END 'w': BEGIN self->world_coo, info END 'H': BEGIN self->listing, info END 'h': BEGIN self->hotkeys_help END ELSE: ; nothing ENDCASE RETURN END PRO EXAMDISPLAY::E, Event ; ; Event handling for the examdisplay object. ; IF widget_info(self.glabel, /valid) THEN BEGIN widget_control, self.maindisp, get_value=gwin widget_control, self.glabel, set_value=strn(gwin) ENDIF CASE event.id OF self.exam_button: BEGIN self->popup, event END self.maintext1: BEGIN self->hotkeys, event END ELSE: BEGIN IF event.id EQ self.maindisp THEN BEGIN event_type = tag_names(event, /structure) IF event_type NE '' $ AND widget_info(self.exam_button,/valid) THEN BEGIN IF event_type EQ 'WIDGET_TRACKING' THEN BEGIN IF 1b - event.enter THEN BEGIN widget_control, self.maintext0, /input_focus ENDIF ENDIF ELSE BEGIN widget_control, self.maintext1, /input_focus ENDELSE ENDIF ENDIF self->imgdisplay::e, event IF obj_valid(self) THEN BEGIN IF widget_info(self.x_world_text, /valid) THEN BEGIN self->world_coo_update ENDIF ENDIF END ENDCASE RETURN END PRO EXAMDISPLAY::DRAW, Image, Header, _EXTRA=extra IF n_elements(header) GT 0 THEN BEGIN IF ptr_valid(self.header) THEN ptr_free, self.header self.header = ptr_new(header) ENDIF self->imgdisplay::draw, image, _extra=extra RETURN END PRO EXAMDISPLAY::CLEANUP IF ptr_valid(self.header) THEN ptr_free, self.header IF ptr_valid(self.log_tag) THEN ptr_free, self.log_tag self->hotkeys_cleanup self->imgdisplay::cleanup RETURN END FUNCTION EXAMDISPLAY::INIT, Parent, $ HEADER=header, NOEXAMINE=noexamine, LOG_tag=log_tag, _EXTRA=extra ; Arguments: ; Parent: Widget ID of parent base widget ; Keywords: ; HEADER: Image header ; NOEXAMINE: If set omit examining capabilities. ; LOG_TAG: Never actually used; is here to avoid problems ; with old calling programs. ; ret = self->imgdisplay::init(Parent, _extra=extra) ; ; self.button_frame is part of IMGDISPLAY IF n_elements(header) GT 0 THEN self.header = ptr_new(header) IF n_elements(log_tag) LE 0 THEN log_tag='examdisp' self.log_tag = ptr_new(log_tag) self.exam_button=-1L self.maintext0=-1L self.maintext1=-1L self.logging = 1 nexam = keyword_set(noexamine) IF 1b - nexam THEN BEGIN self.exam_button = widget_button(self.button_frame, value='EXAMINE') self.maintext0 = widget_text(self.button_frame, $ scr_xsize=1,scr_ysize=1, $ /editable) self.maintext1 = widget_text(self.button_frame, $ scr_xsize=1,scr_ysize=1, $ /all_events) ENDIF readout_exists = widget_info(self.xreadout, /valid) IF readout_exists THEN BEGIN value_column = widget_info(self.xreadout, /parent) quantity_row = widget_info(value_column, /parent) label_column = widget_info(quantity_row, /child) junk = widget_label(label_column, value='Window:') self.glabel = widget_label(value_column, value='nnnnn') ENDIF ELSE self.glabel = -1L RETURN, ret END PRO EXAMDISPLAY__DEFINE ; Just gets the object definition into the IDL session. struct = {EXAMDISPLAY, exam_button:-1L, $ maintext0:-1L, $ maintext1:-1L, $ header:ptr_new(), $ popup_info:ptr_new(), $ x_world_type:-1L, $ y_world_type:-1L, $ x_world_text:-1L, $ y_world_text:-1L, $ x_world_60_text:-1L, $ y_world_60_text:-1L, $ logging:1L, $ log_count:0L, $ log_tag:ptr_new(), $ wcs:0b, $ glabel:-1L, $ inherits IMGDISPLAY} RETURN END