;+ ; NAME: fw.pro ; ; PURPOSE: Fits Widget Viewer ; ; CATEGORY: ACOS Analysis ; ; CALLING SEQUENCE: ; fw ; ; INPUTS: none ; ; KEYWORD PARAMETERS: none ; ; PROCEDURE: ; Display FITS images using "exptv" ; Adjust min/max/gamma to obtain suitable contrast & brightness. ; Apply min/max/gamma to byte array version of image. ; Save display version of image. ; Use later to make composites with other images. ; ; LIMITATIONS: ; fw only works properly in SHARED color map mode (=> pseudo_color=8). ; ; MODIFICATION HISTORY: ; 15 April 1996: created by Andrew L. Stanger, HAO/NCAR ; 17 April 1996: replace min/max/gamma inputs with sliders ; which modify the color map only. Apply button may ; then be used to alter the byte array image itself. ; 16 May 1996: add min/max input scaling label & text. ; 20 May 1996: default lut directory: /picard/people/stanger/idl/color ; 21 May 1996: add data_min & data_max text widgets. ; 23 May 1996: fix image file & directory I/O logic. ; 10 Jun 1996: If CRRADIUS not present, check for RADIUS parameter. ; Also, write datamin, datamax parameters to output FTS file. ; 19 Nov 1996: default lut directory: /home/riker/stanger/idl/color ; 20 Mar 1997: set pseudo_color device & 256 level colormap (private). ; 16 Dec 1998: remove '.fits' from FILTER. ;- ;------------------------------------------------------------------------------- PRO fw_display, image, MAX = cur_max, MIN = cur_min ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Display Image. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - exptv, image, MAX = cur_max, MIN = cur_min, xalign = 0.5, yalign = 0.5 END ;------------------------------------------------------------------------------- PRO fw_house, hdu ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Annotate image. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @fw_common img_date_obs = '' img_doy = '' img_time_obs = '' img_origin = '' img_telescop = '' img_object = '' img_type_obs = '' img_type_dp = '' img_data_min = 0.0 img_data_max = 255.0 img_disp_min = 0.0 img_disp_max = 255.0 img_crpix1 = 0.0 img_crpix2 = 0.0 img_crradius = 0.0 ;--- Get parameter values from FITS header. ;--- Observation date. fw_date_obs = fxpar (hdu, 'DATE-OBS') IF (!err NE -1) THEN BEGIN $ smonth = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', $ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] iday = fix (strmid (fw_date_obs, 0, 2)) imonth = fix (strmid (fw_date_obs, 3, 2)) - 1 iyear = fix (strmid (fw_date_obs, 6, 2)) nday = intarr (12) nday ( [0, 2, 4, 6, 7, 9, 11] ) = 31 nday ( [3, 5, 8, 10] ) = 30 ly = float (iyear) / 4.0 IF ((ly - fix (ly)) eq 0.0) THEN nday (1) = 29 ELSE nday (1) = 28 idoy = 0 IF (imonth ne 0) THEN $ FOR i = 0, imonth - 1 DO BEGIN idoy = idoy + nday (i) ENDFOR idoy = idoy + iday img_doy = string (idoy) img_date_obs = string (iday, FORMAT = "(I2)") + '-' + $ smonth (imonth) + '-' + $ string (iyear, FORMAT = "(i2)") ENDIF ;--- Observation time. fw_time_obs = fxpar (hdu, 'TIME-OBS') IF (!err NE -1) THEN img_time_obs = fw_time_obs ;--- Origin: organization or institute or observatory. fw_origin = fxpar (hdu, 'ORIGIN') IF (!err NE -1) THEN img_origin = fw_origin ;--- Telescope name. fw_telescop = fxpar (hdu, 'TELESCOP') IF (!err NE -1) THEN img_telescop = fw_telescop ;--- Object observed. fw_object = fxpar (hdu, 'OBJECT') IF (!err NE -1) THEN img_object = fw_object ;--- Type of observation. fw_type_obs = fxpar (hdu, 'TYPE-OBS') IF (!err NE -1) THEN img_type_obs = fw_type_obs ;--- Type of data processing applied to image. fw_type_dp = fxpar (hdu, 'TYPE-DP') IF (!err NE -1) THEN img_type_dp = fw_type_dp ;--- Reference point (sun center) X-axis location. fw_crpix1 = fxpar (hdu, 'CRPIX1') IF (!err NE -1) THEN img_crpix1 = fw_crpix1 ;--- Reference point (sun center) Y-axis location. fw_crpix2 = fxpar (hdu, 'CRPIX2') IF (!err NE -1) THEN img_crpix2 = fw_crpix2 ;--- Solar radius (pixels). fw_crradius = fxpar (hdu, 'CRRADIUS') ; Image solar radius (pixels). crradius_err = !err IF (crradius_err NE -1) THEN $ img_crradius = fw_crradius $ ELSE $ BEGIN fw_radius = fxpar (hdu, 'RADIUS') ; Image solar radius (pixels). radius_err = !err IF (radius_err NE -1) THEN $ BEGIN fxaddpar, hdu, 'CRRADIUS', fw_radius, ' SOLAR RADIUS [PIXELS].' img_crradius = fw_radius END ENDELSE simg_crpix1 = string (img_crpix1, FORMAT = "(F8.2)") simg_crpix2 = string (img_crpix2, FORMAT = "(F8.2)") simg_crradius = string (img_crradius, FORMAT = "(F8.2)") ;--- Data minimum value. fw_data_min = fxpar (hdu, 'DATAMIN') datamin_err = !err IF (datamin_err NE -1) THEN $ BEGIN img_data_min = fw_data_min ENDIF $ ELSE $ BEGIN img_data_min = MIN (img_dbuf) fxaddpar, hdu, 'DATAMIN', img_data_min, FORMAT="(E9.2)" END ;--- Data maximum value. fw_data_max = fxpar (hdu, 'DATAMAX') datamax_err = !err IF (datamax_err NE -1) THEN $ BEGIN img_data_max = fw_data_max ENDIF $ ELSE $ BEGIN img_data_max = MAX (img_dbuf) fxaddpar, hdu, 'DATAMAX', img_data_max, FORMAT="(E9.2)" END ;--- Display minimum value. fw_disp_min = fxpar (hdu, 'DISPMIN') dispmin_err = !err IF (dispmin_err NE -1) THEN $ BEGIN img_disp_min = fw_disp_min ENDIF $ ELSE $ img_disp_min = MIN (img_dbuf) ;--- Display maximum value. fw_disp_max = fxpar (hdu, 'DISPMAX') dispmax_err = !err IF (dispmax_err NE -1) THEN $ BEGIN img_disp_max = fw_disp_max ENDIF $ ELSE $ img_disp_max = MAX (img_dbuf) data_min = img_data_min data_max = img_data_max disp_min = img_disp_min disp_max = img_disp_max disp_gamma = 1.0 tv_min = disp_min tv_max = disp_max tv_gamma = disp_gamma sav_min = disp_min sav_max = disp_max sav_gamma = disp_gamma PRINT, 'fw_house>data_min/data_max: ', data_min, data_max PRINT, 'fw_house>disp_min/disp_max: ', disp_min, disp_max WIDGET_CONTROL, tw_doy, SET_VALUE = img_doy WIDGET_CONTROL, tw_date_obs, SET_VALUE = img_date_obs WIDGET_CONTROL, tw_time_obs, SET_VALUE = img_time_obs WIDGET_CONTROL, tw_origin, SET_VALUE = img_origin WIDGET_CONTROL, tw_telescop, SET_VALUE = img_telescop WIDGET_CONTROL, tw_object, SET_VALUE = img_object WIDGET_CONTROL, tw_type_obs, SET_VALUE = img_type_obs WIDGET_CONTROL, tw_type_dp, SET_VALUE = img_type_dp WIDGET_CONTROL, tw_crpix1, SET_VALUE = simg_crpix1 WIDGET_CONTROL, tw_crpix2, SET_VALUE = simg_crpix2 WIDGET_CONTROL, tw_crradius, SET_VALUE = simg_crradius cminmax_refresh fminmax_refresh pminmax_refresh END ;------------------------------------------------------------------------------- PRO cminmax_refresh ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Update color look-up table sliders. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @fw_common WIDGET_CONTROL, MIN_SLIDER, SET_VALUE = string (vbot, FORMAT="(I3)") WIDGET_CONTROL, MAX_SLIDER, SET_VALUE = string (vtop, FORMAT="(I3)") WIDGET_CONTROL, GAMMA_LABEL, SET_VALUE = STRING (gammaval, FORMAT="(f6.3)") WIDGET_CONTROL, GAMMA_SLIDER, SET_VALUE = 50 END ;------------------------------------------------------------------------------- PRO fminmax_refresh ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Update image scaling min/max range. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @fw_common adisp_min = ABS (disp_min) IF (adisp_min NE 0.0 AND adisp_min LT 0.001 OR adisp_min GE 10000.0) THEN $ WIDGET_CONTROL, tw_disp_min, SET_VALUE = num2str (disp_min, FORMAT="(E8.2)") $ ELSE $ WIDGET_CONTROL, tw_disp_min, SET_VALUE = num2str (disp_min, FORMAT="(F20.3)") adisp_max = ABS (disp_max) IF (adisp_max NE 0.0 AND adisp_max LT 0.001 OR adisp_max GE 10000.0) THEN $ WIDGET_CONTROL, tw_disp_max, SET_VALUE = num2str (disp_max, FORMAT="(E8.2)") $ ELSE $ WIDGET_CONTROL, tw_disp_max, SET_VALUE = num2str (disp_max, FORMAT="(F20.3)") END ;------------------------------------------------------------------------------- PRO pminmax_refresh ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Update pixel data min/max range. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @fw_common adata_min = ABS (data_min) IF (adata_min NE 0.0 AND adata_min LT 0.001 OR adata_min GE 10000.0) THEN $ WIDGET_CONTROL, tw_data_min, SET_VALUE = num2str (data_min, FORMAT="(E8.2)") $ ELSE $ WIDGET_CONTROL, tw_data_min, SET_VALUE = num2str (data_min, FORMAT="(F20.3)") adata_max = ABS (data_max) IF (adata_max NE 0.0 AND adata_max LT 0.001 OR adata_max GE 10000.0) THEN $ WIDGET_CONTROL, tw_data_max, SET_VALUE = num2str (data_max, FORMAT="(E8.2)") $ ELSE $ WIDGET_CONTROL, tw_data_max, SET_VALUE = num2str (data_max, FORMAT="(F20.3)") END ;------------------------------------------------------------------------------- PRO FW_Event, Event ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Event processing for fw procedure. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @fw_common WIDGET_CONTROL, Event.Id, GET_UVALUE=Ev IF (Event.Id EQ wl_lut) THEN BEGIN ; PRINT, 'wl_lut event', ' event.index: ', event.index, $ ; ' ', lut_names (event.index) ; PRINT, 'lut_paths: ' ; PRINT, lut_paths ; PRINT, 'lut_paths (event.index): ', lut_paths (event.index) ; PRINT, 'fw_lct>size (red): ', size (red) ; PRINT, 'fw_lct> red: ' ; PRINT, red fw_lct, lut_paths (event.index) GOTO, set_gamma ENDIF CASE Ev OF 'BUTTON1': BEGIN ; Print, 'Event for Quit' WIDGET_CONTROL, event.top, /destroy ; Kill all widgets. END 'BUTTON2': BEGIN ; Load image. ; Print, 'Event for Load Image' old_dir = img_dir img_path = PICKFILE (PATH=old_dir, GET_PATH=img_dir, $ /READ, FILTER = '*.fts') img_file = strip_dirname (img_path) ; Strip directory from path. PRINT, 'img_path: ', img_path PRINT, 'img_dir: ', img_dir PRINT, 'img_file: ', img_file IF (img_file NE '') THEN $ BEGIN flash_msg, tw_info, 'Loading FITS image : ' + img_file, $ num = 2, /NOBEEP WIDGET_CONTROL, tw_file_id, SET_VALUE = img_file img_ibuf = readfits (img_path, img_hdu) ; Read image into input buffer. img_dbuf = img_ibuf ; Display buffer. apply_minmaxgam = 0 fw_house, img_hdu fw_display, img_dbuf, MIN=disp_min, MAX=disp_max ; PRINT, 'Load> min (img_dbuf): ', min (img_dbuf), $ ; ' max (img_dbuf): ', max (img_dbuf) WIDGET_CONTROL, tw_info, SET_VALUE = 'Loaded file: ' + img_path ENDIF END 'BUTTON3': BEGIN ; Restore image. ; Print, 'Event for Restore Image' flash_msg, tw_info, 'Restoring ' + img_file + $ ' with default parameters. ',$ num = 2, /NOBEEP WIDGET_CONTROL, tw_file_id, SET_VALUE = img_file img_ibuf = readfits (img_path, img_hdu) ; Read image into input buffer. img_dbuf = img_ibuf ; Display buffer. apply_minmaxgam = 0 vbot = 0 vtop = 100 gammaval = 1.0 cminmax_refresh fminmax_refresh fw_house, img_hdu fw_display, img_dbuf, MIN=disp_min, MAX=disp_max ; PRINT, 'restore> min (img_dbuf): ', min (img_dbuf), $ ; ' max (img_dbuf): ', max (img_dbuf) WIDGET_CONTROL, tw_info, SET_VALUE = 'Restored file: ' + img_path END 'BUTTON4': BEGIN ; Save Image: FITS. ; Print, 'Event for Save Image: FITS' ;--- Create output file name. extloc = strpos (img_file, '.fts') IF (extloc EQ -1) THEN extloc = strpos (img_file, '.fits') IF (extloc NE -1) THEN $ out_file = strmid (img_file, 0, extloc) $ ELSE $ out_file = img_file out_file = out_file + '.fw.fts' flash_msg, tw_info, 'Saving image as a FITS file: ' + $ out_file, num = 4, /NOBEEP ;--- Modify FITS header. out_hdu = img_hdu sdbuf = size (img_dbuf) dtype = sdbuf (3) ; data type CASE dtype OF 0: BEGIN nbitpix = 0 END 1: BEGIN nbitpix = 8 END 2: BEGIN nbitpix = 16 END 3: BEGIN nbitpix = 32 END 4: BEGIN nbitpix = -32 END 5: BEGIN nbitpix = -32 END 6: BEGIN nbitpix = -32 END 7: BEGIN nbitpix = -8 END 8: BEGIN nbitpix = -1 END ENDCASE ; PRINT, 'dtype: ', dtype, ' nbitpix: ', nbitpix fxaddpar, out_hdu, 'BITPIX', nbitpix fxaddpar, out_hdu, 'DISPMIN', disp_min, FORMAT="(E9.2)" fxaddpar, out_hdu, 'DISPMAX', disp_max, FORMAT="(E9.2)" fxaddpar, out_hdu, 'COMMENT', $ ' -->IMAGE HAS BEEN MODIFIED BY IDL PROCEDURE FW.PRO' fxaddpar, out_hdu, 'COMMENT', $ ' --> CHECK BITPIX, BSCALE, BZERO, DISPMIN, DISPMAX. IF (apply_minmaxgam) THEN $ BEGIN fxaddpar, out_hdu, 'DATAMIN', disp_min, FORMAT="(E9.2)" fxaddpar, out_hdu, 'DATAMAX', disp_max, FORMAT="(E9.2)" fxaddpar, out_hdu, 'COMMENT', ' -->DISPMIN CORRESPONDS TO ' $ + string (sav_min, FORMAT = "(E9.2)") fxaddpar, out_hdu, 'COMMENT', ' -->DISPMAX CORRESPONDS TO ' $ + string (sav_max, FORMAT = "(E9.2)") fxaddpar, out_hdu, 'COMMENT', ' -->GAMMA CORRECTION (' + $ string (sav_gamma, FORMAT = "(F6.3)") + ') HAS BEEN APPLIED.' END ; PRINT, 'save image>out_file: ', out_file ; PRINT, 'save image>data_min/max: ', data_min, data_max ; PRINT, 'save image>sav_min/max: ', sav_min, sav_max ; PRINT, 'save image>sav_gamma: ', sav_gamma ;--- Write file to disk. PRINT, 'Writing FITS file ', out_file, ' to disk.' ; PRINT, 'size (img_dbuf): ', size (img_dbuf) ; PRINT, 'min (img_dbuf): ', min (img_dbuf), $ ; ' max (img_dbuf): ', max (img_dbuf) out_path = img_dir + out_file writefits, out_path, img_dbuf, out_hdu WIDGET_CONTROL, tw_info, SET_VALUE = 'Saved FITS file: ' + out_path END 'BUTTON5': BEGIN ; Save Sun Rasterfile. Print, 'Event for Save Image: Sun Raster' ;--- Create output file name. PRINT, 'img_dir: ', img_dir PRINT, 'img_file: ', img_file extloc = STRPOS (img_file, '.fts') IF (extloc EQ -1) THEN extloc = STRPOS (img_file, '.fits') IF (extloc NE -1) THEN $ out_file = strmid (img_file, 0, extloc) $ ELSE $ out_file = img_file out_file = out_file + '.fw.ras' PRINT, 'out_file: ', out_file flash_msg, tw_info, 'Saving image as a Sun rasterfile: ' + $ out_file, num = 4, /NOBEEP sdbuf = size (img_dbuf) dtype = sdbuf (3) ; data type IF (dtype EQ 0) THEN $ BEGIN PRINT, 'Invalid image type: ', dtype END $ ELSE $ ; Apply min/max/gamma. BEGIN img_rbuf = bytscl (img_dbuf, MIN=tv_min, MAX=tv_max, TOP=tv_top) img_rbuf = gamtran (img_rbuf, tv_gamma) END ; tvlct, red, green, blue, /get ; Read color LUT. PRINT, 'Writing Sun Rasterfile: ', out_file ; PRINT, 'size (img_dbuf): ', size (img_dbuf) ; PRINT, 'min (img_dbuf): ', min (img_dbuf), $ ; ' max (img_dbuf): ', max (img_dbuf) ; PRINT, 'write_ras>size (red): ', size (red) ; PRINT, 'write_ras> red: ' ; PRINT, red ; Flip image top-to-bottom for Sun Rasterfile & write to disk. out_path = img_dir + out_file write_ras, out_path, reverse (img_rbuf, 2), red, green, blue WIDGET_CONTROL, tw_info, SET_VALUE = 'Saved Sun Rasterfile: ' + out_path END ; 'BUTTON6': BEGIN ; Lat/Long Grid. ; Print, 'Event for Grid' ; END 'BUTTON7': BEGIN ; FITS header. Print, 'Event for FITS Header' END 'MINIMUM': BEGIN ; Data min value. ; Print, 'Event for Data Minimum' WIDGET_CONTROL, MIN_SLIDER, GET_VALUE = vbot frac_min = vbot / 100.0 tv_min = frac_min * (disp_max - disp_min) + disp_min GOTO, set_gamma END 'MAXIMUM': BEGIN ; Data max value. ; Print, 'Event for Data Maximum' WIDGET_CONTROL, MAX_SLIDER, GET_VALUE = vtop frac_max = vtop / 100.0 tv_max = frac_max * (disp_max - disp_min) + disp_min GOTO, set_gamma END "GAMMA": BEGIN ; Gamma value. ; Print, 'Event for Gamma Correction' WIDGET_CONTROL, GAMMA_SLIDER, GET_VALUE = sgammaval tv_gamma = 10^((sgammaval/50.0) - 1) gammaval = 1.0 / tv_gamma ; PRINT, 'sgammaval: ', sgammaval, ' gammaval: ', gammaval, $ ; ' tv_gamma: ', tv_gamma WIDGET_CONTROL, GAMMA_LABEL, $ SET_VALUE = STRING (tv_gamma, FORMAT="(F6.3)") GOTO, set_gamma set_gamma: IF (use_values) THEN nc = 256 ELSE nc = ncolors s = (nc - 1) / 100.0 x0 = vbot * s x1 = vtop * s IF (x0 NE x1) THEN s = (nc - 1.0) / (x1 - x0) ELSE s = 1.0 int = -s * x0 IF (gammaval EQ 1.0) THEN s = round (findgen (nc) * s + int > 0.0) $ ELSE s = ((findgen (nc) * (s / nc) + (int / nc) > 0.0) ^ gammaval) * nc IF (chop NE 0) THEN BEGIN too_high = WHERE (s GE nc, n) IF (n GT 0) THEN s (too_high) = 0L ENDIF IF (use_values) THEN BEGIN s = s < 255L l = lindgen (ncolors) + cbot r_curr (cbot) = (r = s (r_orig (l))) g_curr (cbot) = (g = s (g_orig (l))) b_curr (cbot) = (b = s (b_orig (l))) ENDIF ELSE BEGIN s = s + cbot r_curr (cbot) = (r = r_orig (s)) g_curr (cbot) = (g = g_orig (s)) b_curr (cbot) = (b = b_orig (s)) ENDELSE tvlct, r, g, b, cbot IF (apply_minmaxgam) THEN $ WIDGET_CONTROL, tw_info, $ SET_VALUE = 'Applied min/max/gamma to image, ' + $ 'which is now a byte array.' END 'MIN_MAX_GAM': BEGIN ; Apply min/max/gamma. ; Print, 'Event for Apply min/max/gamma' ; PRINT, 'Apply disp_min/disp_max: ', disp_min, disp_max ; PRINT, 'Apply tv_min /tv_max: ', tv_min, tv_max flash_msg, tw_info, 'Applying color map min/max/gamma to image pixels.', $ num = 2 ;--- Apply linear photometric scaling using disp_min & disp_max. img_dbuf = bytscl (img_dbuf, MIN=tv_min, MAX=tv_max, TOP=tv_top) ; PRINT, 'size (img_dbuf): ', size (img_dbuf) ;--- Apply gamma correction. img_dbuf = gamtran (img_dbuf, tv_gamma) ; PRINT, 'size (img_dbuf): ', size (img_dbuf) apply_minmaxgam = 1 ;--- Convert to byte array. img_dbuf = byte (img_dbuf) ; PRINT, 'size (img_dbuf): ', size (img_dbuf) dmin = MIN (img_dbuf) dmax = MAX (img_dbuf) ; PRINT, 'Apply dmin/dmax: ', dmin, dmax sav_min = tv_min sav_max = tv_max sav_gamma = tv_gamma data_min = 0.0 data_max = 255.0 disp_min = 0.0 disp_max = 255.0 disp_gamma = 1.0 tv_min = disp_min tv_max = disp_max tv_gamma = disp_gamma vbot = 0 vtop = 100 gammaval = 1.0 PRINT, 'min_max_gam> sav_min/sav_max: ', sav_min, sav_max PRINT, 'min_max_gam> disp_min/disp_max: ', disp_min, disp_max PRINT, 'min_max_gam> tv_min/tv_max: ', tv_min, tv_max cminmax_refresh fminmax_refresh pminmax_refresh fw_display, img_dbuf, MIN=disp_min, MAX=disp_max GOTO, set_gamma END 'DATA_MIN': BEGIN ; Display minimum data pixel intensity. flash_msg, tw_info, 'Minimum data value is NOT changeable.' END 'DATA_MAX': BEGIN ; Display maximum data pixel intensity. flash_msg, tw_info, 'Maximum data value is NOT changeable.' END 'SET_MIN': BEGIN ; Set minimum scaling value for image file. value_old = disp_min loop = 1 WHILE loop DO BEGIN WIDGET_CONTROL, event.id, get_value = str_min disp_min = FLOAT (str_min (0)) IF (disp_min GT disp_max) THEN BEGIN flash_msg, tw_info, 'Minimum value cannot be set ' + $ 'greater than the maximum value.', num = 1 PRINT, 'Minimum value cannot be set ' + $ 'greater than the maximum value.' WAIT, 1.0 WIDGET_CONTROL, tw_info, SET_VALUE = '' disp_min = value_old ENDIF ELSE loop = 0 END IF (disp_min NE value_old) THEN BEGIN ; WIDGET_CONTROL, tw_disp_max, /input_focus adisp_min = ABS (disp_min) IF (adisp_min NE 0.0 AND $ adisp_min LT 0.001 OR adisp_min GE 10000.0) THEN $ WIDGET_CONTROL, tw_disp_min, $ SET_VALUE = num2str (disp_min, FORMAT="(E9.2)") $ ELSE $ WIDGET_CONTROL, tw_disp_min, $ SET_VALUE = num2str (disp_min, FORMAT="(F9.3)") vbot = 0 vtop = 100 gammaval = 1.0 tv_min = disp_min tv_max = disp_max tv_gamma = 1.0 cminmax_refresh fw_display, img_dbuf, MIN=disp_min, MAX=disp_max GOTO, set_gamma ENDIF END 'SET_MAX': BEGIN ; Set maximum scaling value for image file. value_old = disp_max loop = 1 WHILE loop DO BEGIN WIDGET_CONTROL, event.id, get_value = str_max disp_max = FLOAT (str_max (0)) IF (disp_max LT disp_min) THEN BEGIN flash_msg, tw_info, 'Maximum value cannot be set ' + $ 'smaller than the minimum value.', num = 1 PRINT, 'Maximum value cannot be set ' + $ 'smaller than the minimum value.' WAIT, 1.0 WIDGET_CONTROL, tw_info, SET_VALUE = '' disp_max = value_old ENDIF ELSE loop = 0 END IF (disp_max NE value_old) THEN BEGIN ; WIDGET_CONTROL, tw_disp_min, /input_focus adisp_max = ABS (disp_max) IF (adisp_max NE 0.0 AND $ adisp_max LT 0.001 OR adisp_max GE 10000.0) THEN $ WIDGET_CONTROL, tw_disp_max, $ SET_VALUE = num2str (disp_max, FORMAT="(E9.2)") $ ELSE $ WIDGET_CONTROL, tw_disp_max, $ SET_VALUE = num2str (disp_max, FORMAT="(F9.3)") vbot = 0 vtop = 100 gammaval = 1.0 tv_min = disp_min tv_max = disp_max tv_gamma = 1.0 cminmax_refresh fw_display, img_dbuf, MIN=disp_min, MAX=disp_max GOTO, set_gamma ENDIF END ENDCASE END ;------------------------------------------------------------------------------- PRO FW, GROUP=group, $ IMGDIR=imgdir, FILE=file, $ LUTDIR=lutdir, LUTLIST=lutlist, $ USE_CURRENT=use_current, NCOLORS=nc, BOTTOM=bottom ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; FITS widget analysis software ; ; PURPOSE ; Create widgets for FW functions. ; ; USAGE ; fw ; ; HISTORY ; Author: Andrew L. Stanger 17 April 1996 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @fw_common ;--- Explicitly set pseudocolor mode & shared color map. DEVICE, PSEUDO_COLOR = 8 WINDOW, XSIZE = 16, YSIZE = 16, COLORS = -1 WDELETE ;--------------------------------------------------------------------------- ; Define fonts. ;--------------------------------------------------------------------------- ; bfont = '-adobe-courier-bold-r-normal--20-140-100-100-m-110-iso8859-1' bfont = '-*-times-bold-r-normal-*-16-*-100-100-*-*-*-*' bfont = (get_dfont (bfont))(0) IF (bfont EQ '') THEN bfont = 'fixed' ; lfont = '-misc-fixed-bold-r-normal--13-100-100-100-c-70-iso8859-1' ; lfont = '-*-lucida-*-r-*-*-14-*-*-*-*-*-*-*' lfont = '-*-helvetica-*-r-*-*-14-*-*-*-*-*-*-*' lfont = (get_dfont (lfont))(0) IF (lfont EQ '') THEN lfont = 'fixed' ; lfont2 = '-misc-fixed-bold-r-normal--15-140-75-75-c-90-iso8859-1' lfont2 = '-*-sorority-*-r-*-*-14-*-*-*-*-*-*-*' lfont2 = (get_dfont (lfont2))(0) IF (lfont2 EQ '') THEN lfont2 = 'fixed' tfont = '-*-itc bookman-*-r-*-*-14-*-*-*-*-*-*-*' tfont = (get_dfont (tfont))(0) IF (tfont EQ '') THEN tfont = 'fixed' ;--- Initialize variables. xslide = 20 yslide = 200 lock = 0 chop = 0 vbot = 0 vtop = 100 gammaval = 1.0 use_values = 0 disp_min = 0 disp_max = 255 disp_gamma = 1.0 tv_min = disp_min tv_max = disp_max tv_top = 249 tv_gamma = disp_gamma sav_min = disp_min sav_max = disp_max sav_gamma = disp_gamma apply_minmaxgam = 0 ;--- Set initial image directory. env_img_dir = GETENV ('FW_IMG_DIR') ; Get env FW_IMG_DIR. IF (env_img_dir NE '') THEN $ img_dir = env_img_dir $ ELSE $ img_dir = '.' ; Default. IF (N_ELEMENTS (imgdir) NE 0) THEN $ ; imgdir overrides env. img_dir = imgdir env_img_file = GETENV ('FW_IMG_FILE') ; Gen env FW_IMG_FILE. IF (env_img_file NE '') THEN $ img_file = env_img_file $ ELSE $ img_file = '' ; Default. IF (n_elements (file) NE 0) THEN $ ; file overrides env. img_file = file ;--- Set color look-up table directory. env_lut_dir = GETENV ('FW_LUT_DIR') ; Get env FW_LUT_DIR. IF (env_lut_dir NE '') THEN $ lut_dir = env_lut_dir $ ELSE $ lut_dir = '/home/stanger/idl/color' ; Default. IF (n_elements (lutdir) NE 0) THEN $ ; lutdir overrides env. lut_dir = lutdir env_lut_list = GETENV ('FW_LUT_LIST') ; Gen env FW_LUT_LIST. IF (env_lut_list NE '') THEN $ lut_list = env_lut_list $ ELSE $ lut_list = 'fw_lut.ls' ; Default. IF (n_elements (lutlist) NE 0) THEN $ ; lutlist overrides env. lut_list = lutlist lut_path = lut_dir + '/' + lut_list GET_LUN, lun OPENR, lun, lut_path ntables = 0b lutfile = '' WHILE (NOT EOF (lun)) DO $ BEGIN READF, lun, FORMAT = "(A)", lutfile ntables = ntables + 1 ; PRINT, 'ntables: ', ntables, ' lutfile: ', lutfile END ; PRINT, 'ntables: ', ntables lut_paths = strarr (ntables) lut_names = strarr (ntables) POINT_LUN, lun, 0 ; Reset pointer to BOF. FOR i = 0, ntables - 1 DO $ BEGIN readf, lun, FORMAT = "(A)", lutfile lut_names (i) = lutfile END lut_paths = lut_dir + '/' + lut_names ; PRINT, 'lutpaths: ' ; PRINT, lutpaths IF (N_ELEMENTS (group) EQ 0) THEN GROUP=0 junk = { CW_PDMENU_S, flags:0, name:'' } ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;--- Define Widgets. BASEFW = WIDGET_BASE (GROUP_LEADER=group, $ ; Root base. COLUMN=1, $ MAP=1, $ TITLE='FW', $ UVALUE='BASEFW') BASE0 = WIDGET_BASE (BASEFW, $ ; Major Row base. ROW=1, $ MAP=1, $ UVALUE='BASE0') BASE1 = WIDGET_BASE (BASE0, $ ; Base for left column. COLUMN=1, $ MAP=1, $ UVALUE='BASE1') BASE1T = WIDGET_BASE (BASE1, $ ; Base for buttons. ROW=1, $ MAP=1, $ UVALUE='BASE1T') BASE1TL = WIDGET_BASE (BASE1T, $ ; Quit/Load/Save base. COLUMN=1, $ MAP=1, $ UVALUE='BASE1TL') BASE1TR = WIDGET_BASE (BASE1T, $ ; Base: col 1 top right. COLUMN=1, $ MAP=1, $ UVALUE='BASE1TR') BUTTON1 = WIDGET_BUTTON (BASE1TL, $ ; Quit button. UVALUE='BUTTON1', $ VALUE='Quit', $ FONT=bfont) BUTTON2 = WIDGET_BUTTON (BASE1TL, $ ; Load Image button. UVALUE='BUTTON2', $ VALUE='Load Image', $ FONT=bfont) BUTTON3 = WIDGET_BUTTON (BASE1TL, $ ; Restore Image button. UVALUE='BUTTON3', $ VALUE='Restore Image', $ FONT=bfont) BUTTON4 = WIDGET_BUTTON (BASE1TR, $ ; Save Image button. UVALUE='BUTTON4', $ VALUE='Save Image: FITS', $ FONT=bfont) BUTTON5 = WIDGET_BUTTON (BASE1TR, $ ; Save Image button. UVALUE='BUTTON5', $ VALUE='Save Image: Sun Raster', $ FONT=bfont) ; BUTTON6 = WIDGET_BUTTON (BASE1TR, $ ; Solar Grid button. ; UVALUE='BUTTON6', $ ; VALUE='Grid', $ ; FONT=bfont) ; WIDGET_CONTROL, BUTTON6, SENSITIVE=0 ; Make insensitive. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BASE1A = WIDGET_BASE (BASE1, $ ; Apply base. /ROW, $ /MAP, $ UVALUE='BASEA') LABELB1A = WIDGET_LABEL (BASE1A, $ UVALUE='LABELB1A', $ VALUE='Image Intensity', $ FONT=lfont2) APPLY_BUTTON = WIDGET_BUTTON (BASE1A, $ UVALUE='MIN_MAX_GAM', $ VALUE='Apply min/max/gamma', $ FONT=bfont) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BASE1M = WIDGET_BASE (BASE1, $ ; Modify LUT base. /COLUMN, $ /MAP, $ UVALUE='BASE1M') LABELB1M = WIDGET_LABEL (BASE1M, $ UVALUE='LABELB1M', $ VALUE='LUT Intensity', $ FONT=lfont2) BASE1MS = WIDGET_BASE (BASE1M, $ ; Modify LUT slider base /ROW, $ /MAP, $ UVALUE='BASE1MS') BASE1MS1 = WIDGET_BASE (BASE1MS, $ ; Min slider base. XSIZE=80, $ /COLUMN, $ /MAP, $ UVALUE='BASE1MS1') MIN_SLIDER = WIDGET_SLIDER (BASE1MS1, TITLE = "Min", $ /VERTICAL, $ MINIMUM = 0, MAXIMUM = 100, VALUE = 0, $ /DRAG, UVALUE = "MINIMUM", XSIZE=xslide, YSIZE=yslide) BASE1MS2 = WIDGET_BASE (BASE1MS, $ ; Max slider base. XSIZE=80, $ /COLUMN, $ /MAP, $ UVALUE='BASE1MS2') MAX_SLIDER = WIDGET_SLIDER (BASE1MS2, TITLE = "Max", $ /VERTICAL, $ MINIMUM = 0, MAXIMUM = 100, VALUE = 100, $ /DRAG, UVALUE = "MAXIMUM", XSIZE=xslide, YSIZE=yslide) BASE1MS3 = WIDGET_BASE (BASE1MS, $ ; Gamma slider base. XSIZE=80, $ /COLUMN, $ /MAP, $ UVALUE='BASE1MS3') GAMMA_SLIDER = WIDGET_SLIDER (BASE1MS3, TITLE = "Gamma", $ /VERTICAL, $ MINIMUM = 0, MAXIMUM = 100, VALUE = 50, $ /DRAG, UVALUE = "GAMMA", /SUPPRESS_VALUE, XSIZE=xslide, YSIZE=yslide) GAMMA_LABEL = WIDGET_LABEL (BASE1MS3, VALUE = STRING (1.0), FONT=lfont) BASE1C = WIDGET_BASE (BASE1, $ ; Modify Colormap base. /COLUMN, $ /MAP, $ UVALUE='BASE1C') DEVICE, GET_SCREEN = scrsiz IF (scrsiz (1) LE 768) THEN nlut = 8 ELSE nlut = 16 wl_lut = WIDGET_LIST (BASE1C, VALUE = lut_names, ysize = nlut) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BASE2 = WIDGET_BASE (BASE0, $ ; Annotation base. COLUMN=1, $ MAP=1, $ UVALUE='BASE2') BUTTON7 = WIDGET_BUTTON (BASE2, $ UVALUE='BUTTON7', $ VALUE='FITS Header', $ FONT=bfont) WIDGET_CONTROL, BUTTON7, SENSITIVE=0 ; Make insensitive. LABEL4 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL4', $ VALUE='Day Of Year', $ FONT=lfont) TextVal4 = [ '001-366' ] TEXT4 = WIDGET_TEXT (BASE2, VALUE=TextVal4, $ EDITABLE=1, $ UVALUE='TEXT4', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_doy = TEXT4 LABEL5 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL5', $ VALUE='Date', $ FONT=lfont) TextVal5 = [ 'YY/MM/DD' ] TEXT5 = WIDGET_TEXT (BASE2, VALUE=TextVal5, $ EDITABLE=1, $ UVALUE='TEXT5', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_date_obs = TEXT5 LABEL6 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL6', $ VALUE='Time (UT)', $ FONT=lfont) TextVal6 = [ 'HH:MM:SS' ] TEXT6 = WIDGET_TEXT (BASE2, VALUE=TextVal6, $ EDITABLE=1, $ UVALUE='TEXT6', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_time_obs = TEXT6 LABEL7 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL7', $ VALUE='Origin', $ FONT=lfont) TextVal7 = [ 'Observatory' ] TEXT7 = WIDGET_TEXT (BASE2, VALUE=TextVal7, $ EDITABLE=1, $ UVALUE='TEXT7', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_origin = TEXT7 LABEL8 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL8', $ VALUE='Telescope', $ FONT=lfont) TextVal8 = [ 'Name' ] TEXT8 = WIDGET_TEXT (BASE2, VALUE=TextVal8, $ EDITABLE=1, $ UVALUE='TEXT8', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_telescop = TEXT8 LABEL9 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL9', $ VALUE='Object', $ FONT=lfont) TextVal9 = [ 'Sun' ] TEXT9 = WIDGET_TEXT (BASE2, VALUE=TextVal9, $ EDITABLE=1, $ UVALUE='TEXT9', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_object = TEXT9 LABEL10 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL10', $ VALUE='Type-Obs', $ FONT=lfont) TextVal10 = [ 'Observation Type' ] TEXT10 = WIDGET_TEXT (BASE2, VALUE=TextVal10, $ EDITABLE=1, $ UVALUE='TEXT10', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_type_obs = TEXT10 LABEL11 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL11', $ VALUE='Type-DP', $ FONT=lfont) TextVal11 = [ 'Raw Image' ] TEXT11 = WIDGET_TEXT (BASE2, VALUE=TextVal11, $ EDITABLE=1, $ UVALUE='TEXT11', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_type_dp =TEXT11 LABEL12 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL12', $ VALUE='X Sun Center', $ FONT=lfont) TextVal12 = [ 'X [pixels]' ] TEXT12 = WIDGET_TEXT (BASE2, VALUE=TextVal12, $ EDITABLE=1, $ UVALUE='TEXT12', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_crpix1 =TEXT12 LABEL13 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL13', $ VALUE='Y Sun Center', $ FONT=lfont) TextVal13 = [ 'Y [pixels]' ] TEXT13 = WIDGET_TEXT (BASE2, VALUE=TextVal13, $ EDITABLE=1, $ UVALUE='TEXT13', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_crpix2 =TEXT13 LABEL14 = WIDGET_LABEL (BASE2, $ UVALUE='LABEL14', $ VALUE='Solar Radius', $ FONT=lfont) TextVal14 = [ 'Radius [pixels]' ] TEXT14 = WIDGET_TEXT (BASE2, VALUE=TextVal14, $ EDITABLE=1, $ UVALUE='TEXT14', $ XSIZE=16, YSIZE=1, $ FONT=tfont) tw_crradius =TEXT14 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BASE3 = WIDGET_BASE (BASE0, $ ; Image Display base. COLUMN=1, $ MAP=1, $ UVALUE='BASE3') tw_file_id = WIDGET_TEXT (BASE3, $ ; Image filename. VALUE='', $ UVALUE='', $ YSIZE=2, $ FONT=tfont, $ /FRAME) BASE3T = WIDGET_BASE (BASE3, $ ; Image Window base. COLUMN=1, $ MAP=1, $ UVALUE='BASE3T') ximg = 520 yimg = 520 DRAW3T = WIDGET_DRAW (BASE3T, $ ; Image window. RETAIN=2, $ UVALUE='DRAW3T', $ XSIZE=ximg, $ YSIZE=yimg) BASE3B = WIDGET_BASE (BASE3, $ ; Color bar base. COLUMN=1, $ MAP=1, $ UVALUE='BASE3B') xct = 512 yct = 20 DRAW3B = WIDGET_DRAW (BASE3B, $ ; Color bar window. RETAIN=2, $ UVALUE='DRAW3B', $ XSIZE=xct, $ YSIZE=yct) BASE3P = WIDGET_BASE (BASE3, $ ; MIN/MAX pixel base. ROW=1, $ MAP=1, $ UVALUE='BASE3P') lw_data_range = WIDGET_LABEL (BASE3P, $ ; Data range label. VALUE='DATA RANGE', $ FONT=lfont2) BASE3PL = WIDGET_BASE (BASE3P, $ ; MIN pixel base. ROW=1, $ MAP=1, $ UVALUE='BASE3PL') lw_data_min = WIDGET_LABEL (BASE3PL, $ ; MIN pixel label. VALUE='DATA MIN', $ FONT=lfont) tw_data_min = WIDGET_TEXT (BASE3PL, $ ; MIN pixel text. VALUE = '', $ UVALUE = 'DATA_MIN', $ XSIZE = 9, $ FONT=tfont) BASE3PR = WIDGET_BASE (BASE3P, $ ; MAX pixel base. ROW=1, $ MAP=1, $ UVALUE='BASE3PR') lw_data_max = WIDGET_LABEL (BASE3PR, $ ; MAX pixel label. VALUE='DATA MAX', $ FONT=lfont) tw_data_max = WIDGET_TEXT (BASE3PR, $ ; MAX pixel text. VALUE = '', $ UVALUE = 'DATA_MAX', $ XSIZE = 9, $ FONT=tfont) BASE3S = WIDGET_BASE (BASE3, $ ; MIN/MAX scaling base. ROW=1, $ MAP=1, $ UVALUE='BASE3S') lw_disp_range = WIDGET_LABEL (BASE3S, $ ; Display range label. VALUE='DISP RANGE', $ FONT=lfont2) BASE3SL = WIDGET_BASE (BASE3S, $ ; MIN scaling base. ROW=1, $ MAP=1, $ UVALUE='BASE3SL') lw_disp_min = WIDGET_LABEL (BASE3SL, $ ; MIN scaling label. VALUE='DISP MIN', $ FONT=lfont) tw_disp_min = WIDGET_TEXT (BASE3SL, $ ; MIN scaling text. VALUE = '', $ UVALUE = 'SET_MIN', $ XSIZE = 9, $ FONT=tfont, $ /EDITABLE) BASE3SR = WIDGET_BASE (BASE3S, $ ; MAX scaling base. ROW=1, $ MAP=1, $ UVALUE='BASE3SR') lw_disp_max = WIDGET_LABEL (BASE3SR, $ ; MAX scaling label. VALUE='DISP MAX', $ FONT=lfont) tw_disp_max = WIDGET_TEXT (BASE3SR, $ ; MAX scaling text. VALUE = '', $ UVALUE = 'SET_MAX', $ XSIZE = 9, $ FONT=tfont, $ /EDITABLE) tw_info = WIDGET_TEXT (BASEFW, $ ; Information text. YSIZE=2, $ FONT=tfont, $ /FRAME) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;--- Create Widgets. WIDGET_CONTROL, BASE0, /REALIZE ; WIDGET_CONTROL, state.draw, GET_VALUE=tmp ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IF (N_ELEMENTS (bottom) GT 0) THEN cbot = bottom ELSE cbot = 0 ncolors = !d.table_size - cbot IF (N_ELEMENTS (nc) GT 0) THEN ncolors = ncolors < nc IF (ncolors LE 0) THEN message,'Number of colors is 0 or negative' ;--- If no common, use current colors IF (KEYWORD_SET (use_current) or N_ELEMENTS (r_orig) LE 0) THEN BEGIN TVLCT, r_orig, g_orig, b_orig, /GET r_curr = r_orig b_curr = b_orig g_curr = g_orig ENDIF r0 = r_curr ; Save original colors g0 = g_curr b0 = b_curr color = ncolors + cbot -1 cps = [0, ncolors-1] tfun = cps pnt = -1 index = bindgen (256) red = bindgen (256) green = bindgen (256) blue = bindgen (256) r = red g = green b = blue IF (ncolors NE 256) THEN $ BEGIN p = (LINDGEN (ncolors) * 255) / (ncolors - 1) r = red (p) g = green (p) b = blue (p) END r_orig (cbot) = r g_orig (cbot) = g b_orig (cbot) = b r_curr = r_orig g_curr = g_orig b_curr = b_orig tvlct, r_orig, g_orig, b_orig, cbot ; PRINT, 'fw> size (r_orig): ', size (r_orig) ; PRINT, 'fw> r_orig: ' ; PRINT, r_orig ; PRINT, '!d.table_size: ', !D.TABLE_SIZE ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;--- Get drawable window index. COMMON DRAW3T_Comm, DRAW7_Id WIDGET_CONTROL, DRAW3T, GET_VALUE=DRAW3T_Id WIDGET_CONTROL, DRAW3B, get_value=tmp1 WSET, tmp1 TVSCL, BYTSCL (INDGEN (xct) # REPLICATE (1, yct), top = !d.n_colors-1) WSET, DRAW3T_Id ;--- Set initial image file for testing: ; imgdir = '/riker/usr/people/stanger/idl/lib/acos/' ; imgfile = '801050544.c4q.fts' ; img_dir = imgdir ; img_file = imgfile ; img_path = img_dir + '/' + img_file img_path = img_dir + img_file ; img_dir must end with '/'. PRINT, 'img_dir: ', img_dir PRINT, 'img_file: ', img_file PRINT, 'img_path: ', img_path ;--- Load initial image (if specified). IF (img_file NE '') THEN $ BEGIN WIDGET_CONTROL, tw_file_id, SET_VALUE = img_file img_ibuf = readfits (img_path, img_hdu) img_dbuf = img_ibuf fw_house, img_hdu fw_display, img_dbuf, MIN=disp_min, MAX=disp_max PRINT, 'fw>min (img_dbuf): ', min (img_dbuf), $ ' max (img_dbuf): ', max (img_dbuf) END $ ELSE $ flash_msg, tw_info, $ 'Use Load Image button to select an input image to display.', num=1 XMANAGER, 'FW', BASE0 END