;+ ; $Id: tiepointer.pro,v 1.6 2012/03/01 16:44:29 nathan Exp $ ; ; Tiepointer is covered in the Sunloop User Guide: ; $SSW/stereo/secchi/idl/display/sunloop/sunloop_user_guide.pdf ; ; written by: Jeffrey.R.Hall@jpl.nasa.gov ; written for: Paulett.C.Liewer@jpl.nasa.gov ; STEREO/SECCHI Project ; ; "Copyright 2012, by the California Institute of Technology. ; ALL RIGHTS RESERVED. United States Government Sponsorship ; acknowledged. Any commercial use must be negotiated with the ; Office of Technology Transfer at the California Institute of ; Technology. ; This software may be subject to U.S. export control laws. ; By accepting this software, the user agrees to comply with ; all applicable U.S. export laws and regulations. User has ; the responsibility to obtain export licenses, or other ; export authority as may be required before exporting such ; information to foreign countries or providing access to ; foreign persons." ;- @chain_link_utilities.pro @line3d.pro FUNCTION tiepointer::max_calc,data,min,scaler,ntol=ntol ; Calculate max. ; Exclude outliers as defined by contiguous groupings of non-zero histogram bins ; that contain less than ntolerance pixels. hist=0 scaler=1 hist=HISTOGRAM(data/scaler) WHILE (N_ELEMENTS(hist) LT 10000) DO BEGIN scaler=scaler/10.0 hist=HISTOGRAM(data/scaler) ENDWHILE ncount=0L IF KEYWORD_SET(ntol) THEN ntolerance=ntol ELSE ntolerance=6 FOR z=N_ELEMENTS(hist)-1ULL,1,-1 DO BEGIN max=z+min/scaler IF hist[z] GT 0 THEN ncount=ncount+1 IF ncount GT 0 THEN BEGIN max=max+ncount IF ncount GT ntolerance THEN BREAK IF hist[z] EQ 0 THEN ncount = 0 ENDIF ENDFOR RETURN,max*scaler END PRO tiepointer::bytescale_raw_data ;------------------------------------------------------- ; Convert raw data to byte, with scaling factors. ;------------------------------------------------------- min=SELF.image1_min_value max=SELF.image1_max_value exp=1.0/SELF.image1_gamma_value IF PTR_VALID(SELF.bytescaled_array1_ptr) THEN PTR_FREE,SELF.bytescaled_array1_ptr SELF.bytescaled_array1_ptr=PTR_NEW(BYTSCL((((*SELF.raw_array1_ptr)-min)/FLOAT(ABS(max-min)))^exp,MIN=0,MAX=1)) min=SELF.image2_min_value max=SELF.image2_max_value exp=1.0/SELF.image2_gamma_value IF PTR_VALID(SELF.bytescaled_array2_ptr) THEN PTR_FREE,SELF.bytescaled_array2_ptr SELF.bytescaled_array2_ptr=PTR_NEW(BYTSCL((((*SELF.raw_array2_ptr)-min)/FLOAT(ABS(max-min)))^exp,MIN=0,MAX=1)) data=0 END FUNCTION tiepointer::convert_xy_into_linesamp,inp_values,REVERSE=reverse direction=0 IF (SIZE(reverse,/TYPE) GT 0) THEN IF (reverse EQ 1) THEN direction=1 ;------------------------------------------------------- ; Misnomer: Although this tiepointer program uses x,y ; the sunloop program deals with line,samp. ;------------------------------------------------------- CASE direction OF 0 : BEGIN ; Forward. Convert [x1,y1,x2,y2] into [line1,samp1,line2,samp2]. xy=inp_values line_left=(SELF.widgetdraw_geom_DRAW_YSIZE)[0]-xy[1] samp_left=xy[0]+1 line_right=(SELF.widgetdraw_geom_DRAW_YSIZE)[1]-xy[3] samp_right=xy[2]+1 RETURN,[line_left,samp_left,line_right,samp_right] END 1 : BEGIN ; Reverse. Convert [line1,samp1,line2,samp2] into [x1,y1,x2,y2]. linesamp=inp_values x_left=linesamp[1]-1 y_left=(SELF.widgetdraw_geom_DRAW_YSIZE)[0]-linesamp[0] x_right=linesamp[3]-1 y_right=(SELF.widgetdraw_geom_DRAW_YSIZE)[1]-linesamp[2] RETURN,[x_left,y_left,x_right,y_right] END ENDCASE END FUNCTION tiepointer::get_color,x,y,window ;------------------------------------------------------- ; Make color black or white depending on the image value ; of an averaged area centered at the tiepoint location. ;------------------------------------------------------- buffer=3 xsub=(x*(x LE buffer))+(buffer*(x GT buffer)) ysub=(y*(y LE buffer))+(buffer*(y GT buffer)) CASE window OF 1 : xtmp=((*SELF.hdr1ptr).NAXIS1-1)-x 2 : xtmp=((*SELF.hdr2ptr).NAXIS1-1)-x ENDCASE xadd=(xtmp*(xtmp LE buffer))+(buffer*(xtmp GT buffer)) CASE window OF 1 : ytmp=((*SELF.hdr1ptr).NAXIS2-1)-y 2 : ytmp=((*SELF.hdr2ptr).NAXIS2-1)-y ENDCASE yadd=(ytmp*(ytmp LE buffer))+(buffer*(ytmp GT buffer)) CASE window OF 1 : color=(!D.N_COLORS-1)*(MEAN((*SELF.bytescaled_array1_ptr)[x-xsub:x+xadd,y-ysub:y+yadd]) LT 128) 2 : color=(!D.N_COLORS-1)*(MEAN((*SELF.bytescaled_array2_ptr)[x-xsub:x+xadd,y-ysub:y+yadd]) LT 128) ENDCASE RETURN,color END PRO tiepointer::load_color_table IF ((SELF.color_table)[0] EQ -1) THEN BEGIN ; Yellow. TVLCT,INDGEN(255),INDGEN(255),INTARR(255) ENDIF ELSE BEGIN LOADCT,SELF.color_table,/SILENT ENDELSE END PRO tiepointer::redraw WIDGET_CONTROL,/HOURGLASS ;------------------------------------------------------- ; Display the images in the windows. ;------------------------------------------------------- curwin=!D.WINDOW WSET,SELF.window1 SELF->load_color_table cmap_applies=colormap_applicable() IF NOT cmap_applies THEN BEGIN DEVICE,GET_DECOMPOSED=orig_decomposed_value DEVICE,DECOMPOSED=0 ENDIF WIDGET_CONTROL,SELF.displaylabel1,SET_VALUE=FILE_BASENAME(SELF.left_filename) TV,*SELF.bytescaled_array1_ptr WSET,SELF.window2 WIDGET_CONTROL,SELF.displaylabel2,SET_VALUE=FILE_BASENAME(SELF.right_filename) TV,*SELF.bytescaled_array2_ptr IF NOT cmap_applies THEN BEGIN DEVICE,DECOMPOSED=orig_decomposed_value ENDIF WSET,curwin END PRO tiepointer::plot_reference_points ;------------------------------------------------------- ; Plot reference points. ;------------------------------------------------------- curwin=!D.WINDOW SELF->setup_plot_space ; Left WSET,SELF.window1 xsize=(SELF.widgetdraw_geom_DRAW_XSIZE)[0] ysize=(SELF.widgetdraw_geom_DRAW_YSIZE)[0] ; Show LEFT reference points: sun center and optical axis. x=((*SELF.secchistruct1ptr).suncenter_xy)[0] y=((*SELF.secchistruct1ptr).suncenter_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN OPLOT,[x],[y],PSYM=6,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Sun Center',COLOR=SELF->get_color(x,y,1) ENDIF ;x=((*SELF.secchistruct1ptr).optax_xy)[0] ;y=((*SELF.secchistruct1ptr).optax_xy)[1] ;IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 ; XYOUTS,x,y,' Optical Axis',COLOR=SELF->get_color(x,y,1) ;ENDIF ; Draw radius circles. km_sun_radius = 695000L image_size = (*SELF.hdr1ptr).NAXIS1 arcsec_pixel = (*SELF.hdr1ptr).CDELT1 IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN arcsec_pixel = arcsec_pixel * 60 * 60 date_obs = (*SELF.hdr1ptr).DATE_OBS sun_x_center = ((*SELF.secchistruct1ptr).suncenter_xy)[0] sun_y_center = ((*SELF.secchistruct1ptr).suncenter_xy)[1] radians_pixel = arcsec_pixel / 60.0 / 60.0 * !DTOR distance = (get_stereo_lonlat(date_obs,'b'))[0] km_pixel = distance * SIN( radians_pixel ) pixels_sun_radius = km_sun_radius / km_pixel FOR rsun=1,350 DO BEGIN ; Draw a circle at the solar disc (1Rsun). IF (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'cor2') THEN IF (rsun GT 1) THEN IF ((rsun MOD 2) NE 0) THEN CONTINUE IF (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'hi_1') THEN IF ((rsun MOD 10) NE 0) THEN CONTINUE IF (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'hi_2') THEN IF ((rsun MOD 50) NE 0) THEN CONTINUE radius = rsun radians361 = !DTOR * ( FINDGEN( 361 ) - 90 ) * (-1) x = COS(radians361) * pixels_sun_radius * radius + sun_x_center y = SIN(radians361) * pixels_sun_radius * radius + sun_y_center OPLOT,x,y,THICK=1,COLOR=!D.N_COLORS-1 IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN BEGIN offset = 1.90 ENDIF ELSE BEGIN offset = 2.35 ENDELSE offset_x = 35 offset_y = 5 x = sun_x_center + rsun * pixels_sun_radius * SIN( offset ) + offset_x y = sun_y_center - rsun * pixels_sun_radius * COS( offset ) - offset_y XYOUTS, x, y, STRTRIM(rsun,2)+' Rs', /DEVICE, ALIGNMENT = 0.5, CHARSIZE = 1.5, COLOR = !D.N_COLORS-1 IF (rsun GT 2) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'euvi') THEN BREAK IF (rsun GT 5) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'cor1') THEN BREAK IF (rsun GT 21) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'cor2') THEN BREAK IF (rsun GT 100) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'hi_1') THEN BREAK ENDFOR ;;IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN BEGIN ; Mercury x=((*SELF.secchistruct1ptr).mercury_xy)[0] y=((*SELF.secchistruct1ptr).mercury_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Mercury',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Mercury',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Venus x=((*SELF.secchistruct1ptr).venus_xy)[0] y=((*SELF.secchistruct1ptr).venus_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Venus',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Venus',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Earth x=((*SELF.secchistruct1ptr).earth_xy)[0] y=((*SELF.secchistruct1ptr).earth_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Earth',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Earth',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Mars x=((*SELF.secchistruct1ptr).mars_xy)[0] y=((*SELF.secchistruct1ptr).mars_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Mars',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Mars',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Jupiter x=((*SELF.secchistruct1ptr).jupiter_xy)[0] y=((*SELF.secchistruct1ptr).jupiter_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Jupiter',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Jupiter',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Neptune x=((*SELF.secchistruct1ptr).neptune_xy)[0] y=((*SELF.secchistruct1ptr).neptune_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Neptune',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Neptune',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Uranus x=((*SELF.secchistruct1ptr).uranus_xy)[0] y=((*SELF.secchistruct1ptr).uranus_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,1),THICK=3 XYOUTS,x,y,' Uranus',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Uranus',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ;;ENDIF ; Right WSET,SELF.window2 xsize=(SELF.widgetdraw_geom_DRAW_XSIZE)[1] ysize=(SELF.widgetdraw_geom_DRAW_YSIZE)[1] ; Show RIGHT reference points: sun center and optical axis. x=((*SELF.secchistruct2ptr).suncenter_xy)[0] y=((*SELF.secchistruct2ptr).suncenter_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN OPLOT,[x],[y],PSYM=6,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Sun Center',COLOR=SELF->get_color(x,y,1) ENDIF ;x=((*SELF.secchistruct2ptr).optax_xy)[0] ;y=((*SELF.secchistruct2ptr).optax_xy)[1] ;IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 ; XYOUTS,x,y,' Optical Axis',COLOR=SELF->get_color(x,y,1) ;ENDIF ; Draw radius circles. km_sun_radius = 695000L image_size = (*SELF.hdr2ptr).NAXIS1 arcsec_pixel = (*SELF.hdr2ptr).CDELT1 IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN arcsec_pixel = arcsec_pixel * 60 * 60 date_obs = (*SELF.hdr2ptr).DATE_OBS sun_x_center = ((*SELF.secchistruct2ptr).suncenter_xy)[0] sun_y_center = ((*SELF.secchistruct2ptr).suncenter_xy)[1] radians_pixel = arcsec_pixel / 60.0 / 60.0 * !DTOR distance = (get_stereo_lonlat(date_obs,'a'))[0] km_pixel = distance * SIN( radians_pixel ) pixels_sun_radius = km_sun_radius / km_pixel FOR rsun=1,350 DO BEGIN ; Draw a circle at the solar disc (1Rsun). IF (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'cor2') THEN IF (rsun GT 1) THEN IF ((rsun MOD 2) NE 0) THEN CONTINUE IF (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'hi_1') THEN IF ((rsun MOD 10) NE 0) THEN CONTINUE IF (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'hi_2') THEN IF ((rsun MOD 50) NE 0) THEN CONTINUE radius = rsun radians361 = !DTOR * ( FINDGEN( 361 ) - 90 ) * (-1) x = COS(radians361) * pixels_sun_radius * radius + sun_x_center y = SIN(radians361) * pixels_sun_radius * radius + sun_y_center OPLOT,x,y,THICK=1,COLOR=!D.N_COLORS-1 IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN BEGIN offset = 4.4 ENDIF ELSE BEGIN offset = 2.35 ENDELSE offset_x = 35 offset_y = 5 x = sun_x_center + rsun * pixels_sun_radius * SIN( offset ) + offset_x y = sun_y_center - rsun * pixels_sun_radius * COS( offset ) - offset_y XYOUTS, x, y, STRTRIM(rsun,2)+' Rs', /DEVICE, ALIGNMENT = 0.5, CHARSIZE = 1.5, COLOR = !D.N_COLORS-1 IF (rsun GT 2) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'euvi') THEN BREAK IF (rsun GT 5) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'cor1') THEN BREAK IF (rsun GT 21) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'cor2') THEN BREAK IF (rsun GT 200) AND (STRLOWCASE(STRMID(SELF.detector,0,4)) EQ 'hi_1') THEN BREAK ENDFOR ;;IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN BEGIN ; Mercury x=((*SELF.secchistruct2ptr).mercury_xy)[0] y=((*SELF.secchistruct2ptr).mercury_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Mercury',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Mercury',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Venus x=((*SELF.secchistruct2ptr).venus_xy)[0] y=((*SELF.secchistruct2ptr).venus_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Venus',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Venus',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Earth x=((*SELF.secchistruct2ptr).earth_xy)[0] y=((*SELF.secchistruct2ptr).earth_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Earth',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Earth',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Mars x=((*SELF.secchistruct2ptr).mars_xy)[0] y=((*SELF.secchistruct2ptr).mars_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Mars',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Mars',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Jupiter x=((*SELF.secchistruct2ptr).jupiter_xy)[0] y=((*SELF.secchistruct2ptr).jupiter_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Jupiter',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Jupiter',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Neptune x=((*SELF.secchistruct2ptr).neptune_xy)[0] y=((*SELF.secchistruct2ptr).neptune_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Neptune',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Neptune',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ; Uranus x=((*SELF.secchistruct2ptr).uranus_xy)[0] y=((*SELF.secchistruct2ptr).uranus_xy)[1] IF (x GE 3) AND (x LT xsize-3) AND (y GE 3) AND (y LT ysize-3) THEN BEGIN ; OPLOT,[x],[y],PSYM=5,COLOR=SELF->get_color(x,y,2),THICK=3 XYOUTS,x,y,' Uranus',COLOR=255, CHARSIZE=2, CHARTHICK=3 XYOUTS,x,y,' Uranus',COLOR=0, CHARSIZE=2, CHARTHICK=1 ENDIF ;;ENDIF WSET,curwin END PRO tiepointer::draw_grid ;------------------------------------------------------- ; Few different methods attempting to plot grid on sun ; surface. None is completely perfect. Needs work. ;------------------------------------------------------- ; This method sort of works. xsize=(SELF.widgetdraw_geom_DRAW_XSIZE)[1] ysize=(SELF.widgetdraw_geom_DRAW_YSIZE)[1] km_sun_radius = 695000L arcsec_pixel = (*SELF.hdr2ptr).CDELT1 IF (STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi') THEN arcsec_pixel = arcsec_pixel * 60 * 60 date_obs = (*SELF.hdr2ptr).DATE_OBS radians_pixel = arcsec_pixel / 60.0 / 60.0 * !DTOR distance = (get_stereo_lonlat(date_obs,'a'))[0] km_pixel = distance * SIN( radians_pixel ) pixels_sun_radius = km_sun_radius / km_pixel curwin=!D.WINDOW WSET,SELF.window1 suncenter_x = ( xsize/2.0 - ((*SELF.secchistruct1ptr).suncenter_xy)[0] ) / pixels_sun_radius suncenter_y = ( ysize/2.0 - ((*SELF.secchistruct1ptr).suncenter_xy)[1] ) / pixels_sun_radius fov=[xsize/pixels_sun_radius,ysize/pixels_sun_radius] DRAW_GRID,[suncenter_x,suncenter_y],fov,(*SELF.hdr1ptr).DATE_OBS,GRIDTYPE=2,/NOERASE,GRIDSEP=15,TILT=(*SELF.hdr1ptr).HGLT_OBS WSET,SELF.window2 suncenter_x = ( xsize/2.0 - ((*SELF.secchistruct2ptr).suncenter_xy)[0] ) / pixels_sun_radius suncenter_y = ( ysize/2.0 - ((*SELF.secchistruct2ptr).suncenter_xy)[1] ) / pixels_sun_radius fov=[xsize/pixels_sun_radius,ysize/pixels_sun_radius] DRAW_GRID,[suncenter_x,suncenter_y],fov,(*SELF.hdr2ptr).DATE_OBS,GRIDTYPE=2,/NOERASE,GRIDSEP=15,TILT=(*SELF.hdr2ptr).HGLT_OBS WSET,curwin ; Initial incomplete attempt to port of sxtsort technique of mapping a grid onto the solar surface. ; CASE SELF.coordinate_system OF ; 0 : BEGIN ; lon_left = (360 - (*SELF.hdr1ptr).HGLN_OBS) MOD 360 ; Stonyhurst Heliographic ; lon_right = (360 - (*SELF.hdr2ptr).HGLN_OBS) MOD 360 ; lat_left = (*SELF.hdr1ptr).HGLT_OBS ; lat_right = (*SELF.hdr2ptr).HGLT_OBS ; END ; 1 : BEGIN ; lon_left = (360 - (*SELF.hdr1ptr).CRLN_OBS) MOD 360 ; Carrington ; lon_right = (360 - (*SELF.hdr2ptr).CRLN_OBS) MOD 360 ; lat_left = (*SELF.hdr1ptr).CRLT_OBS ; lat_right = (*SELF.hdr2ptr).CRLT_OBS ; END ; ENDCASE ; ;xy = [ ((*SELF.secchistruct1ptr).suncenter_xy)[0], $ ; ((*SELF.secchistruct1ptr).suncenter_xy)[1], $ ; ((*SELF.secchistruct2ptr).suncenter_xy)[0], $ ; ((*SELF.secchistruct2ptr).suncenter_xy)[1] ] ;n_samps_left = (*SELF.hdr1ptr).NAXIS1 ;n_lines_left = (*SELF.hdr1ptr).NAXIS2 ; ; scale=1280000000 ; ; WSET,SELF.window1 ;help,lat_left,lon_left,lat_right,lon_right ; map_set, lat_left, lon_left, 0.0, /orthographic, /whole_map, $ ; position = [ 0.08, 0.18, 0.88, 0.98 ], $ ; scale = scale, /noerase, /noborder, /horizon, $ ; color = 234 + 256L * ( 234 + 256L * 234 ) ; ; WSET,SELF.window2 ; map_set, lat_right, lon_right, 0.0, /orthographic, /whole_map, $ ; position = [ 0.08, 0.18, 0.88, 0.98 ], $ ; scale = scale, /noerase, /noborder, /horizon, $ ; color = 234 + 256L * ( 234 + 256L * 234 ) ; DIFFERENT INCOMPLETE ATTEMPT TO PLOT GRID. ;left_euvifilename ='20090613_235830_n4euB.fts' ;right_euvifilename='20090613_235830_n4euA.fts' ;mreadfits,left_euvifilename, left_hdr,left_img ;mreadfits,right_euvifilename, right_hdr,right_img ;imgarr=SCC_STEREOPAIR(right_img,left_img,right_hdr,left_hdr,/CUBIC) ;data=REFORM(imgarr[1,*,*]) ;index=right_hdr ;index2map,index,data,emap ; index,data -> DMZ map object ;plot_map,emap,grid=15,/limb,/log,margin=.05,fov=40,center=[0,0] ;Then, for example: ;wdef,xx,1024,/ur ; make 1024^2 window upper right quadrant ; ;plot_map,emap,grid=15,/limb,/log,margin=.05,fov=40,center=[0,0] ;;(field of view=40 arcmin, centered on [0,0], 15 deg. grid spacing+limb ; ;;Add coordinate lables with /GLABLE switch ;plot_map,emap,grid=15,/glabel,/limb,/log,margin=.05,fov=40,center=[0,0] END PRO tiepointer::plot_all_tiepoints,WINDOW=window,NO_NUMBERS=no_numbers ;------------------------------------------------------- ; Plot all the tiepoints. ;------------------------------------------------------- IF KEYWORD_SET(window) THEN window=window ELSE window=2 ; 0=window1, 1=window2, 2=both windows. IF KEYWORD_SET(no_numbers) THEN no_numbers=1 ELSE no_numbers=0 curwin=!D.WINDOW SELF->setup_plot_space SELF.chain=CHAIN_START_FINDER(SELF.chain) show_tiepoint_numbers_A = (SELF.show_tiepoint_numbers EQ 0) show_tiepoint_numbers_B = (SELF.show_tiepoint_numbers EQ 2) n_chain_links = CHAIN_LINK_COUNTER(SELF.chain) IF (n_chain_links GT 0) THEN BEGIN x_window1=LONARR(n_chain_links) y_window1=LONARR(n_chain_links) x_window2=LONARR(n_chain_links) y_window2=LONARR(n_chain_links) c_window1=LONARR(n_chain_links) c_window2=LONARR(n_chain_links) ENDIF FOR i=0,n_chain_links-1 DO BEGIN CASE no_numbers OF 0 : shownumbers=((show_tiepoint_numbers_A) OR ((show_tiepoint_numbers_B) AND ((i EQ 0) OR (i EQ n_chain_links-1)))) 1 : shownumbers=0 ENDCASE IF (window EQ 0) OR (WINDOW EQ 2) THEN BEGIN x_window1[i]=(*(*SELF.chain).data)[0] y_window1[i]=(*(*SELF.chain).data)[1] c_window1[i]=SELF->get_color(x_window1[i],y_window1[i],1) IF shownumbers THEN BEGIN WSET,SELF.window1 XYOUTS,x_window1[i],y_window1[i],STRTRIM(i+1,2),/DEVICE,COLOR=c_window1[i] ENDIF ENDIF IF (window EQ 1) OR (window EQ 2) THEN BEGIN x_window2[i]=(*(*SELF.chain).data)[2] y_window2[i]=(*(*SELF.chain).data)[3] c_window2[i]=SELF->get_color(x_window2[i],y_window2[i],2) IF shownumbers THEN BEGIN WSET,SELF.window2 XYOUTS,x_window2[i],y_window2[i],STRTRIM(i+1,2),/DEVICE,COLOR=c_window2[i] ENDIF ENDIF IF PTR_VALID((*SELF.chain).next) THEN SELF.chain=(*SELF.chain).next ENDFOR IF (n_chain_links GT 0) THEN BEGIN WSET,SELF.window1 ;print,'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' ;print,'x_window1,y_window1 = ',x_window1,y_window1 ;print,'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' IF (window EQ 0) OR (window EQ 2) THEN PLOTS,x_window1,y_window1,PSYM=7,COLOR=c_window1 WSET,SELF.window2 IF (window EQ 1) OR (window EQ 2) THEN PLOTS,x_window2,y_window2,PSYM=7,COLOR=c_window2 ENDIF IF (SELF.show_reference_points EQ 1) THEN SELF->plot_reference_points IF (SELF.show_grid EQ 1) THEN SELF->draw_grid WSET,curwin END FUNCTION tiepointer::get_window_ndx,event ;------------------------------------------------------- ; Get correct ndx for window1 or window2 tiepoint x,y ; location. ;------------------------------------------------------- RETURN,[0,1]+2*(event.ID EQ SELF.widgetdraw2) END FUNCTION tiepointer::within_tolerance,event ;------------------------------------------------------- ; Determine if the cursor distance to tiepoint is within ; the tolerance. Smaller values can be used for when ; tiepoints are clustered very close together. Largest ; value can be used the rest of the time. ;------------------------------------------------------- ndx=SELF->get_window_ndx(event) IF ((event.X GE (*(*SELF.chain).data)[ndx[0]]-SELF.tolerance) $ AND (event.X LE (*(*SELF.chain).data)[ndx[0]]+SELF.tolerance) $ AND (event.Y GE (*(*SELF.chain).data)[ndx[1]]-SELF.tolerance) $ AND (event.Y LE (*(*SELF.chain).data)[ndx[1]]+SELF.tolerance)) THEN BEGIN within=1 ENDIF ELSE BEGIN within=0 ENDELSE RETURN,within END FUNCTION tiepointer::convert_gamma_value,FORWARD=forward,REVERSE=reverse,IMAGE1=image1,IMAGE2=image2 CASE 1 OF KEYWORD_SET(forward) : BEGIN CASE 1 OF KEYWORD_SET(image1) : BEGIN IF WIDGET_INFO(SELF.image1_gamma_slider,/VALID_ID) THEN WIDGET_CONTROL,SELF.image1_gamma_slider,GET_VALUE=slider_value $ ELSE slider_value=50 CASE 1 OF slider_value LT 50 : RETURN,slider_value/100.0+0.5 ; 0.5-1.0 slider_value GE 50 : RETURN,slider_value/50.0 ; 1.0-2.0 ENDCASE END KEYWORD_SET(image2) : BEGIN IF WIDGET_INFO(SELF.image2_gamma_slider,/VALID_ID) THEN WIDGET_CONTROL,SELF.image2_gamma_slider,GET_VALUE=slider_value $ ELSE slider_value=50 CASE 1 OF slider_value LT 50 : RETURN,slider_value/100.0+0.5 ; 0.5-1.0 slider_value GE 50 : RETURN,slider_value/50.0 ; 1.0-2.0 ENDCASE END ENDCASE END KEYWORD_SET(reverse) : BEGIN CASE 1 OF KEYWORD_SET(image1) : BEGIN IF (SELF.image1_gamma_value LT 1.0) THEN RETURN,FIX(SELF.image1_gamma_value*100-50) ; 0-50 IF (SELF.image1_gamma_value GE 1.0) THEN RETURN,FIX(SELF.image1_gamma_value*50) ; 50-100 END KEYWORD_SET(image2) : BEGIN IF (SELF.image2_gamma_value LT 1.0) THEN RETURN,FIX(SELF.image2_gamma_value*100-50) ; 0-50 IF (SELF.image2_gamma_value GE 1.0) THEN RETURN,FIX(SELF.image2_gamma_value*50) ; 50-100 END ENDCASE END ENDCASE END FUNCTION tiepointer::get_current_datetime_string a=STRSPLIT((SYSTIME()),' ',/EXTRACT) CASE a[1] OF 'Jan' : a[1]='01' 'Feb' : a[1]='02' 'Mar' : a[1]='03' 'Apr' : a[1]='04' 'May' : a[1]='05' 'Jun' : a[1]='06' 'Jul' : a[1]='07' 'Aug' : a[1]='08' 'Sep' : a[1]='09' 'Oct' : a[1]='10' 'Nov' : a[1]='11' 'Dec' : a[1]='12' ENDCASE ; Make sure day is 2 digits. IF (a[2] LT 10) THEN a[2]='0'+a[2] b=STRSPLIT(a[3],':',/EXTRACT) RETURN,a[4]+a[1]+a[2]+'_'+b[0]+b[1]+b[2] END PRO tiepointer::plot_sunloop_trace,xy curwin=!D.WINDOW WSET,SELF.window1 x=xy[0,*] y=xy[1,*] ;color=x ;FOR i=0,N_ELEMENTS(color)-1 DO color[i]=SELF->get_color(x[i],y[i],1) OPLOT,[x],[y],PSYM=3,COLOR=255 ;ROUND(MEAN(color)/255)*255 WSET,SELF.window2 x=xy[2,*] y=xy[3,*] ;FOR i=0,N_ELEMENTS(color)-1 DO color[i]=SELF->get_color(x[i],y[i],1) OPLOT,[x],[y],PSYM=3,COLOR=255 ;ROUND(MEAN(color)/255)*255 ;------------------------------------------------------- ; Second call to OPLOT to force last point in chain to ; get a symbol in the second window when adding a new ; tiepoint. Probably a bug in IDL. (IDL6/6.1, linux ; RH9 and MacOSX 10.3) ;------------------------------------------------------- OPLOT,[x],[y],PSYM=3,COLOR=255 ;ROUND(MEAN(color)/255)*255 WSET,curwin END PRO tiepointer::manage_widgets,event ;------------------------------------------------------- ; This is the event handler for all widgets. ;------------------------------------------------------- CASE TAG_NAMES(event,/STRUCTURE_NAME) OF 'WIDGET_BASE' : BEGIN ;------------------------------------------------------- ; Resize by user. ; (This is tricky to get exactly right. May still need ; fine-tuning.) ;------------------------------------------------------- tlb_geom = WIDGET_INFO(SELF.tlb,/GEOMETRY) buttonbase_geom = WIDGET_INFO(SELF.buttonbase,/GEOMETRY) displaylabel1_geom = WIDGET_INFO(SELF.displaylabel1,/GEOMETRY) new_xsize = (event.X-(tlb_geom.XPAD*7))/2 new_ysize = ((((((event.Y-(tlb_geom.YPAD*5))-buttonbase_geom.YSIZE)-(buttonbase_geom.YPAD*2))-displaylabel1_geom.YSIZE)-(displaylabel1_geom.YPAD*2))) new_xsize = new_xsize < (SELF.widgetdraw_geom_DRAW_XSIZE)[0] new_ysize = new_ysize < (SELF.widgetdraw_geom_DRAW_YSIZE)[0] WIDGET_CONTROL,SELF.widgetdraw1,SCR_XSIZE=new_xsize,SCR_YSIZE=new_ysize WIDGET_CONTROL,SELF.widgetdraw2,SCR_XSIZE=new_xsize,SCR_YSIZE=new_ysize ;------------------------------------------------------- ; Don't let the draw widgets end up being narrower than ; the tlb, which is limited by the buttonbase width. ;------------------------------------------------------- tlb_geom = WIDGET_INFO(SELF.tlb,/GEOMETRY) new_xsize = (tlb_geom.XSIZE-tlb_geom.XPAD*7)/2-3 WIDGET_CONTROL,SELF.widgetdraw1,SCR_XSIZE=new_xsize WIDGET_CONTROL,SELF.widgetdraw2,SCR_XSIZE=new_xsize ;widgetdraw1_geom=WIDGET_INFO(SELF.widgetdraw1,/GEOMETRY) ;widgetdraw2_geom=WIDGET_INFO(SELF.widgetdraw2,/GEOMETRY) ;SELF.widgetdraw_geom_DRAW_XSIZE=[widgetdraw1_geom.DRAW_XSIZE,widgetdraw2_geom.DRAW_XSIZE] ;SELF.widgetdraw_geom_DRAW_YSIZE=[widgetdraw1_geom.DRAW_YSIZE,widgetdraw2_geom.DRAW_YSIZE] END ; Widget base. 'WIDGET_TRACKING' : BEGIN IF (event.ENTER EQ 1) THEN BEGIN ;------------------------------------------------------- ; Mouse is entering the draw widget. Reload the color ; table, just in case. ;------------------------------------------------------- SELF->load_color_table ;;; TVLCT, *(SELF.red_table_ptr), $ ;;; *(SELF.grn_table_ptr), $ ;;; *(SELF.blu_table_ptr) ENDIF END ; Widget tracking. 'WIDGET_DRAW' : BEGIN ;------------------------------------------------------- ; Read pixel values from array1 when in widget_draw 0. ; Read pixel values from array2 when in widget_draw 1. ;------------------------------------------------------- x = STRTRIM(event.X,2) y = STRTRIM(event.Y,2) ;------------------------------------------------------- ; Set variable to search for tiepoint when moving is ; starting. ;------------------------------------------------------- IF (event.RELEASE GE 2) THEN BEGIN SELF.new_x_tp_location=-1 SELF.new_y_tp_location=-1 SELF.keep_checking=1 ENDIF ;------------------------------------------------------- ; Only update the readouts if the computer is fast ; enough to not slow down tiepoint moving. If computer ; is slow, then update readouts only on button release. ;------------------------------------------------------- print,'TIEPOINTER - here 00000' print,'SELF.mouse_button_is_down = ',SELF.mouse_button_is_down IF ((SELF.mouse_button_is_down EQ 0) OR (event.RELEASE GE 2) OR ((SELF.mouse_button_is_down EQ 2) AND ((SELF.computer EQ SELF.computer_fast) OR (SELF.computer EQ SELF.computer_medium)))) THEN BEGIN CASE ((SELF->get_window_ndx(event))[*]/2)[0] OF 0 : wcs=*SELF.wcs1ptr 1 : wcs=*SELF.wcs2ptr ENDCASE coord=WCS_GET_COORD( wcs, [event.x,event.y] ) ; SELF.coordinate_system is 0 for Stonyhurst, and 1 for Carrington. WCS_CONVERT_FROM_COORD, wcs, coord, 'HG', lon, lat, CARRINGTON=SELF.coordinate_system lon_deg=STRTRIM(lon,2) lat_deg=STRTRIM(lat,2) linesamp = SELF->convert_xy_into_linesamp([x,y,x,y]) line = STRTRIM(FIX(linesamp[0]),2) samp = STRTRIM(FIX(linesamp[1]),2) CASE ((SELF->get_window_ndx(event))[*]/2)[0] OF 0 : BEGIN IF SIZE(*SELF.raw_array1_ptr,/TYPE) EQ 1 THEN BEGIN dn_value = STRTRIM(FIX((*SELF.raw_array1_ptr)[x,y]),2) ENDIF ELSE BEGIN dn_value = STRTRIM((*SELF.raw_array1_ptr)[x,y],2) ENDELSE END 1 : BEGIN IF SIZE(*SELF.raw_array2_ptr,/TYPE) EQ 1 THEN BEGIN dn_value = STRTRIM(FIX((*SELF.raw_array2_ptr)[x,y]),2) ENDIF ELSE BEGIN dn_value = STRTRIM((*SELF.raw_array2_ptr)[x,y],2) ENDELSE END ENDCASE WIDGET_CONTROL,SELF.value_label1,SET_VALUE=STRING(' line,samp = ',line,', ',samp,' ') WIDGET_CONTROL,SELF.value_label2,SET_VALUE=STRING(' x,y = ',x,', ',y,' ') WIDGET_CONTROL,SELF.value_label3,SET_VALUE=STRING(' lon,lat = ',lon_deg,', ',lat_deg,' ') WIDGET_CONTROL,SELF.value_label4,SET_VALUE=STRING(' value = ',dn_value,' ') ENDIF ;------------------------------------------------------- ; Remember the mouse button status, regardless of which ; mouse button or which draw window it is. ;------------------------------------------------------- print,'TIEPOINTER - here 0000' print,'event.TYPE = ',event.TYPE print,'event.PRESS = ',event.PRESS IF (event.TYPE EQ 0) AND (event.PRESS GE 1) THEN BEGIN SELF.mouse_button_is_down = event.PRESS print,'TIEPOINTER - here 000' print,'SELF.mouse_button_is_down = ',SELF.mouse_button_is_down ;------------------------------------------------------- ; Middle button is being pressed, switch TYPE to 2 so ; that it thinks motion is occuring ;------------------------------------------------------- IF (event.PRESS EQ 2) THEN event.TYPE = 2 ; IF (event.MODIFIERS EQ 2) THEN event.TYPE = 2 ENDIF IF (event.TYPE EQ 1) AND (event.RELEASE GE 2) THEN BEGIN SELF.mouse_button_is_down = 0 print,'TIEPOINTER - here 00' print,'SELF.mouse_button_is_down = ',SELF.mouse_button_is_down IF (event.RELEASE EQ 2) THEN BEGIN SELF.initialize_cursor2tiepoint_offset=1 ENDIF ; Do redraw only on mouse release, to speed up moving tiepoints. SELF->redraw SELF->plot_all_tiepoints ENDIF print,'TIEPOINTER - here 0' print,'SELF.mouse_button_is_down = ',SELF.mouse_button_is_down print,'PTR_VALID(SELF.chain) = ',PTR_VALID(SELF.chain) CASE 1 OF ;------------------------------------------------------- ; Move tiepoint on middle mouse button drag motion. ;------------------------------------------------------- ( (SELF.mouse_button_is_down EQ 2) AND PTR_VALID(SELF.chain) ) : BEGIN print,'TIEPOINTER - here 1' ;------------------------------------------------------- ; Position the current chain link at the first tiepoint ; found near the cursor, if it's distance (cursor to ; tiepoint) is within the tolerance. ;------------------------------------------------------- ndx=SELF->get_window_ndx(event) IF (SELF.keep_checking EQ 1) THEN BEGIN print,'TIEPOINTER - here 2' SELF.chain=CHAIN_START_FINDER(SELF.chain) ; SELF.keep_checking=1 WHILE SELF.keep_checking DO BEGIN IF SELF->within_tolerance(event) THEN BEGIN SELF.keep_checking=0 ENDIF ELSE BEGIN IF PTR_VALID((*SELF.chain).next) THEN BEGIN SELF.chain=(*SELF.chain).next ENDIF ELSE BEGIN SELF.keep_checking=0 ENDELSE ENDELSE ENDWHILE ENDIF ELSE BEGIN print,'TIEPOINTER - here 3' ;------------------------------------------------------- ; Get back to the chain link we were using (because ; plot_all_tiepoints leaves the chain at the last link.) ;------------------------------------------------------- SELF.chain=CHAIN_START_FINDER(SELF.chain) nlinks=CHAIN_LINK_COUNTER(SELF.chain) FOR link=0,nlinks-1 DO BEGIN IF (SELF.new_x_tp_location GE 0) AND (SELF.new_y_tp_location GE 0) THEN BEGIN IF ((*(*SELF.chain).data)[ndx[0]] EQ SELF.new_x_tp_location) AND ((*(*SELF.chain).data)[ndx[1]] EQ SELF.new_y_tp_location) THEN BEGIN ;print,'bingo' BREAK ENDIF ELSE BEGIN SELF.chain=(*SELF.chain).next ENDELSE ENDIF ENDFOR ENDELSE print,'TIEPOINTER - here 4' IF (SELF.keep_checking EQ 0) THEN BEGIN print,'TIEPOINTER - here 5' IF (SELF.initialize_cursor2tiepoint_offset EQ 1) THEN BEGIN print,'TIEPOINTER - here 6' SELF.x_cursor2tiepoint_offset=event.X-(*(*SELF.chain).data)[ndx[0]] SELF.y_cursor2tiepoint_offset=event.Y-(*(*SELF.chain).data)[ndx[1]] SELF.initialize_cursor2tiepoint_offset=0 ENDIF ;------------------------------------------------------- ; Update the tiepoint position. Verify the cursor has ; not moved off the image area. IF IMAGES ARE ; ROTATED HORIZONTAL TO THE STEREO BASELINE, THEN ; CONSTRAIN THE Y-AXIS MOVEMENT. ;------------------------------------------------------- SELF.new_x_tp_location=event.X-SELF.x_cursor2tiepoint_offset SELF.new_y_tp_location=event.Y-SELF.y_cursor2tiepoint_offset IF (SELF.rotate EQ 'to stereo baseline') THEN SELF.new_y_tp_location=((*(*SELF.chain).data)[ndx])[1] ; KEEP Y-AXIS CONSTANT. ; ; First, convert X,Y to LON,LAT. Do this for each spacecraft. ; CASE ndx OF ; 0 : BEGIN ; wcs=*SELF.wcs1ptr ; hdr=*SELF.hdr1ptr ; END ; 1 : BEGIN ; wcs=*SELF.wcs2ptr ; hdr=*SELF.hdr2ptr ; END ; ENDCASE ; coord_new=WCS_GET_COORD( wcs, [SELF.new_x_tp_location,SELF.new_y_tp_location] ) ; coord_old=WCS_GET_COORD( wcs, [(*(*SELF.chain).data)[ndx[0]],(*(*SELF.chain).data)[ndx[1]]] ) print,'TIEPOINTER - here 7' IF ((SELF.new_x_tp_location GE 0) AND (SELF.new_x_tp_location LT (SELF.widgetdraw_geom_DRAW_XSIZE)[ndx[0]/2]) $ AND (SELF.new_y_tp_location GE 0) AND (SELF.new_y_tp_location LT (SELF.widgetdraw_geom_DRAW_YSIZE)[ndx[1]/2])) THEN BEGIN ;print,'--------------------------------------------------------------------------------------------------' ;print,'SELF.x_cursor2tiepoint_offset,SELF.y_cursor2tiepoint_offset = ',SELF.x_cursor2tiepoint_offset,SELF.y_cursor2tiepoint_offset ;print,'SELF.new_x_tp_location,SELF.new_y_tp_location = ',SELF.new_x_tp_location,SELF.new_y_tp_location ;print,'(*(*SELF.chain).data)['+string(ndx)+'] = '+string((*(*SELF.chain).data)[ndx]) (*(*SELF.chain).data)[ndx]=[SELF.new_x_tp_location,SELF.new_y_tp_location] ;print,'(*(*SELF.chain).data)['+string(ndx)+'] = '+string((*(*SELF.chain).data)[ndx]) ;print,'--------------------------------------------------------------------------------------------------' start_time=SYSTIME(/SECONDS) CASE SELF.computer OF SELF.computer_fast : BEGIN print,'TIEPOINTER - here 8' ;------------------------------------------------------- ; For deluxe results on a fast computer (maybe 3 GHz or ; faster), do BOTH redraw AND plot_all_tiepoints for ; every move event. ;------------------------------------------------------- SELF->redraw SELF->plot_all_tiepoints,/NO_NUMBERS,WINDOW=ndx[0]/2 ;------------------------------------------------------- ; Dis-allow moving tiepoints if computer is too slow to handle the ; redraw requirement at the current "Computer Speed" setting. Lowering ; the "Computer Speed" setting reduces the overhead required for a ; redraw event and thus improving the apparent performance. The lowest ; setting will always allow moving tiepoints even if it's very slow. ;------------------------------------------------------- IF ((SYSTIME(/SECONDS) - start_time) GT SELF.computer_thresh) AND (SELF.computer_automatic EQ 1) THEN BEGIN ;------------------------------------------------------- ; Tiepointer tool is initialized with a "Computer Speed" ; setting of FAST. Automically downgrade this setting if ; redraw speed is found to be slow. This setting controls ; the extent of operations performed per redraw event. ;------------------------------------------------------- SELF.preferences_map=0 SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.preferences_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.computer_medium_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF.preferences_map=1 SELF->redraw SELF->plot_all_tiepoints ; ddddd=DIALOG_MESSAGE(['Moving tiepoints is slow on this computer.', $ ; 'Computer Speed preference has been automatically downgraded to MEDIUM.', $ ; 'Downgrading will improve apparent performance by reducing the extent of operations performed per redraw event.', $ ; 'Manually upgrading this setting will disable automatic downgrading, so if it becomes slow you will have to manually downgrade it.']) ENDIF END SELF.computer_medium : BEGIN print,'TIEPOINTER - here 9' ;------------------------------------------------------- ; To speed up moving tiepoints, ONLY do plot_all_tiepoints. ; (redraw only on mouse release.) ;------------------------------------------------------- SELF->plot_all_tiepoints,/NO_NUMBERS,WINDOW=ndx[0]/2 ;------------------------------------------------------- ; Dis-allow moving tiepoints if computer is too slow to handle the ; redraw requirement at the current "Computer Speed" setting. Lowering ; the "Computer Speed" setting reduces the overhead required for a ; redraw event and thus improving the apparent performance. The lowest ; setting will always allow moving tiepoints even if it's very slow. ;------------------------------------------------------- IF ((SYSTIME(/SECONDS) - start_time) GT SELF.computer_thresh) AND (SELF.computer_automatic EQ 1) THEN BEGIN ;------------------------------------------------------- ; Automically downgrade the "Computer Speed" setting if ; redraw speed is found to be slow. This setting controls ; the extent of operations performed per redraw event. ;------------------------------------------------------- SELF.preferences_map=0 SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.preferences_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.computer_slow_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF.preferences_map=1 SELF->redraw SELF->plot_all_tiepoints ; ddddd=DIALOG_MESSAGE(['Moving tiepoints is slow on this computer.', $ ; 'Computer Speed preference has been automatically downgraded to SLOW.', $ ; 'Downgrading will improve apparent performance by reducing the extent of operations performed per redraw event.', $ ; 'Manually upgrading this setting will disable automatic downgrading, so if it becomes slow you will have to manually downgrade it.']) ENDIF END SELF.computer_slow : BEGIN print,'TIEPOINTER - here 10' ;------------------------------------------------------- ; To speed up moving tiepoints even more (necessary on ; Mac G4 laptop), instead do a simple PLOTS of new ; location for the current tiepoint only. (Don't do ; redraw or plot_all_tiepoints, and redraw only on mouse ; release.) ;------------------------------------------------------- xy=(*(*SELF.chain).data) curwin=!D.WINDOW WSET,SELF.window1 PLOTS,xy[0],xy[1],PSYM=7,COLOR=SELF->get_color(SELF.new_x_tp_location,SELF.new_y_tp_location,1) WSET,SELF.window2 PLOTS,xy[2],xy[3],PSYM=7,COLOR=SELF->get_color(SELF.new_x_tp_location,SELF.new_y_tp_location,2) WSET,curwin END ENDCASE ENDIF ENDIF ; SELF.keep_checking=0 ; ENDIF ELSE BEGIN ; IF PTR_VALID((*SELF.chain).next) THEN BEGIN ; SELF.chain=(*SELF.chain).next ; ENDIF ELSE BEGIN ; SELF.keep_checking=0 ; ENDELSE ; ENDELSE ; ENDWHILE print,'TIEPOINTER - here 11' END ;------------------------------------------------------- ; Arrow keys to move cursor by 1 pixel increments. ;------------------------------------------------------- ((event.KEY GT 0) OR (event.CH GT 0)) : BEGIN ; ARROW KEYS ARE A WORK IN PROGRESS... ;PRINT,event.KEY,event.CH,'!D.WINDOW=',!D.WINDOW END ;------------------------------------------------------- ; Add tiepoint on left mouse button press. ; Draw it in both windows ;------------------------------------------------------- (event.TYPE EQ 0 AND event.PRESS EQ 1 AND event.RELEASE EQ 0) : BEGIN xsize=(SELF.widgetdraw_geom_DRAW_XSIZE)[0] ysize=(SELF.widgetdraw_geom_DRAW_YSIZE)[0] CASE event.ID OF ; Position the tiepoint at event.X/Y in the selected window, and (if sun centers are in frame) calculate ; the position in the opposite window based on the difference between sun centers. SELF.widgetdraw1 : BEGIN x_left=event.X y_left=event.Y ; Add new tiepoint close to existing tiepoint set, as defined by first tiepoint in chain. IF PTR_VALID(SELF.chain) THEN BEGIN SELF.chain=CHAIN_START_FINDER(SELF.chain) xy=*(*SELF.chain).data x_center_diff=xy[0]-xy[2] y_center_diff=xy[1]-xy[3] ENDIF ELSE BEGIN ; If this is first tiepoint to be added, use diffference between sun center locations. x_center_diff=((*SELF.secchistruct2ptr).suncenter_xy)[0]-((*SELF.secchistruct1ptr).suncenter_xy)[0] y_center_diff=((*SELF.secchistruct2ptr).suncenter_xy)[1]-((*SELF.secchistruct1ptr).suncenter_xy)[1] ENDELSE x_right=event.X-ROUND(x_center_diff) IF (x_right LT 0) OR (x_right GE xsize) THEN x_right=event.X y_right=event.Y-ROUND(y_center_diff) IF (y_right LT 0) OR (y_right GE ysize) THEN y_right=event.Y END SELF.widgetdraw2 : BEGIN x_right=event.X y_right=event.Y IF PTR_VALID(SELF.chain) THEN BEGIN SELF.chain=CHAIN_START_FINDER(SELF.chain) xy=*(*SELF.chain).data x_center_diff=xy[2]-xy[0] y_center_diff=xy[3]-xy[1] ENDIF ELSE BEGIN x_center_diff=((*SELF.secchistruct2ptr).suncenter_xy)[0]-((*SELF.secchistruct1ptr).suncenter_xy)[0] y_center_diff=((*SELF.secchistruct2ptr).suncenter_xy)[1]-((*SELF.secchistruct1ptr).suncenter_xy)[1] ENDELSE x_left=event.X-ROUND(x_center_diff) IF (x_left LT 0) OR (x_left GE xsize) THEN x_left=event.X y_left=event.Y-ROUND(y_center_diff) IF (y_left LT 0) OR (y_left GE ysize) THEN y_left=event.Y END ENDCASE SELF.chain=CHAIN_LINK_ADD(SELF.chain,[x_left,y_left,x_right,y_right]) ;UNNECESSARY TO REDRAW IMAGES SIMPLY TO ADD ONE NEW TIEPOINT. ; SELF->redraw SELF->plot_all_tiepoints END ;------------------------------------------------------- ; Delete tiepoint on right mouse button press. ; Remove it from the screen. ;------------------------------------------------------- ((event.TYPE EQ 0 AND event.PRESS EQ 4) AND PTR_VALID(SELF.chain)) : BEGIN ;------------------------------------------------------- ; Position the current chain link at the first tiepoint ; found near the cursor, if it's distance (cursor to ; tiepoint) is within the tolerance. ;------------------------------------------------------- SELF.chain=CHAIN_START_FINDER(SELF.chain) keep_checking=1 WHILE ((keep_checking GE 1) AND PTR_VALID(SELF.chain)) DO BEGIN IF SELF->within_tolerance(event) THEN BEGIN ;------------------------------------------------------- ; The keep_checking variable is used to keep track of ; which tiepoint number is currently being checked. ;------------------------------------------------------- mssg='Delete tiepoint '+STRTRIM(keep_checking,2)+'?' confirm=DIALOG_MESSAGE(mssg,/QUESTION,DIALOG_PARENT=SELF.tlb) IF (STRUPCASE(confirm) EQ 'YES') THEN BEGIN ;------------------------------------------------------- ; Delete the tiepoint. ;------------------------------------------------------- SELF.chain=CHAIN_LINK_DELETE(SELF.chain) SELF->redraw IF PTR_VALID(SELF.chain) THEN $ SELF->plot_all_tiepoints ENDIF keep_checking=0 ENDIF ELSE BEGIN IF PTR_VALID((*SELF.chain).next) THEN BEGIN SELF.chain=(*SELF.chain).next keep_checking=keep_checking+1 ENDIF ELSE BEGIN keep_checking=0 ENDELSE ENDELSE ENDWHILE END ELSE : BEGIN END ENDCASE END ; Widget draw. 'WIDGET_TEXT_CH' : BEGIN ; This happens for every character typed because /ALL_EVENTS is turned on. WIDGET_CONTROL,event.ID,GET_VALUE=newval newval=STRTRIM(newval,2) CASE event.ID OF SELF.image1_min_field : BEGIN CASE VALID_NUM(newval) OF 0 : BEGIN ; Allow these ascii characters ['-','+','.','e','E'] but reject all other non-numbers. IF (STRPOS(newval,'-') LT 0) AND (STRPOS(newval,'+') LT 0) AND (STRPOS(newval,'.') LT 0) AND (STRLOWCASE(STRPOS(newval,'e')) LT 0) THEN BEGIN ; Revert to stored value. IF (SIZE(newval,/TYPE) EQ 1) THEN BEGIN WIDGET_CONTROL,SELF.image1_min_field,SET_VALUE=STRTRIM(FIX(SELF.image1_min_value),2) ENDIF ELSE BEGIN WIDGET_CONTROL,SELF.image1_min_field,SET_VALUE=STRTRIM(SELF.image1_min_value,2) ENDELSE ENDIF END 1 : BEGIN SELF.image1_min_value=DOUBLE(newval) END ENDCASE END SELF.image1_max_field : BEGIN CASE VALID_NUM(newval) OF 0 : BEGIN ; Allow these ascii characters ['-','+','.','e','E'] but reject all other non-numbers. IF (STRPOS(newval,'-') LT 0) AND (STRPOS(newval,'+') LT 0) AND (STRPOS(newval,'.') LT 0) AND (STRLOWCASE(STRPOS(newval,'e')) LT 0) THEN BEGIN IF (SIZE(newval,/TYPE) EQ 1) THEN BEGIN WIDGET_CONTROL,SELF.image1_max_field,SET_VALUE=STRTRIM(FIX(SELF.image1_max_value),2) ENDIF ELSE BEGIN WIDGET_CONTROL,SELF.image1_max_field,SET_VALUE=STRTRIM(SELF.image1_max_value,2) ENDELSE ENDIF END 1 : BEGIN SELF.image1_max_value=DOUBLE(newval) END ENDCASE END SELF.image2_min_field : BEGIN CASE VALID_NUM(newval) OF 0 : BEGIN ; Allow these ascii characters ['-','+','.','e','E'] but reject all other non-numbers. IF (STRPOS(newval,'-') LT 0) AND (STRPOS(newval,'+') LT 0) AND (STRPOS(newval,'.') LT 0) AND (STRLOWCASE(STRPOS(newval,'e')) LT 0) THEN BEGIN IF (SIZE(newval,/TYPE) EQ 1) THEN BEGIN WIDGET_CONTROL,SELF.image2_min_field,SET_VALUE=STRTRIM(FIX(SELF.image2_min_value),2) ENDIF ELSE BEGIN WIDGET_CONTROL,SELF.image2_min_field,SET_VALUE=STRTRIM(SELF.image2_min_value,2) ENDELSE ENDIF END 1 : BEGIN SELF.image2_min_value=DOUBLE(newval) END ENDCASE END SELF.image2_max_field : BEGIN CASE VALID_NUM(newval) OF 0 : BEGIN ; Allow these ascii characters ['-','+','.','e','E'] but reject all other non-numbers. IF (STRPOS(newval,'-') LT 0) AND (STRPOS(newval,'+') LT 0) AND (STRPOS(newval,'.') LT 0) AND (STRLOWCASE(STRPOS(newval,'e')) LT 0) THEN BEGIN IF (SIZE(newval,/TYPE) EQ 1) THEN BEGIN WIDGET_CONTROL,SELF.image2_max_field,SET_VALUE=STRTRIM(FIX(SELF.image2_max_value),2) ENDIF ELSE BEGIN WIDGET_CONTROL,SELF.image2_max_field,SET_VALUE=STRTRIM(SELF.image2_max_value,2) ENDELSE ENDIF END 1 : BEGIN SELF.image2_max_value=DOUBLE(newval) END ENDCASE END ELSE: ENDCASE END ; Widget Text. 'WIDGET_BUTTON' : BEGIN WIDGET_CONTROL,SELF.tlb,SENSITIVE=0 WIDGET_CONTROL,/HOURGLASS ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; SCC_TRIANGULATE BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF (event.id EQ SELF.scc_triangulate_button) THEN BEGIN ;------------------------------------------------------- ; Make sure there is at least 1 tiepoint before proceeding. ;------------------------------------------------------- IF (PTR_VALID(SELF.chain) EQ 0) THEN BEGIN r=DIALOG_MESSAGE('No tiepoints. Must have at least 1 tiepoint to run SCC_TRIANGULATE.',/INFORMATION) WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 BREAK ENDIF ; IF (CHAIN_LINK_COUNTER(SELF.chain) EQ 1) THEN BEGIN ; r=DIALOG_MESSAGE('Single tiepoint. Must have multiple tiepoints to run SCC_TRIANGULATE.',/INFORMATION) ; WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 ; BREAK ; ENDIF ;------------------------------------------------------- ; Autosave tiepoints with timestamp in filename. ;------------------------------------------------------- current_datetime_string=SELF->get_current_datetime_string() SELF.chain=CHAIN_START_FINDER(SELF.chain) xy_filename='tiepoints_'+FILE_BASENAME(SELF.right_filename)+'_saved_'+current_datetime_string+'.xy' xyz_filename=xy_filename+'z' OPENW,lun,xy_filename,/GET_LUN IF PTR_VALID(SELF.chain) THEN BEGIN keep_writing=1 ENDIF ELSE BEGIN keep_writing=0 ENDELSE WHILE (keep_writing EQ 1) DO BEGIN ;------------------------------------------------------- ; Misnomer: Although this tiepointer program uses x,y ; the xyzsun program deals with line,samp. ; ; When writing the file, convert x,y --> line,samp. ;------------------------------------------------------- xy=*(*SELF.chain).data linesamp=SELF->convert_xy_into_linesamp(xy) PRINTF,lun,linesamp IF PTR_VALID((*SELF.chain).next) THEN BEGIN SELF.chain=(*SELF.chain).next ENDIF ELSE BEGIN keep_writing=0 ENDELSE ENDWHILE FREE_LUN,lun ;------------------------------------------------------- ; x=zero longitude/latitude ; y=zero lat, 90 degrees longitude ; z=north ; Output .xyz filename has same timestamp as input .xy filename. ;------------------------------------------------------- ;------------------------------------------------------- ; Get size of left image (assume both images are the same size.) ; SECCHI spacecraft: 1=B=Left, 2=A=Right ;------------------------------------------------------- xy = [ ((*SELF.secchistruct1ptr).suncenter_xy)[0], $ ((*SELF.secchistruct1ptr).suncenter_xy)[1], $ ((*SELF.secchistruct2ptr).suncenter_xy)[0], $ ((*SELF.secchistruct2ptr).suncenter_xy)[1] ] linesamp = SELF->convert_xy_into_linesamp(xy) center_line_left = linesamp[0] center_samp_left = linesamp[1] center_line_right = linesamp[2] center_samp_right = linesamp[3] north_angle_left = (*SELF.secchistruct1ptr).solar_north_angle north_angle_right = (*SELF.secchistruct2ptr).solar_north_angle focal_length_in_pixels_left = ((*SELF.secchistruct1ptr).focal_length_in_pixels)[0] ;x/y [0|1] assumed to be same. focal_length_in_pixels_right = ((*SELF.secchistruct2ptr).focal_length_in_pixels)[0] ;x/y [0|1] assumed to be same. CASE SELF.coordinate_system OF 0 : BEGIN lon_left = 360 - (*SELF.hdr1ptr).HGLN_OBS ; Stonyhurst Heliographic lon_right = 360 - (*SELF.hdr2ptr).HGLN_OBS lat_left = (*SELF.hdr1ptr).HGLT_OBS lat_right = (*SELF.hdr2ptr).HGLT_OBS END 1 : BEGIN lon_left = 360 - (*SELF.hdr1ptr).CRLN_OBS ; Carrington lon_right = 360 - (*SELF.hdr2ptr).CRLN_OBS lat_left = (*SELF.hdr1ptr).CRLT_OBS lat_right = (*SELF.hdr2ptr).CRLT_OBS END ENDCASE OPENW,lun,xyz_filename,/GET_LUN PRINTF,lun,' Image dimensions= '+STRTRIM((*SELF.hdr1ptr).NAXIS1,2)+' '+STRTRIM((*SELF.hdr1ptr).NAXIS1,2)+' pixels' PRINTF,lun,' Spacecraft ranges= '+STRTRIM((*SELF.hdr1ptr).DSUN_OBS/1000,2)+' '+STRTRIM((*SELF.hdr2ptr).DSUN_OBS/1000,2)+' km' PRINTF,lun,' Sub spacecraft solar latitudes= '+STRTRIM(lat_left,2)+' '+STRTRIM(lat_right,2)+' degrees' PRINTF,lun,' Sub spacecraft solar longitudes= '+STRTRIM(lon_left,2)+' '+STRTRIM(lon_right,2)+' degrees west' PRINTF,lun,' Solar radius, pole= 695990. equator= 695990. km' PRINTF,lun,' Solar center1 line= '+STRTRIM(center_line_left,2)+' sample= '+STRTRIM(center_samp_left,2) PRINTF,lun,' Solar center1 line= '+STRTRIM(center_line_right,2)+' sample= '+STRTRIM(center_samp_right,2) PRINTF,lun,' Solar north angle= '+STRTRIM(north_angle_left,2)+' '+STRTRIM(north_angle_right,2)+' deg clock from up' PRINTF,lun,' Focal lengths= '+STRTRIM(focal_length_in_pixels_left,2)+' '+STRTRIM(focal_length_in_pixels_right,2)+' mm' ;Focal lengths= 16067.481 14225.159 mm PRINTF,lun,' Camera scale= 1. pixels/mm' PRINTF,lun,' Camera axis line= '+STRTRIM((*SELF.hdr1ptr).NAXIS1/2.,2)+' sample= '+STRTRIM((*SELF.hdr1ptr).NAXIS2/2.,2) PRINTF,lun,' linel sampl liner sampr X Y Z lat lon R/Rsun error' tiepoints=(READ_ASCII(xy_filename,COUNT=tp_count)).(0) coord = DBLARR(tp_count,3) FOR tp=0,tp_count-1 DO BEGIN ; Convert tiepoints from [LINE,SAMP] values to [X,Y] values. tp_a = FLTARR(2) tp_b = FLTARR(2) tp_a[0] = tiepoints[3,tp] tp_a[1] = (*SELF.hdr2ptr).NAXIS2 - tiepoints[2,tp] tp_b[0] = tiepoints[1,tp] tp_b[1] = (*SELF.hdr1ptr).NAXIS2 - tiepoints[0,tp] ; First, convert X,Y to LON,LAT. Do this for each spacecraft. system=(['Stonyhurst','Carrington'])[SELF.coordinate_system] IF ( STRUPCASE(system) EQ 'STONYHURST' ) THEN system = 'HEEQ' wcs1=FITSHEAD2WCS(*SELF.hdr1ptr, COORD_TYPE=system ) wcs2=FITSHEAD2WCS(*SELF.hdr2ptr, COORD_TYPE=system ) coord1=WCS_GET_COORD( wcs1, tp_b ) coord2=WCS_GET_COORD( wcs2, tp_a ) ; Second, convert LON,LAT to X,Y,Z with SCC_TRIANGULATE. This can be done for all points at once or one point at a time, either way. scc_tri_coord = SCC_TRIANGULATE( (*SELF.hdr1ptr).DATE_OBS, coord2, coord1, error, SYSTEM=system ) ; Account for HI. coord[tp,*] = scc_tri_coord * MAX([1,(3600*(STRLOWCASE(STRMID(SELF.detector,0,2)) EQ 'hi'))]) ; Convert [X,Y,Z] to rad,lon,lat. CSPICE_RECLAT, REFORM(coord[tp,*]), radius, longitude, latitude solar_radius_km=(6.96e08/1000) ; Solar Radius == 6.960 x 10^8 meters r_rsun=radius/solar_radius_km lat_deg=latitude*!RADEG lon_deg=(360+longitude*!RADEG) MOD 360 PRINTF,lun,tiepoints[*,tp],REFORM(coord[tp,*]),lat_deg,lon_deg,r_rsun,error,FORMAT='(4(F11.2),3(D13.0),3(D11.4),1(D11.0))' ENDFOR PRINTF,lun,'-9999 (flag to start metadata)' PRINTF,lun,(['Stonyhurst','Carrington'])[SELF.coordinate_system] PRINTF,lun,STRTRIM((*SELF.hdr1ptr).WAVELNTH,2) PRINTF,lun,SELF.left_filename +' (left)' PRINTF,lun,SELF.right_filename+' (right)' PRINTF,lun,'Image Rotation: '+STRTRIM(SELF.rotate,2) PRINTF,lun,'Tiepoint pair to XYZ point calculation performed with SCC_TRIANGULATE' FREE_LUN,lun ;------------------------------------------------------- ; Call xyz viewing widget LINE3D. ;------------------------------------------------------- IF (FILE_SEARCH(xyz_filename) EQ '') THEN BEGIN ddddd=DIALOG_MESSAGE(['xyz file:',xyz_filename,'not found']) WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 RETURN ENDIF ascii=READ_ASCII(xyz_filename,DATA_START=12) metadata_start=WHERE((ascii.(0))[0,*] EQ -9999) xyz=ascii.(0)[4:6,0:metadata_start-1] ; Normalize xyz to unit sphere. solar_radius_km=(6.96e08/1000) ; Solar Radius == 6.960 x 10^8 meters xyz=xyz/solar_radius_km date=(STRSPLIT((*SELF.hdr1ptr).DATE_OBS,'T',/EXTRACT))[0] time=(STRSPLIT((*SELF.hdr1ptr).DATE_OBS,'T',/EXTRACT))[1] date=(STRSPLIT(date,'-',/EXTRACT))[0]+(STRSPLIT(date,'-',/EXTRACT))[1]+(STRSPLIT(date,'-',/EXTRACT))[2] time=(STRSPLIT(time,':',/EXTRACT))[0]+(STRSPLIT(time,':',/EXTRACT))[1]+STRMID((STRSPLIT(time,':',/EXTRACT))[2],0,2) ddddd=DIALOG_MESSAGE(['xyz computation complete.','Show in viewer?'],/QUESTION) IF (STRUPCASE(ddddd) EQ 'YES') THEN BEGIN LINE3D,xyz,xyz_filename,SELF.tlb,TIMESTEPS=date+'_'+time ENDIF WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; SCC_MEASURE BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF (event.id EQ SELF.scc_measure_button) THEN BEGIN ; STEREO-A (right) filename comes first, followed by STEREO-B (left). ;------------------------------------------------------- ; Save tiepoint file with timestamp in filename. ;------------------------------------------------------- answer='yes' IF (STRLOWCASE(SELF.rotate) NE 'no') THEN BEGIN answer=DIALOG_MESSAGE([ 'Current image pair is rotated.', $ 'SCC_MEASURE tiepoints are not compatable with rotated images.', $ '', $ '(You may proceed to select tiepoints with SCC_MEASURE but...', $ 'it will be necessary to reload the tiepointer with un-rotated', $ 'images before reading those tiepoints.)', $ '', $ 'Proceed with SCC_MEASURE?'],/QUESTION) ENDIF IF (STRLOWCASE(answer) EQ 'yes') THEN BEGIN current_datetime_string=SELF->get_current_datetime_string() xy_filename='tiepoints_'+FILE_BASENAME(SELF.right_filename)+'_saved_'+current_datetime_string+'.xy_scc_measure' CALL_PROCEDURE,'scc_measure',SELF.right_filename,SELF.left_filename,OUTFILE=xy_filename,/NO_BLOCK,/SECCHIPREP,/PRECOMMCORRECT_ON ENDIF ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; READ TIEPOINTS BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF (event.id EQ SELF.read_tiepoint_file_button) THEN BEGIN ;------------------------------------------------------- ; Read file where each line is a tiepoint, formatted: ; line1 samp1 line2 samp2 ;------------------------------------------------------- ok_to_read_file=0 CASE 1 OF (SELF.xy_filename EQ '') : BEGIN ;------------------------------------------------------- ; Read tiepoint file manually as usual. ; (SELF.xy_filename will only be set if xy filename ; is passed from sunloop command line.) ;------------------------------------------------------- filenames=DIALOG_PICKFILE(/READ,FILTER='*.xy',/MULTIPLE_FILES) END ELSE : BEGIN ;------------------------------------------------------- ; If xy_filename was passed in from sunloop command line, ; then initialize tiepointer with these tiepoints. In this ; case, the READ TIEPOINTS BUTTON event is being triggered ; automatically. ;------------------------------------------------------- filenames=SELF.xy_filename END ENDCASE FOR file=0,N_ELEMENTS(filenames)-1 DO BEGIN filename=filenames[file] IF (filename NE '') AND FILE_EXIST(filename) THEN BEGIN ;AND (STRMID(filename,1,2,/REVERSE_OFFSET) EQ 'xy') ok_to_read_file=1 ENDIF IF (ok_to_read_file EQ 1) THEN BEGIN IF (file EQ 0) AND PTR_VALID(SELF.chain) THEN BEGIN mssg='Discard current set of tiepoints?' confirm=DIALOG_MESSAGE(mssg,/QUESTION,DIALOG_PARENT=SELF.tlb) IF (STRUPCASE(confirm) EQ 'YES') THEN BEGIN depointer_result=CHAIN_DEATH(SELF.chain) SELF->redraw ENDIF ELSE BEGIN BREAK ENDELSE ENDIF tiepoints=(READ_ASCII(filename)).(0) SELF.chain=CHAIN_START_FINDER(SELF.chain) FOR tiepoint=0,N_ELEMENTS(tiepoints[0,*])-1 DO BEGIN ;------------------------------------------------------- ; Misnomer: Although this tiepointer program uses x,y ; the xyzsun program deals with line,samp. ; ; When reading the file, convert line,samp --> x,y. ;------------------------------------------------------- points=tiepoints[*,tiepoint] CASE N_ELEMENTS(points) OF 4 : BEGIN ; Points are saved as Line,Samp by sunloop.pro(tiepointer.pro), so convert to X,Y. ; Left eye (behind spacescraft) is first in tiepoint file saved by sunloop.pro(tiepointer.pro). points=tiepoints[*,tiepoint] xy=SELF->convert_xy_into_linesamp(points,/REVERSE) END 7 : BEGIN ; Points are saved as X,Y by scc_measure.pro. ; Ahead spacecraft (right eye) is first in tiepoint file saved by scc_measure.pro, so swap their positions. xy=ROUND([points[5],points[6],points[3],points[4]]) END ELSE : BEGIN ddddd=DIALOG_MESSAGE(['Tiepoint file does not conform.', $ 'Must have either 4 or 7 values per line.', $ '(4 if created by sunloop.pro, and 7 if created by .pro)']) WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 RETURN END ENDCASE compatability_check_ndx=WHERE((xy GE (*SELF.hdr1ptr).NAXIS1) OR (xy GE (*SELF.hdr1ptr).NAXIS2) OR (xy GE (*SELF.hdr2ptr).NAXIS1) OR (xy GE (*SELF.hdr2ptr).NAXIS2), count) IF (count GT 0) THEN BEGIN ddddd=DIALOG_MESSAGE(['Tiepoint xy file contains point value large than image area.', 'Tiepoint xy file is incompatable with this image pair.', $ 'Tiepoint xy file was probably created using larger image.', '', 'Tiepoint xy file not read.']) BREAK ENDIF SELF.chain=CHAIN_LINK_ADD(SELF.chain,xy) ENDFOR SELF->redraw SELF->plot_all_tiepoints ENDIF ENDFOR ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; TIEPOINTER PREFERENCES BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF (event.ID EQ SELF.preferences_button) THEN BEGIN ;------------------------------------------------------- ; Kill the widget if it exists. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ;------------------------------------------------------- ; Create the widget base. ;------------------------------------------------------- SELF.preferences_base=WIDGET_BASE(TITLE='Tiepointer Preferences',GROUP_LEADER=SELF.tlb,/COLUMN,UVALUE=SELF,MAP=SELF.preferences_map) ;------------------------------------------------------- ; Set up the button for showing reference point labels. ;------------------------------------------------------- SELF.referencepointlabels_menu_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Reference Graphics >',/MENU) shownumbers1=WIDGET_BUTTON(SELF.referencepointlabels_menu_button,VALUE='On',/CHECKED_MENU,UVALUE=1) shownumbers0=WIDGET_BUTTON(SELF.referencepointlabels_menu_button,VALUE='Off',/CHECKED_MENU,UVALUE=0) id=WIDGET_INFO(SELF.referencepointlabels_menu_button,/CHILD) id=WIDGET_INFO(id,/SIBLING) ; Set the Off button. WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_UVALUE=show_reference_points IF (show_reference_points EQ SELF.show_reference_points) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE ;------------------------------------------------------- ; Set up the button for showing grid. ;------------------------------------------------------- SELF.grid_menu_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Grid >',/MENU) shownumbers1=WIDGET_BUTTON(SELF.grid_menu_button,VALUE='On',/CHECKED_MENU,UVALUE=1) shownumbers0=WIDGET_BUTTON(SELF.grid_menu_button,VALUE='Off',/CHECKED_MENU,UVALUE=0) id=WIDGET_INFO(SELF.grid_menu_button,/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_UVALUE=show_grid IF (show_grid EQ SELF.show_grid) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE ;------------------------------------------------------- ; Set up the button for showing numbers. ;------------------------------------------------------- SELF.shownumbers_menu_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Tiepoint Numbers >',/MENU) shownumbers0=WIDGET_BUTTON(SELF.shownumbers_menu_button,VALUE='Show Tiepoint Numbers',/CHECKED_MENU,UVALUE=0) shownumbers1=WIDGET_BUTTON(SELF.shownumbers_menu_button,VALUE='No Show',/CHECKED_MENU,UVALUE=1) shownumbers2=WIDGET_BUTTON(SELF.shownumbers_menu_button,VALUE='First and Last Only',/CHECKED_MENU,UVALUE=2) id=WIDGET_INFO(SELF.shownumbers_menu_button,/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_UVALUE=show_tiepoint_numbers IF (show_tiepoint_numbers EQ SELF.show_tiepoint_numbers) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE ;------------------------------------------------------- ; Set up the button for changing color tables. ;------------------------------------------------------- SELF.color_table_menu_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Color Table >',/MENU) colortable0=WIDGET_BUTTON(SELF.color_table_menu_button,VALUE='B-W Linear',/CHECKED_MENU,UVALUE=0) colortable1=WIDGET_BUTTON(SELF.color_table_menu_button,VALUE='Blue',/CHECKED_MENU,UVALUE=1) colortable3=WIDGET_BUTTON(SELF.color_table_menu_button,VALUE='Red',/CHECKED_MENU,UVALUE=3) colortable3=WIDGET_BUTTON(SELF.color_table_menu_button,VALUE='Green',/CHECKED_MENU,UVALUE=8) colortable3=WIDGET_BUTTON(SELF.color_table_menu_button,VALUE='Yellow',/CHECKED_MENU,UVALUE=-1) id=WIDGET_INFO(SELF.color_table_menu_button,/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_UVALUE=color_table IF (color_table EQ SELF.color_table) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE ;------------------------------------------------------- ; Set up the button for Cursor Tolerance. ;------------------------------------------------------- SELF.tolerance_menu_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Cursor Tolerance >',/MENU) tolerance1=WIDGET_BUTTON(SELF.tolerance_menu_button,VALUE='1',/CHECKED_MENU) tolerance2=WIDGET_BUTTON(SELF.tolerance_menu_button,VALUE='2',/CHECKED_MENU) tolerance3=WIDGET_BUTTON(SELF.tolerance_menu_button,VALUE='3',/CHECKED_MENU) tolerance4=WIDGET_BUTTON(SELF.tolerance_menu_button,VALUE='4',/CHECKED_MENU) tolerance5=WIDGET_BUTTON(SELF.tolerance_menu_button,VALUE='5',/CHECKED_MENU) id=WIDGET_INFO(SELF.tolerance_menu_button,/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_VALUE=tolerance IF (tolerance EQ SELF.tolerance) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE ;------------------------------------------------------- ; Set up the button for Computer Speed, for purposes of ; optimizing redraw performance when moving tiepoints. ;------------------------------------------------------- SELF.computer_menu_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Computer Speed >',/MENU) SELF.computer_fast_button=WIDGET_BUTTON(SELF.computer_menu_button,VALUE=SELF.computer_fast,/CHECKED_MENU) SELF.computer_medium_button=WIDGET_BUTTON(SELF.computer_menu_button,VALUE=SELF.computer_medium,/CHECKED_MENU) SELF.computer_slow_button=WIDGET_BUTTON(SELF.computer_menu_button,VALUE=SELF.computer_slow,/CHECKED_MENU) id=WIDGET_INFO(SELF.computer_menu_button,/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_VALUE=computer IF (computer EQ SELF.computer) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE ;------------------------------------------------------- ; Set up the button for closing the preferences window. ;------------------------------------------------------- SELF.close_preferences_button=WIDGET_BUTTON(SELF.preferences_base,VALUE='Close') ;------------------------------------------------------- ; Realize the widget. ;------------------------------------------------------- WIDGET_CONTROL,SELF.preferences_base,/REALIZE XMANAGER,'Preferences Base',SELF.preferences_base,EVENT_HANDLER='tiepointer_manage_widgets',NO_BLOCK=1 ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; TIEPOINTER IMAGE BRIGHTNESS BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF (event.ID EQ SELF.brightness_button) THEN BEGIN ;------------------------------------------------------- ; Kill the widget if it exists. ;------------------------------------------------------- IF WIDGET_INFO(SELF.brightness_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.brightness_base,/DESTROY ;------------------------------------------------------- ; Create the widget base. ;------------------------------------------------------- SELF.brightness_base=WIDGET_BASE(TITLE='Image Brightness',GROUP_LEADER=SELF.tlb,/COLUMN,UVALUE=SELF) brightness_base0=WIDGET_BASE(SELF.brightness_base,/ROW,UVALUE=SELF) brightness_base1=WIDGET_BASE(brightness_base0,/COLUMN,UVALUE=SELF,/FRAME) brightness_base2=WIDGET_BASE(brightness_base0,/COLUMN,UVALUE=SELF,/FRAME) brightness_base3=WIDGET_BASE(SELF.brightness_base,/ROW,UVALUE=SELF,/FRAME,/ALIGN_CENTER) lab=WIDGET_LABEL(brightness_base1,VALUE='Left Image ') lab=WIDGET_LABEL(brightness_base2,VALUE='Right Image ') ;------------------------------------------------------- ; Set up min/max widgets for left image. ;------------------------------------------------------- brightness_base1a=WIDGET_BASE(brightness_base1,/COLUMN,/FRAME) brightness_base1b=WIDGET_BASE(brightness_base1,/COLUMN,/FRAME) IF (SIZE((*SELF.raw_array1_ptr),/TYPE) EQ 1) THEN BEGIN min_str_val=STRTRIM(FIX(SELF.image1_min_value),2) max_str_val=STRTRIM(FIX(SELF.image1_max_value),2) ENDIF ELSE BEGIN min_str_val=STRTRIM(SELF.image1_min_value,2) max_str_val=STRTRIM(SELF.image1_max_value,2) ENDELSE lab = WIDGET_LABEL(brightness_base1a,VALUE='Min: ') SELF.image1_min_field = WIDGET_TEXT(brightness_base1a,/EDITABLE,/ALL_EVENTS,VALUE=min_str_val) SELF.image1_max_field = WIDGET_TEXT(brightness_base1b,/EDITABLE,/ALL_EVENTS,VALUE=max_str_val) SELF.image1_histogram_min_button = WIDGET_BUTTON(brightness_base1a,VALUE='Use Histogram Min') SELF.image1_histogram_max_button = WIDGET_BUTTON(brightness_base1b,VALUE='Use Histogram Max') ;------------------------------------------------------- ; Set up min/max widgets for right image. ;------------------------------------------------------- brightness_base2a=WIDGET_BASE(brightness_base2,/COLUMN,/FRAME) brightness_base2b=WIDGET_BASE(brightness_base2,/COLUMN,/FRAME) IF (SIZE((*SELF.raw_array2_ptr),/TYPE) EQ 1) THEN BEGIN min_str_val=STRTRIM(FIX(SELF.image2_min_value),2) max_str_val=STRTRIM(FIX(SELF.image2_max_value),2) ENDIF ELSE BEGIN min_str_val=STRTRIM(SELF.image2_min_value,2) max_str_val=STRTRIM(SELF.image2_max_value,2) ENDELSE lab = WIDGET_LABEL(brightness_base2a,VALUE='Min: ') SELF.image2_min_field = WIDGET_TEXT(brightness_base2a,/EDITABLE,/ALL_EVENTS,VALUE=min_str_val) SELF.image2_max_field = WIDGET_TEXT(brightness_base2b,/EDITABLE,/ALL_EVENTS,VALUE=max_str_val) SELF.image2_histogram_min_button = WIDGET_BUTTON(brightness_base2a,VALUE='Use Histogram Min') SELF.image2_histogram_max_button = WIDGET_BUTTON(brightness_base2b,VALUE='Use Histogram Max') ;------------------------------------------------------- ; Set up slider for Image Gamma. ;------------------------------------------------------- gamma_base1=WIDGET_BASE(brightness_base1,/COLUMN,/FRAME,/ALIGN_CENTER) gamma_base2=WIDGET_BASE(brightness_base2,/COLUMN,/FRAME,/ALIGN_CENTER) SELF.gamma_label1=WIDGET_LABEL(gamma_base1,VALUE='Gamma = '+STRTRIM(SELF.image1_gamma_value,2),/DYNAMIC_RESIZE) SELF.gamma_label2=WIDGET_LABEL(gamma_base2,VALUE='Gamma = '+STRTRIM(SELF.image2_gamma_value,2),/DYNAMIC_RESIZE) SELF.image1_gamma_slider=WIDGET_SLIDER(gamma_base1,VALUE=SELF->convert_gamma_value(/REVERSE,/IMAGE1),TITLE='Brighter -->',MIN=0,MAX=300,/SUPPRESS_VALUE,/DRAG) SELF.image2_gamma_slider=WIDGET_SLIDER(gamma_base2,VALUE=SELF->convert_gamma_value(/REVERSE,/IMAGE2),TITLE='Brighter -->',MIN=0,MAX=300,/SUPPRESS_VALUE,/DRAG) ;------------------------------------------------------- ; Set up the "apply" button. ;------------------------------------------------------- SELF.apply_brightness_button=WIDGET_BUTTON(brightness_base3,VALUE='Apply') ;------------------------------------------------------- ; Set up the button for closing the brightness window. ;------------------------------------------------------- SELF.applyclose_brightness_button=WIDGET_BUTTON(brightness_base3,VALUE='Apply and Close') SELF.close_brightness_button=WIDGET_BUTTON(brightness_base3,VALUE='Close') ;------------------------------------------------------- ; Realize the widget. ;------------------------------------------------------- WIDGET_CONTROL,SELF.brightness_base,/REALIZE XMANAGER,'Brightness Base',SELF.brightness_base,EVENT_HANDLER='tiepointer_manage_widgets',NO_BLOCK=1 ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; TIEPOINTER HELP BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF (event.ID EQ SELF.help_button) THEN BEGIN SELF->help,/DIALOG END ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; TIEPOINTER COORDINATE SYSTEM BUTTON. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; Change coordinate system, and check mark that button. ;------------------------------------------------------- IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.coordinate_system_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_UVALUE=coordinate_system SELF.coordinate_system=coordinate_system id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN BEGIN WIDGET_CONTROL,id,SET_BUTTON=1 IF (SELF.coordinate_system EQ 0) THEN WIDGET_CONTROL,SELF.coordinate_system_menu_button,SET_VALUE='Stonyhurst' IF (SELF.coordinate_system EQ 1) THEN WIDGET_CONTROL,SELF.coordinate_system_menu_button,SET_VALUE='Carrington' ENDIF id=WIDGET_INFO(id,/SIBLING) ENDWHILE system=(['Stonyhurst','Carrington'])[SELF.coordinate_system] IF ( STRUPCASE(system) EQ 'STONYHURST' ) THEN system = 'HEEQ' SELF.wcs1ptr=PTR_NEW(FITSHEAD2WCS(*SELF.hdr1ptr, COORD_TYPE=system ),/NO_COPY) SELF.wcs2ptr=PTR_NEW(FITSHEAD2WCS(*SELF.hdr2ptr, COORD_TYPE=system ),/NO_COPY) ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; Manage the Tiepointer Preferences widget. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF WIDGET_INFO(event.ID,/VALID_ID) THEN BEGIN ;------------------------------------------------------- ; Set the computer variable and check mark that button. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.computer_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_VALUE=computer ;------------------------------------------------------- ; Disable automatic downgrading after any manual upgrade. ;------------------------------------------------------- IF (SELF.computer EQ SELF.computer_slow) AND (computer EQ SELF.computer_medium) OR $ (SELF.computer EQ SELF.computer_slow) AND (computer EQ SELF.computer_fast) OR $ (SELF.computer EQ SELF.computer_medium) AND (computer EQ SELF.computer_fast) THEN SELF.computer_automatic=0 SELF.computer=computer id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN WIDGET_CONTROL,id,SET_BUTTON=1 id=WIDGET_INFO(id,/SIBLING) ENDWHILE ; IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ;------------------------------------------------------- ; Set the tolerance variable and check mark that button. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.tolerance_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_VALUE=tolerance SELF.tolerance=tolerance id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN WIDGET_CONTROL,id,SET_BUTTON=1 id=WIDGET_INFO(id,/SIBLING) ENDWHILE ; IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ;------------------------------------------------------- ; Show tiepoints numbers or not, and check mark that button. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.referencepointlabels_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_UVALUE=show_reference_points SELF.show_reference_points=show_reference_points id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN WIDGET_CONTROL,id,SET_BUTTON=1 id=WIDGET_INFO(id,/SIBLING) ENDWHILE SELF->redraw SELF->plot_all_tiepoints ; IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ;------------------------------------------------------- ; Show grid or not, and check mark that button. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.grid_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_UVALUE=show_grid SELF.show_grid=show_grid id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN WIDGET_CONTROL,id,SET_BUTTON=1 id=WIDGET_INFO(id,/SIBLING) ENDWHILE SELF->redraw SELF->plot_all_tiepoints ; IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ;------------------------------------------------------- ; Show tiepoints numbers or not, and check mark that button. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.shownumbers_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_UVALUE=show_tiepoint_numbers SELF.show_tiepoint_numbers=show_tiepoint_numbers id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN WIDGET_CONTROL,id,SET_BUTTON=1 id=WIDGET_INFO(id,/SIBLING) ENDWHILE SELF->redraw SELF->plot_all_tiepoints ; IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ;------------------------------------------------------- ; Set the color table. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (WIDGET_INFO(event.ID,/PARENT) EQ SELF.color_table_menu_button) THEN BEGIN WIDGET_CONTROL,event.ID,GET_UVALUE=color_table SELF.color_table=color_table id=WIDGET_INFO(WIDGET_INFO(event.ID,/PARENT),/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,SET_BUTTON=0 IF (id EQ event.ID) THEN WIDGET_CONTROL,id,SET_BUTTON=1 id=WIDGET_INFO(id,/SIBLING) ENDWHILE SELF->redraw SELF->plot_all_tiepoints ; IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ;------------------------------------------------------- ; Close preferences window. ;------------------------------------------------------- IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN IF (event.ID EQ SELF.close_preferences_button) THEN BEGIN IF WIDGET_INFO(SELF.preferences_base,/VALID_ID) THEN WIDGET_CONTROL,SELF.preferences_base,/DESTROY ENDIF ENDIF ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ; Manage the Image Brightness widget. ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- ;------------------------------------------------------- IF WIDGET_INFO(event.ID,/VALID_ID) THEN BEGIN ;------------------------------------------------------- ; "Close" image brightness window. ;------------------------------------------------------- IF (event.ID EQ SELF.close_brightness_button) THEN BEGIN WIDGET_CONTROL,SELF.brightness_base,/DESTROY ENDIF ;------------------------------------------------------- ; "Apply" or "Apply and Close" image brightness window. ;------------------------------------------------------- IF (event.ID EQ SELF.apply_brightness_button) OR (event.ID EQ SELF.applyclose_brightness_button) THEN BEGIN WIDGET_CONTROL,SELF.image1_min_field,GET_VALUE=image1_min_value WIDGET_CONTROL,SELF.image2_min_field,GET_VALUE=image2_min_value WIDGET_CONTROL,SELF.image1_max_field,GET_VALUE=image1_max_value WIDGET_CONTROL,SELF.image2_max_field,GET_VALUE=image2_max_value SELF.image1_min_value=DOUBLE(image1_min_value) SELF.image2_min_value=DOUBLE(image2_min_value) SELF.image1_max_value=DOUBLE(image1_max_value) SELF.image2_max_value=DOUBLE(image2_max_value) WIDGET_CONTROL,SELF.image1_min_field,SET_VALUE=STRTRIM(SELF.image1_min_value,2) WIDGET_CONTROL,SELF.image1_max_field,SET_VALUE=STRTRIM(SELF.image1_max_value,2) WIDGET_CONTROL,SELF.image2_min_field,SET_VALUE=STRTRIM(SELF.image2_min_value,2) WIDGET_CONTROL,SELF.image2_max_field,SET_VALUE=STRTRIM(SELF.image2_max_value,2) SELF.image1_gamma_value=SELF->convert_gamma_value(/FORWARD,/IMAGE1) SELF.image2_gamma_value=SELF->convert_gamma_value(/FORWARD,/IMAGE2) WIDGET_CONTROL,SELF.gamma_label1,SET_VALUE='Gamma = '+STRTRIM(SELF.image1_gamma_value,2) WIDGET_CONTROL,SELF.gamma_label2,SET_VALUE='Gamma = '+STRTRIM(SELF.image2_gamma_value,2) IF (event.ID EQ SELF.applyclose_brightness_button) THEN WIDGET_CONTROL,SELF.brightness_base,/DESTROY SELF->bytescale_raw_data SELF->redraw SELF->plot_all_tiepoints ENDIF CASE event.ID OF SELF.image1_histogram_min_button : BEGIN SELF.image1_min_value=MIN(*SELF.raw_array1_ptr) ; Account for BYTE data. CASE SIZE(SELF.image1_min_value,/TYPE) OF 1 : WIDGET_CONTROL,SELF.image1_min_field,SET_VALUE=STRTRIM(FIX(SELF.image1_min_value),2) ELSE : WIDGET_CONTROL,SELF.image1_min_field,SET_VALUE=STRTRIM(SELF.image1_min_value,2) ENDCASE END SELF.image1_histogram_max_button : BEGIN SELF.image1_max_value=MAX(*SELF.raw_array1_ptr) ; Account for BYTE data. CASE SIZE(SELF.image1_min_value,/TYPE) OF 1 : WIDGET_CONTROL,SELF.image1_max_field,SET_VALUE=STRTRIM(FIX(SELF.image1_max_value),2) ELSE : WIDGET_CONTROL,SELF.image1_max_field,SET_VALUE=STRTRIM(SELF.image1_max_value,2) ENDCASE END SELF.image2_histogram_min_button : BEGIN SELF.image2_min_value=MIN(*SELF.raw_array2_ptr) ; Account for BYTE data. CASE SIZE(SELF.image1_min_value,/TYPE) OF 1 : WIDGET_CONTROL,SELF.image2_min_field,SET_VALUE=STRTRIM(FIX(SELF.image2_min_value),2) ELSE : WIDGET_CONTROL,SELF.image2_min_field,SET_VALUE=STRTRIM(SELF.image2_min_value,2) ENDCASE END SELF.image2_histogram_max_button : BEGIN SELF.image2_max_value=MAX(*SELF.raw_array2_ptr) ; Account for BYTE data. CASE SIZE(SELF.image1_min_value,/TYPE) OF 1 : WIDGET_CONTROL,SELF.image2_max_field,SET_VALUE=STRTRIM(FIX(SELF.image2_max_value),2) ELSE : WIDGET_CONTROL,SELF.image2_max_field,SET_VALUE=STRTRIM(SELF.image2_max_value,2) ENDCASE END ELSE: ENDCASE ENDIF END ; Widget buttons. 'WIDGET_SLIDER' : BEGIN IF (event.ID EQ SELF.image1_gamma_slider) OR (event.ID EQ SELF.image2_gamma_slider) THEN BEGIN WIDGET_CONTROL,SELF.gamma_label1,SET_VALUE='Gamma = '+STRTRIM(SELF->convert_gamma_value(/FORWARD,/IMAGE1),2) WIDGET_CONTROL,SELF.gamma_label2,SET_VALUE='Gamma = '+STRTRIM(SELF->convert_gamma_value(/FORWARD,/IMAGE2),2) ENDIF END ; Widget sliders. ELSE : BEGIN END ENDCASE WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 END PRO tiepointer_manage_widgets,event ;------------------------------------------------------- ; This routine is necessary because widget event handler ; routines cannot be object methods. This routine just ; passes the event to an object method. ;------------------------------------------------------- WIDGET_CONTROL,event.TOP,GET_UVALUE=tiepointer IF OBJ_VALID(tiepointer) THEN tiepointer->manage_widgets,event END PRO tiepointer::create_widgets ;------------------------------------------------------- ; Create all the widgets. ;------------------------------------------------------- SELF.tlb=WIDGET_BASE(/COLUMN,KILL_NOTIFY='cleanup_pro',UVALUE=SELF,/TLB_SIZE_EVENTS,TITLE='Tiepointer',GROUP_LEADER=SELF.master_tlb,SENSITIVE=0) SELF.buttonbase=WIDGET_BASE(SELF.tlb,/ROW) algorithm_base=WIDGET_BASE(SELF.buttonbase,/FRAME,/ROW) ;------------------------------------------------------- ; Set up the button for changing coordinate system. ;------------------------------------------------------- SELF.coordinate_system_menu_button=WIDGET_BUTTON(algorithm_base,VALUE=(['Stonyhurst','Carrington'])[SELF.coordinate_system],/MENU) coordinate_system_0=WIDGET_BUTTON(SELF.coordinate_system_menu_button,VALUE='Stonyhurst Heliographic',/CHECKED_MENU,UVALUE=0) coordinate_system_1=WIDGET_BUTTON(SELF.coordinate_system_menu_button,VALUE='Carrington',/CHECKED_MENU,UVALUE=1) id=WIDGET_INFO(SELF.coordinate_system_menu_button,/CHILD) WHILE WIDGET_INFO(id,/VALID_ID) DO BEGIN WIDGET_CONTROL,id,GET_UVALUE=coordinate_system IF (coordinate_system EQ SELF.coordinate_system) THEN WIDGET_CONTROL,id,/SET_BUTTON id=WIDGET_INFO(id,/SIBLING) ENDWHILE SELF.scc_triangulate_button=WIDGET_BUTTON(algorithm_base,VALUE='scc_triangulate') SELF.scc_measure_button=WIDGET_BUTTON(algorithm_base,VALUE='scc_measure') SELF.read_tiepoint_file_button=WIDGET_BUTTON(SELF.buttonbase,VALUE='Read Tiepoints') SELF.brightness_button=WIDGET_BUTTON(SELF.buttonbase,VALUE='Brightness') SELF.preferences_button=WIDGET_BUTTON(SELF.buttonbase,VALUE='Prefs') SELF.help_button=WIDGET_BUTTON(SELF.buttonbase,VALUE='Help') xy_value_base1=WIDGET_BASE(SELF.buttonbase,/FRAME) xy_value_base2=WIDGET_BASE(SELF.buttonbase,/FRAME) xy_value_base3=WIDGET_BASE(SELF.buttonbase,/FRAME) xy_value_base4=WIDGET_BASE(SELF.buttonbase,/FRAME) SELF.value_label1=WIDGET_LABEL(xy_value_base1,VALUE=' line,samp = line, samp ',/DYNAMIC_RESIZE) SELF.value_label2=WIDGET_LABEL(xy_value_base2,VALUE=' x,y = x, y ',/DYNAMIC_RESIZE) SELF.value_label3=WIDGET_LABEL(xy_value_base3,VALUE=' lon,lat = lon, lat ',/DYNAMIC_RESIZE) SELF.value_label4=WIDGET_LABEL(xy_value_base4,VALUE=' value = value ',/DYNAMIC_RESIZE) displaybase=WIDGET_BASE(SELF.tlb,/ROW) displaybase1=WIDGET_BASE(displaybase,/COLUMN) displaybase2=WIDGET_BASE(displaybase,/COLUMN) xsize=N_ELEMENTS((*SELF.raw_array1_ptr)[*,0])>N_ELEMENTS((*SELF.raw_array2_ptr)[*,0]) ysize=N_ELEMENTS((*SELF.raw_array1_ptr)[0,*])>N_ELEMENTS((*SELF.raw_array2_ptr)[0,*]) available_wdth=(GET_SCREEN_SIZE())[0]*0.9<(xsize*2) available_hght=(GET_SCREEN_SIZE())[1]*0.8MAX_CALC(*SELF.raw_array1_ptr,SELF.image1_min_value) ;SELF.image2_max_value=SELF->MAX_CALC(*SELF.raw_array2_ptr,SELF.image2_min_value) ENDELSE SELF.new_x_tp_location=-1 SELF.new_y_tp_location=-1 SELF.initialize_cursor2tiepoint_offset=1 SELF.tolerance=5 SELF.show_tiepoint_numbers=0 SELF.raw_array1_ptr=PTR_NEW(array1) SELF.raw_array2_ptr=PTR_NEW(array2) system=(['Stonyhurst','Carrington'])[SELF.coordinate_system] IF ( STRUPCASE(system) EQ 'STONYHURST' ) THEN system = 'HEEQ' SELF.wcs1ptr=PTR_NEW(FITSHEAD2WCS(*SELF.hdr1ptr, COORD_TYPE=system ),/NO_COPY) SELF.wcs2ptr=PTR_NEW(FITSHEAD2WCS(*SELF.hdr2ptr, COORD_TYPE=system ),/NO_COPY) SELF.secchistruct1ptr=PTR_NEW(secchistruct1) SELF.secchistruct2ptr=PTR_NEW(secchistruct2) SELF.left_filename=left_filename SELF.right_filename=right_filename SELF.detector=detector SELF.rotate=rotate SELF.master_tlb=master_tlb SELF->create_widgets XMANAGER,'tiepointer',SELF.tlb,EVENT_HANDLER='tiepointer_manage_widgets',NO_BLOCK=1 widgetdraw1_geom=WIDGET_INFO(SELF.widgetdraw1,/GEOMETRY) widgetdraw2_geom=WIDGET_INFO(SELF.widgetdraw2,/GEOMETRY) SELF.widgetdraw_geom_DRAW_XSIZE=[widgetdraw1_geom.DRAW_XSIZE,widgetdraw2_geom.DRAW_XSIZE] SELF.widgetdraw_geom_DRAW_YSIZE=[widgetdraw1_geom.DRAW_YSIZE,widgetdraw2_geom.DRAW_YSIZE] CASE SELF.detector OF 'euvi' : default_gamma_value=3.0 'cor1' : default_gamma_value=3.0 'cor2' : default_gamma_value=1.0 'hi_1' : default_gamma_value=2.0 'hi_2' : default_gamma_value=2.0 ENDCASE SELF.image1_gamma_value=default_gamma_value SELF.image2_gamma_value=default_gamma_value SELF->bytescale_raw_data SELF->setup_plot_space start_time=SYSTIME(/SECONDS) SELF->redraw SELF->help SELF.show_reference_points=0 SELF.show_grid=0 IF (SELF.show_reference_points EQ 1) THEN SELF->plot_reference_points IF (SELF.show_grid EQ 1) THEN SELF->draw_grid IF ((SYSTIME(/SECONDS) - start_time) GT SELF.computer_thresh) THEN BEGIN ;------------------------------------------------------- ; At initialization, downgrade Computer Speed preference ; to MEDIUM if it's determined that the computer is not ; quick enough for useful tiepoint motion. ;------------------------------------------------------- SELF.preferences_map=0 SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.preferences_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.computer_medium_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF.preferences_map=1 start_time=SYSTIME(/SECONDS) SELF->plot_all_tiepoints IF ((SYSTIME(/SECONDS) - start_time) GT SELF.computer_thresh) THEN BEGIN ;------------------------------------------------------- ; At initialization, downgrade Computer Speed preference ; to SLOW if it's determined that the computer is not ; quick enough for useful tiepoint motion. ;------------------------------------------------------- SELF.preferences_map=0 SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.preferences_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.computer_slow_button,top:SELF.tlb,handler:SELF.tlb,select:1} SELF.preferences_map=1 start_time=SYSTIME(/SECONDS) SELF->plot_all_tiepoints ENDIF ENDIF IF KEYWORD_SET(xy_filename) THEN BEGIN ; xy_filename is being passed from sunloop command line. Initialize tiepointer with these tiepoints. SELF.xy_filename=xy_filename IF (SELF.xy_filename NE '') THEN BEGIN SELF->manage_widgets,{WIDGET_BUTTON,id:SELF.read_tiepoint_file_button,top:SELF.tlb,handler:SELF.tlb,select:1} ENDIF ENDIF WIDGET_CONTROL,SELF.tlb,SENSITIVE=1 RETURN,1 END PRO tiepointer__define ;------------------------------------------------------- ; Define the object structure. These are the internal ; variables which will be conveniently available to all ; object methods as the SELF structure. ;------------------------------------------------------- tiepointer={tiepointer, $ master_tlb:0L, $ ; Calling tlb. tlb:0L, $ ; Top level base of tiepointer program. widgetdraw1:0L, $ ; Left widget draw. widgetdraw2:0L, $ ; Right widget draw. window1:0L, $ ; Left image window number. window2:0L, $ ; Right image window number. widgetdraw_geom_DRAW_XSIZE:LONARR(2), $ ; widgetdraw_geom_DRAW_YSIZE:LONARR(2), $ ; buttonbase:0L, $ ; Base for buttons. scc_triangulate_button:0L, $ ; Call the "scc_triangulate" program. scc_measure_button:0L, $ ; Call the "scc_measure" program. read_tiepoint_file_button:0L, $ ; Read in existing tiepoint file(s). preferences_button:0L, $ ; Call up the preferences interface. brightness_button:0L, $ ; Call up the image brightness interface. help_button:0L, $ ; Help. preferences_base:0L, $ ; Preferences base widget. computer_menu_button:0L, $ ; Preference button widget. computer_fast_button:0L, $ ; Preference button widget. computer_medium_button:0L, $ ; Preference button widget. computer_slow_button:0L, $ ; Preference button widget. tolerance_menu_button:0L, $ ; Preference button widget. shownumbers_menu_button:0L, $ ; Preference button widget. referencepointlabels_menu_button:0L, $ ; Preference button widget. grid_menu_button:0L, $ ; Preference button widget. color_table_menu_button:0L, $ ; Preference button widget. close_preferences_button:0L, $ ; Preference button widget. coordinate_system_menu_button:0L, $ ; Preference button widget. tolerance:0L, $ ; Preference value, radius of acceptable distance from tiepoint to cursor click that will identify a tiepoint for move or delete. show_tiepoint_numbers:0L, $ ; Preference value. show_reference_points:0, $ ; Preference value. show_grid:0, $ ; Preference value. color_table:0L, $ ; Preference value. coordinate_system:0, $ ; Preference value. 0 = Stonyhurst Heliographic, 1 = Carrington. brightness_base:0L, $ ; Image Brightness base widget. image1_min_field:0L, $ ; Image Brightness widget. image2_min_field:0L, $ ; Image Brightness widget. image1_max_field:0L, $ ; Image Brightness widget. image2_max_field:0L, $ ; Image Brightness widget. image1_histogram_min_button:0L, $ ; Image Brightness widget. image2_histogram_min_button:0L, $ ; Image Brightness widget. image1_histogram_max_button:0L, $ ; Image Brightness widget. image2_histogram_max_button:0L, $ ; Image Brightness widget. gamma_label1:0L, $ ; Image Brightness widget. gamma_label2:0L, $ ; Image Brightness widget. image1_gamma_slider:0L, $ ; Image Brightness widget. image2_gamma_slider:0L, $ ; Image Brightness widget. apply_brightness_button:0L, $ ; Image Brightness widget. applyclose_brightness_button:0L, $ ; Image Brightness widget. close_brightness_button:0L, $ ; Image Brightness widget. image1_min_value:0.0d, $ ; Image Brightness value. image2_min_value:0.0d, $ ; Image Brightness vJalue. image1_max_value:0.0d, $ ; Image Brightness value. image2_max_value:0.0d, $ ; Image Brightness value. image1_gamma_value:0.0, $ ; Image Brightness value. image2_gamma_value:0.0, $ ; Image Brightness value. value_label1:0L, $ ; value_label2:0L, $ ; value_label3:0L, $ ; value_label4:0L, $ ; keep_checking:1L, $ ; initialize_cursor2tiepoint_offset:0, $ ; Flag for keeping track of whether or not to re-initialize the cursor2tiepoint offsets. x_cursor2tiepoint_offset:0L, $ ; Cursor distance to tiepoint, the user usually won't click exactly on the tiepoint. y_cursor2tiepoint_offset:0L, $ ; Cursor distance to tiepoint, the user usually won't click exactly on the tiepoint. new_x_tp_location:0L, $ new_y_tp_location:0L, $ mouse_button_is_down:0, $ ; Keep track of mouse button status (pressed or not). raw_array1_ptr:PTR_NEW(), $ ; Left image raw data (not necessarily byte). raw_array2_ptr:PTR_NEW(), $ ; Right image raw data (not necessarily byte). displaylabel1:0L, $ ; Left filename gets displayed above the left widget_draw. displaylabel2:0L, $ ; Right filename gets displayed above the right widget_draw. left_filename:'', $ ; Left image filename. right_filename:'', $ ; Right image filename. bytescaled_array1_ptr:PTR_NEW(), $ ; Left image byte data. bytescaled_array2_ptr:PTR_NEW(), $ ; Right image byte data. hdr1ptr:PTR_NEW(), $ ; Left image header strucutre. hdr2ptr:PTR_NEW(), $ ; Right image header structure. wcs1ptr:PTR_NEW(), $ ; Left image header strucutre. wcs2ptr:PTR_NEW(), $ ; Right image header structure. secchistruct1ptr:PTR_NEW(), $ ; Left image SECCHI structure. secchistruct2ptr:PTR_NEW(), $ ; Right image SECCHI structure. detector:'', $ ; euvi,cor1,cor2,hi_1,hi_2,... etc. rotate:'', $ ; Rotation/calibration description. chain:PTR_NEW(), $ ; chain is a linked list that keeps track of the tiepoints. xy_filename:'', $ ; Initialize tiepointer with these xy points passed from sunloop command line. computer_automatic:0, $ computer_thresh:0.0, $ computer_fast:'', $ computer_medium:'', $ computer_slow:'', $ tag_names_self:'', $ computer:'', $ preferences_map:0 } END