
; Modified considerably in July 1998 by Chris Jacobsen and
; Samuel Patarin to include image deconvolution
;
; 25-mar-1998: modified for 24 bit graphics.  CJJ

PRO tweak_sensitive, main=main, flatten=flatten, $
    fourfilt=fourfilt, deconvol=deconvol, none=none

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm


IF keyword_set(main) THEN BEGIN
    widget_control, tweak_par.disp_min_label, sensitive = 1
    widget_control, tweak_par.disp_max_label, sensitive = 1
    widget_control, tweak_par.disp_gamma_label, sensitive = 1

    widget_control, tweak_par.flatten_label, sensitive = 1
    widget_control, tweak_par.flatten_add_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_reset_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_order_label, sensitive = 0
    widget_control, tweak_par.flatten_doit_label, sensitive = 0

    widget_control, tweak_par.fourfilt_label, sensitive = 1
    widget_control, tweak_par.fourfilt_add_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_reset_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_doit_label, sensitive = 0

    widget_control, tweak_par.wienerfilt_label, sensitive = 1
    widget_control, tweak_par.deconvolve_label, sensitive=1
    widget_control, tweak_par.crop_label, sensitive = 1

    widget_control, tweak_par.header_label, sensitive = 1
    IF (strlen(filename_header) NE 0) THEN BEGIN
        widget_control, tweak_par.save_gif_label, $
            sensitive = 1
        widget_control, tweak_par.save_eps_label, $
            sensitive = 1
        widget_control, tweak_par.save_ncdf_label, $
            sensitive = 1
    ENDIF ELSE BEGIN
        widget_control, tweak_par.save_gif_label, $
            sensitive = 0
        widget_control, tweak_par.save_eps_label, $
            sensitive = 0
        widget_control, tweak_par.save_ncdf_label, $
            sensitive = 0
    ENDELSE

    widget_control, tweak_par.revert_label, sensitive = 1
    widget_control, tweak_par.exit_label, sensitive = 1
ENDIF ELSE IF keyword_set(flatten) THEN BEGIN
    widget_control, tweak_par.disp_min_label, sensitive = 1
    widget_control, tweak_par.disp_max_label, sensitive = 1
    widget_control, tweak_par.disp_gamma_label, sensitive = 1

    widget_control, tweak_par.flatten_label, sensitive = 1
    widget_control, tweak_par.flatten_add_roi_label, sensitive = 1
    widget_control, tweak_par.flatten_reset_roi_label, sensitive = 1
    widget_control, tweak_par.flatten_order_label, sensitive = 1
    widget_control, tweak_par.flatten_doit_label, sensitive = 1

    widget_control, tweak_par.fourfilt_label, sensitive = 1
    widget_control, tweak_par.fourfilt_add_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_reset_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_doit_label, sensitive = 0

    widget_control, tweak_par.wienerfilt_label, sensitive = 0
    widget_control, tweak_par.deconvolve_label, sensitive=0
    widget_control, tweak_par.crop_label, sensitive = 0
 
    widget_control, tweak_par.header_label, sensitive = 0
    widget_control, tweak_par.save_gif_label, sensitive = 0
    widget_control, tweak_par.save_eps_label, sensitive = 0
    widget_control, tweak_par.save_ncdf_label, sensitive = 0

    widget_control, tweak_par.revert_label, sensitive = 1
    widget_control, tweak_par.exit_label, sensitive = 1
ENDIF ELSE IF keyword_set(fourfilt) THEN BEGIN
    widget_control, tweak_par.disp_min_label, sensitive = 1
    widget_control, tweak_par.disp_max_label, sensitive = 1
    widget_control, tweak_par.disp_gamma_label, sensitive = 1

    widget_control, tweak_par.flatten_label, sensitive = 1
    widget_control, tweak_par.flatten_add_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_reset_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_order_label, sensitive = 0
    widget_control, tweak_par.flatten_doit_label, sensitive = 0

    widget_control, tweak_par.fourfilt_label, sensitive = 1
    widget_control, tweak_par.fourfilt_add_roi_label, sensitive = 1
    widget_control, tweak_par.fourfilt_reset_roi_label, sensitive = 1
    widget_control, tweak_par.fourfilt_doit_label, sensitive = 1

    widget_control, tweak_par.wienerfilt_label, sensitive=0
    widget_control, tweak_par.deconvolve_label, sensitive=0
    widget_control, tweak_par.crop_label, sensitive = 0
   
    widget_control, tweak_par.header_label, sensitive = 0
    widget_control, tweak_par.save_gif_label, sensitive = 0
    widget_control, tweak_par.save_eps_label, sensitive = 0
    widget_control, tweak_par.save_ncdf_label, sensitive = 0

    widget_control, tweak_par.revert_label, sensitive = 1
    widget_control, tweak_par.exit_label, sensitive = 1

ENDIF ELSE IF keyword_set(deconvol) THEN BEGIN
    widget_control, tweak_par.disp_min_label, sensitive = 1
    widget_control, tweak_par.disp_max_label, sensitive = 1
    widget_control, tweak_par.disp_gamma_label, sensitive = 1

    widget_control, tweak_par.flatten_label, sensitive = 0
    widget_control, tweak_par.flatten_add_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_reset_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_order_label, sensitive = 0
    widget_control, tweak_par.flatten_doit_label, sensitive = 0

    widget_control, tweak_par.fourfilt_label, sensitive = 0
    widget_control, tweak_par.fourfilt_add_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_reset_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_doit_label, sensitive = 0

    widget_control, tweak_par.wienerfilt_label, sensitive= 0
    widget_control, tweak_par.deconvolve_label, sensitive=0
    widget_control, tweak_par.crop_label, sensitive=0

    widget_control, tweak_par.header_label, sensitive = 0
    widget_control, tweak_par.save_gif_label, sensitive = 0
    widget_control, tweak_par.save_eps_label, sensitive = 0
    widget_control, tweak_par.save_ncdf_label, sensitive = 0

    widget_control, tweak_par.revert_label, sensitive = 1
    widget_control, tweak_par.exit_label, sensitive = 1


ENDIF ELSE IF keyword_set(none) THEN BEGIN
    widget_control, tweak_par.disp_min_label, sensitive = 0
    widget_control, tweak_par.disp_max_label, sensitive = 0
    widget_control, tweak_par.disp_gamma_label, sensitive = 0

    widget_control, tweak_par.flatten_label, sensitive = 0
    widget_control, tweak_par.flatten_add_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_reset_roi_label, sensitive = 0
    widget_control, tweak_par.flatten_order_label, sensitive = 0
    widget_control, tweak_par.flatten_doit_label, sensitive = 0

    widget_control, tweak_par.fourfilt_label, sensitive = 0
    widget_control, tweak_par.fourfilt_add_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_reset_roi_label, sensitive = 0
    widget_control, tweak_par.fourfilt_doit_label, sensitive = 0

    widget_control, tweak_par.wienerfilt_label, sensitive = 0
    widget_control, tweak_par.deconvolve_label, sensitive=0
    widget_control, tweak_par.crop_label, sensitive = 0

    widget_control, tweak_par.header_label, sensitive = 0
    widget_control, tweak_par.save_gif_label, sensitive = 0
    widget_control, tweak_par.save_eps_label, sensitive = 0
    widget_control, tweak_par.save_ncdf_label, sensitive = 0

    widget_control, tweak_par.revert_label, sensitive = 0    
    widget_control, tweak_par.exit_label, sensitive = 0

   
ENDIF

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; For the moment this only works for linear flattening

PRO tweak_flatten

@bsif_common

COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

roi_svec = size(flatten_roi)
IF (roi_svec(0) EQ 0) THEN return

y_indices = flatten_roi / n_cols
y_indices = double(y_indices)
x_indices = flatten_roi mod n_cols
x_indices = double(x_indices)

sum_x = total(x_indices)
sum_y = total(y_indices)
sum_z = total(double(tweaked_image(flatten_roi)))
sum_x_squared = total(x_indices*x_indices)
sum_y_squared = total(y_indices*y_indices)
sum_z_squared = total(double(tweaked_image(flatten_roi) * $
                             tweaked_image(flatten_roi)))
sum_xy = total(x_indices*y_indices)
sum_xz = total(x_indices*tweaked_image(flatten_roi))
sum_yz = total(y_indices*tweaked_image(flatten_roi))
sum_n = double(n_elements(flatten_roi))

a_numerator = sum_xz * $
    (sum_n * sum_y_squared - sum_y * sum_y) - $
     sum_xy * (sum_n * sum_yz - sum_y * sum_z) + $
     sum_x * (sum_yz * sum_y - sum_y_squared * sum_z)
a_denominator = sum_x_squared * $
    (sum_n * sum_y_squared - sum_y * sum_y) - $
     sum_xy * (sum_n * sum_xy - sum_x * sum_y) + $
     sum_x * (sum_xy * sum_y - sum_y_squared * sum_x)
a_fit = a_numerator / a_denominator

b_numerator = sum_x_squared * (sum_n * sum_yz - sum_y * sum_z) - $
    sum_xz * (sum_n * sum_xy - sum_x * sum_y) + $
    sum_x * (sum_xy * sum_z - sum_yz * sum_x)
b_denominator = a_denominator
b_fit = b_numerator / b_denominator

c_numerator = sum_x_squared * (sum_y_squared * sum_z - sum_y * sum_yz) - $
    sum_xy * (sum_xy * sum_z - sum_x * sum_yz) + $
    sum_xz * (sum_xy * sum_y - sum_x * sum_y_squared)
c_denominator = a_denominator
c_fit = c_numerator / c_denominator

all_n = n_elements(tweaked_image)
all_indices = lindgen(all_n)
all_x_indices = all_indices mod n_cols
all_y_indices = all_indices / n_cols
all_x_indices = float(all_x_indices)
all_y_indices = float(all_y_indices)

dc_before = total(tweaked_image)/float(all_n)
tweaked_image = tweaked_image - $
    (a_fit*all_x_indices + b_fit*all_y_indices + c_fit)
dc_after = total(tweaked_image)/float(all_n)
tweaked_image = tweaked_image + dc_before - dc_after

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_imgdisp

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

byte_image = byte(0.5+float(top_color_index)*(( $
                  (((tweaked_image-disp_min) / $
                  float(disp_max-disp_min))^disp_gamma) $
                  >0.)<1.))<byte(top_color_index)

roi_svec = size(flatten_roi)
IF (roi_svec(0) NE 0) THEN BEGIN
    byte_image(flatten_roi) = roi_color_index
ENDIF

wset,tweak_par.image_win
erase
tv,rebin(byte_image,n_cols*img_zoom,n_rows*img_zoom,/sample),$
    0,textregion_ypix,/device
tv,bytarr(n_cols*img_zoom,textregion_ypix)+top_color_index,0,0,/device

bar_microns = 0.2*abs(x_stop-x_start)
IF (bar_microns GE 10.) THEN BEGIN
    bar_microns = 10.*fix(0.5+0.1*fix(0.5+bar_microns))
    bar_string = strtrim(string(fix(0.01+bar_microns)),2)+' microns'
    bar_psstring = strtrim(string(fix(0.01+bar_microns)),2)+' !Mm!Xm'
ENDIF ELSE IF (bar_microns GE 1.) THEN BEGIN
    bar_microns = float(fix(0.5+bar_microns))
    IF (bar_microns EQ 1.) THEN BEGIN
        bar_string = '1 micron'
        bar_psstring = '1 !Mm!Xm'
    ENDIF ELSE BEGIN
        bar_string = strtrim(string(fix(0.01+bar_microns)),2)+' microns'
        bar_psstring = strtrim(string(fix(0.01+bar_microns)),2)+' !Mm!Xm'
    ENDELSE
ENDIF ELSE BEGIN
    bar_microns = (0.1*fix(0.5+10*bar_microns))>0.1
    bar_string = strtrim(string(bar_microns,format='(f10.1)'),2)+' microns'
    bar_psstring = strtrim(string(bar_microns,format='(f10.1)'),2)+' !Mm!Xm'
ENDELSE
bar_pixels = fix(0.5+float(n_cols*img_zoom)*float(bar_microns) / $
                 float(abs(x_stop-x_start)))
bar = bytarr(bar_pixels,fix(0.6*char_ypix))

tv,bar,5,fix(0.25*char_ypix),/device
xyouts,(5+bar_pixels+char_ypix),fix(0.25*char_ypix),/device,font=0,$
    charsize=charsize,bar_string,color=0

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_powdisp

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

powbyte_image = bytscl(alog(abs(fft_image*conj(fft_image))),$
    top=top_color_index)

roi_svec = size(fourfilt_roi)
IF (roi_svec(0) NE 0) THEN BEGIN
    powbyte_image(fourfilt_roi) = roi_color_index
ENDIF

wset,tweak_par.image_win
erase
tv,rebin(powbyte_image,n_cols*img_zoom,n_rows*img_zoom,/sample), $
    0,textregion_ypix,/device

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_roi_event,event

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

CASE event.id OF
    tweak_par.roi_accept_label: BEGIN
        IF (tweak_par.type_of_tweak EQ 1) THEN BEGIN
            svec = size(this_roi)
            IF (svec(0) EQ 0) THEN BEGIN
                flatten_roi = this_roi
            ENDIF ELSE BEGIN
                flatten_roi = [flatten_roi,this_roi]
                flatten_roi = flatten_roi(uniq(flatten_roi,sort(flatten_roi)))
            ENDELSE
            widget_control, hourglass = 1
            tweak_imgdisp
            tweak_sensitive, /flatten
            widget_control, hourglass = 0
        ENDIF ELSE IF (tweak_par.type_of_tweak EQ 2) THEN BEGIN
            svec = size(this_roi)
            IF (svec(0) EQ 0) THEN BEGIN
                fourfilt_roi = this_roi
            ENDIF ELSE BEGIN
                fourfilt_roi = [fourfilt_roi,this_roi]
                fourfilt_roi = fourfilt_roi(uniq(fourfilt_roi,sort(fourfilt_roi)))
            ENDELSE
            widget_control, hourglass = 1
            tweak_powdisp
            tweak_sensitive, /fourfilt
            widget_control, hourglass = 0
        ENDIF ELSE BEGIN
            print,'Unknown type of tweak'
        ENDELSE
        widget_control, tweak_par.roi_base,/destroy
        widget_control, tweak_par.main_base,show=1
    END

    tweak_par.roi_reject_label: BEGIN
        IF (tweak_par.type_of_tweak EQ 1) THEN BEGIN
            widget_control, hourglass = 1
            tweak_imgdisp
            tweak_sensitive, /flatten
            widget_control, hourglass = 0
        ENDIF ELSE IF (tweak_par.type_of_tweak EQ 2) THEN BEGIN
            widget_control, hourglass = 1
            tweak_powdisp
            tweak_sensitive, /fourfilt
            widget_control, hourglass = 0
        ENDIF ELSE BEGIN
            print,'Unknown type of tweak'
        ENDELSE
        widget_control, tweak_par.roi_base,/destroy
        widget_control, tweak_par.main_base,show=1
    END

    tweak_par.image_label: BEGIN
    END

ENDCASE
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_roi

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

tweak_par.roi_base = $
    widget_base(title='Define region',/column)
label = $
    widget_text( tweak_par.roi_base, $
                 xsize=30, ysize=4,/scroll,/wrap, $
                 value='Left button adds points, middle button '+$
                       'erases last point, right button closes '+$
                       'region.  You must then either ACCEPT or '+$
                       'REJECT the region.')
tweak_par.roi_accept_label = $
    widget_button( tweak_par.roi_base, value='ACCEPT region')
tweak_par.roi_reject_label = $
    widget_button( tweak_par.roi_base, value='REJECT region')

tweak_sensitive, /none

widget_control, tweak_par.roi_base, /realize
widget_control, tweak_par.roi_accept_label, sensitive=0
widget_control, tweak_par.roi_reject_label, sensitive=0
;widget_control, tweak_par.main_base,show=1

wset,tweak_par.image_win
this_roi = defroi(n_cols,n_rows,zoom=img_zoom,y0=textregion_ypix)

widget_control, tweak_par.roi_accept_label, sensitive=1
widget_control, tweak_par.roi_reject_label, sensitive=1
widget_control, tweak_par.roi_base,show=1,map=1
xmanager, 'tweak_roi', tweak_par.roi_base, $
    group_leader = tweak_par.main_base

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_wiener_event,event

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

CASE event.id OF
    tweak_par.wiener_accept_label: BEGIN
        widget_control, hourglass=1
        print,'Transforming back to image space'
        tweaked_image = float(shift(fft(shift(fft_image,$
                                              n_cols/2,n_rows/2),$
                                        1),n_cols/2,n_rows/2))
        tweak_imgdisp
        tweak_sensitive, /main
        widget_control, tweak_par.wiener_base,/destroy
        widget_control, tweak_par.main_base,show=1
        widget_control, hourglass=0
    END

    tweak_par.wiener_ignore_label: BEGIN
        widget_control, hourglass=1
        tweak_imgdisp
        tweak_sensitive, /main
        widget_control, tweak_par.wiener_base,/destroy
        widget_control, tweak_par.main_base,show=1
        widget_control, hourglass=0
    END

    tweak_par.wiener_plot_label: BEGIN
        CASE tweak_par.wiener_step OF
            1: BEGIN
                ; In this case, the user was asked to click on
                ; the noise floor.
                IF (event.press NE 0) THEN BEGIN
                    wset,tweak_par.wiener_plot_win
                    coords = convert_coord( event.x, event.y,/device,/to_data)
                    noise_floor = coords(1)
                    oplot,10.^(!x.crange),[0.,0.]+noise_floor,$
                        color=roi_plot_index
                    widget_control, tweak_par.wiener_text_label, $
                        set_value = 'Now click on 1st of 2 points on the '+$
                                    'signal curve.'
                    tweak_par.wiener_step = 2
                ENDIF
            END

            2: BEGIN
                ; Now the user was asked to click on
                ; one point on the signal curve
                IF (event.press NE 0) THEN BEGIN
                    wset,tweak_par.wiener_plot_win
                    coords = convert_coord( event.x, event.y,/device,/to_data)
                    sig1_xy = coords
                    widget_control, tweak_par.wiener_text_label, $
                        set_value = 'Click on the 2nd point on the '+$
                                    'signal curve.'
                    tweak_par.wiener_step = 3
                ENDIF
            END

            3: BEGIN
                ; Now the user was asked to click on
                ; a second point on the signal curve
                IF (event.press NE 0) THEN BEGIN
                    coords = convert_coord( event.x, event.y,/device,/to_data)
                    sig2_xy = coords
                    tweak_par.wiener_step = 0

                    ; Now we do the calculation.
                    widget_control, hourglass=1
                    sig_slope = float(alog10(sig1_xy(1))-alog10(sig2_xy(1))) / $
                        float(alog10(sig1_xy(0))-alog10(sig2_xy(0)))
                    sig_yintercept = alog10(sig1_xy(1)) - $
                        alog10(sig1_xy(0))*sig_slope
                    crossing_freq = $
                        10.^((alog10(noise_floor)-sig_yintercept) / sig_slope)
                    info_string = 'Signal curve declines as frequency '+$
                        'to the power '+$
                        strtrim(string(sig_slope,format='(f10.2)'),2)+$
                        ', with a crossing point at '+$
                        strtrim(string(crossing_freq,format='(f10.1)'),2)+$
                        ' inverse microns, or a half-period of '+$
                        strtrim(string(1./(2.*crossing_freq),$
                          format='(f12.3)'),2)+$
                        ' microns.  Now either apply or ignore filter.'
                    widget_control, tweak_par.wiener_text_label, $
                        set_value = info_string

                    xpoints = 10.^(!x.crange)
                    ypoints = 10.^(sig_slope*!x.crange+sig_yintercept)
                    oplot,xpoints,ypoints,color=roi_plot_index
                    wait,.001
                    signal_curve = 10.^(sig_slope*alog10(freq)+sig_yintercept)
                    wiener_filter = signal_curve/(signal_curve+noise_floor)
                    fft_image = fft_image*wiener_filter(freq_indices)
                    tweak_powdisp
                    widget_control, hourglass=0

                    widget_control, tweak_par.wiener_accept_label, $
                        sensitive = 1
                    widget_control, tweak_par.wiener_ignore_label, $
                        sensitive = 1
                ENDIF
            END
            ELSE: ; nothing
        ENDCASE
    END

ENDCASE
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_wiener

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

tweak_par.wiener_base = $
    widget_base(title='Tweak: Wiener filter',/row)
col1 = widget_base(tweak_par.wiener_base,/col)
col2 = widget_base(tweak_par.wiener_base,/col)

tweak_par.wiener_text_label = $
    widget_text( col1, $
                 xsize=30, ysize=4,/scroll,/wrap, $
                 value='Click on noise floor')
tweak_par.wiener_accept_label = $
    widget_button(col1, value='Apply filter')
tweak_par.wiener_ignore_label = $
    widget_button(col1, value='Ignore filter')

tweak_par.wiener_plot_label = $
    widget_draw(col2, xsize=400, ysize=300,retain=2,/button_events)

widget_control, tweak_par.wiener_base, /realize
widget_control, tweak_par.wiener_accept_label, sensitive=0
widget_control, tweak_par.wiener_ignore_label, sensitive=0

widget_control,tweak_par.wiener_plot_label,get_value=window
tweak_par.wiener_plot_win = window
wset,tweak_par.wiener_plot_win
tvlct,r,g,b

widget_control, hourglass=1
print,'Calculating power spectrum'

all_psd,fft_image,freq,psd,freq_indices,$
  /fft_already,/plot,color=top_plot_index
; Chop out the zero frequency
n_freq = n_elements(freq)
freq = freq(1:(n_freq-1))
psd = psd(1:(n_freq-1))
widget_control, hourglass=0

tweak_par.wiener_step = 1

widget_control, tweak_par.wiener_base,show=1,map=1
xmanager, 'tweak_wiener', tweak_par.wiener_base, $
    group_leader = tweak_par.main_base

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; We only get to this routine if we know the zone plate
;; parameters, and if the signal and noise spectra are known

PRO tweak_deconvolve_calc

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm
    
n_per_airy = 16
n_airy = 8
mtf_threshold = 1.e-3

nu = (1.22*!pi/float(n_per_airy))*findgen(n_per_airy*n_airy)

stop_fraction = zp_d_stop_um/float(zp_d_outer_um)

nu_zero=where(nu eq 0.,nu_zero_count)
nu_nonzero=where(nu ne 0.)
airy_intensity=nu
stop_factor = 1. - stop_fraction*stop_fraction
inverse_stop_factor = 1./stop_factor

if (nu_zero_count ne 0) then begin
    airy_intensity(nu_zero)=stop_factor*stop_factor
endif
airy_intensity(nu_nonzero)= $
  (2.0*beselj(nu(nu_nonzero),1) - $
   stop_fraction*2.0*beselj(stop_fraction*nu(nu_nonzero),1) ) $
  / nu(nu_nonzero)
airy_intensity(nu_nonzero)=$
  airy_intensity(nu_nonzero)*airy_intensity(nu_nonzero)

r_um = 1.e-3*zp_drn_nm*nu/!Pi
dr_um = r_um(1)-r_um(0)

theoretical_mtf = fltarr(n_airy*n_per_airy, /nozero)
freqmax = 1/(1.e-3*zp_drn_nm)
freq_inv_um = freqmax*findgen(n_per_airy*n_airy)/float(n_airy*n_per_airy)

;; CJJ changed to (r_um+0.5*dr_um) in the integrand, and changed
;; "frequencie" to "freq_inv_um"

FOR i=0,(n_airy*n_per_airy-1)  DO BEGIN
    integrand = (r_um+0.5*dr_um) * airy_intensity * $
      beselj(2.*!Pi*(r_um+0.5*dr_um)*freq_inv_um(i),0)*dr_um
    theoretical_mtf(i) = total(integrand)
ENDFOR
;; CJJ The next line sets the MTF to be no smaller than mtf_threshold
theoretical_mtf = (theoretical_mtf/max(theoretical_mtf))>mtf_threshold

;; Now we need to map this onto the power spectrum frequencies "freq"
remapped_mtf = interpol(theoretical_mtf,freq_inv_um,freq)

;; And now the deconvolution filter is 1/MTF times the wiener_filter
deconvolve_filter = wiener_filter/remapped_mtf

wset,tweak_par.deconvolve_plot_win
plot,freq,deconvolve_filter,xtitle='Freq. (inv. um)',$
  ytitle='Deconvolution filter'

fft_image = fft_image*deconvolve_filter(freq_indices)
tweak_powdisp

widget_control,tweak_par.deconvolve_accept_label,sensitive=1
widget_control,tweak_par.deconvolve_ignore_label,sensitive=1
widget_control,tweak_par.deconvolve_calc_label,sensitive=0

return
END


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_deconvolve_event,event

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

CASE event.id OF

   tweak_par.zp_d_outer_um_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.zp_d_outer_um_label,$
          get_value = temp_string
        on_ioerror, zp_d_outer_um_label_oops
        reads,temp_string(0),zp_d_outer_um
         zp_d_outer_um_label_oops:
        widget_control, tweak_par.zp_d_outer_um_label, $
          set_value = strtrim(string(zp_d_outer_um,format='(f10.2)'),2)
        tweak_par.zp_d_outer_gotit = 1
        widget_control, tweak_par.zp_d_stop_um_label,  sensitive=1

        IF ((tweak_par.zp_d_outer_gotit NE 0) AND $
            (tweak_par.zp_d_stop_gotit NE 0) AND $
            (tweak_par.zp_drn_gotit NE 0) AND $
            (tweak_par.deconvolve_step GE 4)) THEN BEGIN
            widget_control, tweak_par.deconvolve_calc_label, sensitive = 1
        ENDIF
    END
   

   tweak_par.zp_d_stop_um_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.zp_d_stop_um_label,$
          get_value = temp_string
        on_ioerror, zp_d_stop_um_label_oops
        reads,temp_string(0),zp_d_stop_um
         zp_d_stop_um_label_oops:
        widget_control, tweak_par.zp_d_stop_um_label, $
          set_value = strtrim(string(zp_d_stop_um,format='(f10.2)'),2)
        tweak_par.zp_d_stop_gotit = 1
        widget_control, tweak_par.zp_drn_nm_label,  sensitive=1

        IF ((tweak_par.zp_d_outer_gotit NE 0) AND $
            (tweak_par.zp_d_stop_gotit NE 0) AND $
            (tweak_par.zp_drn_gotit NE 0) AND $
            (tweak_par.deconvolve_step GE 4)) THEN BEGIN
            widget_control, tweak_par.deconvolve_calc_label, sensitive = 1
        ENDIF
    END

   tweak_par.zp_drn_nm_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.zp_drn_nm_label,$
          get_value = temp_string
        on_ioerror, zp_drn_nm_label_oops
        reads,temp_string(0),zp_drn_nm
         zp_drn_nm_label_oops:
        widget_control, tweak_par.zp_drn_nm_label, $
          set_value = strtrim(string(zp_drn_nm,format='(f10.2)'),2)
        tweak_par.zp_drn_gotit = 1

        IF ((tweak_par.zp_d_outer_gotit NE 0) AND $
            (tweak_par.zp_d_stop_gotit NE 0) AND $
            (tweak_par.zp_drn_gotit NE 0) AND $
            (tweak_par.deconvolve_step GE 4)) THEN BEGIN
            widget_control, tweak_par.deconvolve_calc_label, sensitive = 1
        ENDIF
    END

    tweak_par.deconvolve_calc_label: BEGIN
        ;; This label becomes sensitive only when all the relevant
        ;; information is known: zone plate parameters, noise spectrum
        widget_control, hourglass=1
        tweak_deconvolve_calc
        widget_control, hourglass=0
    END

    tweak_par.deconvolve_accept_label: BEGIN
        widget_control, hourglass=1
        print,'Transforming back to image space'
        tweaked_image = float(shift(fft(shift(fft_image,$
                                              n_cols/2,n_rows/2),$
                                        1),n_cols/2,n_rows/2))
        tweak_imgdisp
        tweak_sensitive, /main
        widget_control, tweak_par.deconvolve_base,/destroy
        widget_control, tweak_par.main_base,show=1
        widget_control, hourglass=0
    END

    tweak_par.deconvolve_ignore_label: BEGIN
        widget_control, hourglass=1
        tweak_imgdisp
        tweak_sensitive, /main
        widget_control, tweak_par.deconvolve_base,/destroy
        widget_control, tweak_par.main_base,show=1
        widget_control, hourglass=0
    END

    tweak_par.deconvolve_plot_label: BEGIN
        CASE tweak_par.deconvolve_step OF
            1: BEGIN
                ; In this case, the user was asked to click on
                ; the noise floor.
                IF (event.press NE 0) THEN BEGIN
                    wset,tweak_par.deconvolve_plot_win
                    coords = convert_coord( event.x, event.y,/device,/to_data)
                    noise_floor = coords(1)
                    oplot,10.^(!x.crange),[0.,0.]+noise_floor,$
                        color=roi_plot_index
                    widget_control, tweak_par.deconvolve_text_label, $
                        set_value = 'Now click on 1st of 2 points on the '+$
                                    'signal curve.'
                    tweak_par.deconvolve_step = 2
                ENDIF
            END

            2: BEGIN
                ; Now the user was asked to click on
                ; one point on the signal curve
                IF (event.press NE 0) THEN BEGIN
                    wset,tweak_par.deconvolve_plot_win
                    coords = convert_coord( event.x, event.y,/device,/to_data)
                    sig1_xy = coords
                    widget_control, tweak_par.deconvolve_text_label, $
                        set_value = 'Click on the 2nd point on the '+$
                                    'signal curve.'
                    tweak_par.deconvolve_step = 3
                ENDIF
            END

            3: BEGIN
                ; Now the user was asked to click on
                ; a second point on the signal curve
                IF (event.press NE 0) THEN BEGIN
                    coords = convert_coord( event.x, event.y,/device,/to_data)
                    sig2_xy = coords
                    tweak_par.deconvolve_step = 4

                    ; Now we do the calculation.
                    widget_control, hourglass=1
                    sig_slope = float(alog10(sig1_xy(1))-alog10(sig2_xy(1))) / $
                        float(alog10(sig1_xy(0))-alog10(sig2_xy(0)))
                    sig_yintercept = alog10(sig1_xy(1)) - $
                        alog10(sig1_xy(0))*sig_slope
                    crossing_freq = $
                        10.^((alog10(noise_floor)-sig_yintercept) / sig_slope)
                    info_string = 'Signal curve declines as frequency '+$
                        'to the power '+$
                        strtrim(string(sig_slope,format='(f10.2)'),2)+$
                        ', with a crossing point at '+$
                        strtrim(string(crossing_freq,format='(f10.1)'),2)+$
                        ' inverse microns, or a half-period of '+$
                        strtrim(string(1./(2.*crossing_freq),$
                          format='(f12.3)'),2)+$
                        ' microns.  Accept or ignore the filter.'
                    widget_control, tweak_par.deconvolve_text_label, $
                        set_value = info_string

                    xpoints = 10.^(!x.crange)
                    ypoints = 10.^(sig_slope*!x.crange+sig_yintercept)
                    oplot,xpoints,ypoints,color=roi_plot_index
                    wait,.001
                    signal_curve = 10.^(sig_slope*alog10(freq)+sig_yintercept)
                    wiener_filter = signal_curve/(signal_curve+noise_floor)

                    IF ((tweak_par.zp_d_outer_gotit NE 0) AND $
                        (tweak_par.zp_d_stop_gotit NE 0) AND $
                        (tweak_par.zp_drn_gotit NE 0)) THEN BEGIN
                        widget_control, tweak_par.deconvolve_calc_label, $
                            sensitive = 1
                    ENDIF
                ENDIF
            END
            ELSE: ; nothing
        ENDCASE
    END

ENDCASE
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_deconvolve

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

tweak_par.deconvolve_base = $
    widget_base(title='Tweak: Deconvolution with Wiener filter',/row)
col1 = widget_base(tweak_par.deconvolve_base,/col)
col2 = widget_base(tweak_par.deconvolve_base,/col)

tweak_par.deconvolve_text_label = $
    widget_text( col1, $
                 xsize=30, ysize=4,/scroll,/wrap, $
                 value='Click on noise floor')

row = widget_base(col1,/row)
label = widget_label(row,value='Zone plate outer diameter (um):') 
tweak_par.zp_d_outer_um_label = $
  widget_text(row,/frame,/editable,xsize=10)
 
row = widget_base(col1,/row)
label = widget_label(row,value='Zone plate central stop diameter (um): ')
tweak_par.zp_d_stop_um_label = $
  widget_text(row,/frame,/editable,xsize=10)
       
row = widget_base(col1,/row)
label = widget_label(row,value='Zone plate outermost zone width (nm): ')
tweak_par.zp_drn_nm_label = $
  widget_text(row,/frame,/editable,xsize=10)

tweak_par.zp_d_outer_gotit = 0
tweak_par.zp_d_stop_gotit = 0
tweak_par.zp_drn_gotit = 0

tweak_par.deconvolve_calc_label = $
    widget_button(col1, value='Calculate filter')
tweak_par.deconvolve_accept_label = $
    widget_button(col1, value='Apply filter')
tweak_par.deconvolve_ignore_label = $
    widget_button(col1, value='Ignore filter')

tweak_par.deconvolve_plot_label = $
    widget_draw(col2, xsize=400, ysize=300,retain=2,/button_events)

widget_control, tweak_par.deconvolve_base, /realize
widget_control, tweak_par.deconvolve_calc_label, sensitive=0
widget_control, tweak_par.deconvolve_accept_label, sensitive=0
widget_control, tweak_par.deconvolve_ignore_label, sensitive=0

widget_control,tweak_par.deconvolve_plot_label,get_value=window
tweak_par.deconvolve_plot_win = window
wset,tweak_par.deconvolve_plot_win
tvlct,r,g,b

widget_control, hourglass=1
print,'Calculating power spectrum'

all_psd,fft_image,freq,psd,freq_indices,$
  /fft_already,/plot,color=top_plot_index
; Chop out the zero frequency
n_freq = n_elements(freq)
freq = freq(1:(n_freq-1))
psd = psd(1:(n_freq-1))
widget_control, hourglass=0

tweak_par.deconvolve_step = 1

widget_control, tweak_par.deconvolve_base,show=1,map=1
xmanager, 'tweak_deconvolve', tweak_par.deconvolve_base, $
    group_leader = tweak_par.main_base

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak_event, event

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

CASE event.id OF
    tweak_par.disp_min_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.disp_min_label,$
          get_value = temp_string
        on_ioerror, disp_min_label_oops
        reads,temp_string(0),disp_min
        disp_min_label_oops:
        widget_control, tweak_par.disp_min_label, $
          set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        widget_control, hourglass = 1
        tweak_imgdisp
        widget_control, hourglass = 0
    END

    tweak_par.disp_max_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.disp_max_label,$
          get_value = temp_string
        on_ioerror, disp_max_label_oops
        reads,temp_string(0),disp_max
        disp_max_label_oops:
        widget_control, tweak_par.disp_max_label, $
          set_value = strtrim(string(disp_max,format='(f10.2)'),2)
        widget_control, hourglass = 1
        tweak_imgdisp
        widget_control, hourglass = 0
    END

    tweak_par.disp_gamma_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.disp_gamma_label,$
          get_value = temp_string
        on_ioerror, disp_gamma_label_oops
        reads,temp_string(0),disp_gamma
        disp_gamma_label_oops:
        widget_control, tweak_par.disp_gamma_label, $
          set_value = strtrim(string(disp_gamma,format='(f10.2)'),2)
        widget_control, hourglass = 1
        tweak_imgdisp
        widget_control, hourglass = 0
    END

    tweak_par.disp_auto_label: BEGIN
        disp_min = min(tweaked_image,max=disp_max)
        widget_control, tweak_par.disp_min_label, $
          set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        widget_control, tweak_par.disp_max_label, $
          set_value = strtrim(string(disp_max,format='(f10.2)'),2)
        widget_control, hourglass = 1
        tweak_imgdisp
        widget_control, hourglass = 0
    END

    tweak_par.flatten_label: BEGIN
        widget_control, hourglass = 1
        flatten_roi = 0
        fourfilt_roi = 0
        tweak_par.type_of_tweak = 1
        tweak_imgdisp
        tweak_sensitive, /flatten
        widget_control, hourglass = 0
    END

    tweak_par.flatten_add_roi_label: BEGIN
        tweak_roi
    END

    tweak_par.flatten_reset_roi_label: BEGIN
        flatten_roi = 0
        widget_control, hourglass = 1
        tweak_imgdisp
        widget_control, hourglass = 0
    END

    tweak_par.flatten_order_label: BEGIN
        flatten_order = flatten_order_list(event.index)
    END

    tweak_par.flatten_doit_label: BEGIN
        widget_control, hourglass = 1
        print,'Flattening image by fitting background to a plane.'
        tweak_flatten
        flatten_roi = 0
        tweak_imgdisp
        tweak_sensitive, /main
        widget_control, hourglass = 0
    END

    tweak_par.fourfilt_label: BEGIN
        widget_control, hourglass = 1
        print,'Transforming image to frequency space.'
        fft_image = shift(fft(shift(tweaked_image,n_cols/2,n_rows/2),$
                              -1),n_cols/2,n_rows/2)
        flatten_roi = 0
        fourfilt_roi = 0
        tweak_par.type_of_tweak = 2
        tweak_powdisp
        tweak_sensitive, /fourfilt
        widget_control, hourglass = 0
    END

    tweak_par.fourfilt_add_roi_label: BEGIN
        tweak_roi
    END

    tweak_par.fourfilt_reset_roi_label: BEGIN
        fourfilt_roi = 0
        widget_control, hourglass = 1
        tweak_powdisp
        widget_control, hourglass = 0
    END

    tweak_par.fourfilt_doit_label: BEGIN
        widget_control, hourglass = 1
        print,'Zeroing selected frequencies, and transforming to real space.'
        fft_image(fourfilt_roi) = 0.
        tweaked_image = float(shift(fft(shift(fft_image,n_cols/2,n_rows/2),$
                                        1),n_cols/2,n_rows/2))
        tweak_imgdisp
        fourfilt_roi = 0
        tweak_sensitive, /main
        widget_control, hourglass = 0
    END

    tweak_par.wienerfilt_label: BEGIN
        widget_control, hourglass = 1
        print,'Transforming to frequency space'
        fft_image = shift(fft(shift(tweaked_image,n_cols/2,n_rows/2),$
                              -1),n_cols/2,n_rows/2)
        tweak_powdisp
        tweak_sensitive, /none
        widget_control, hourglass = 0
        tweak_wiener
    END

    tweak_par.deconvolve_label: BEGIN
        widget_control, hourglass = 1
        print,'Transforming to frequency space'
        fft_image = shift(fft(shift(tweaked_image,n_cols/2,n_rows/2),$
                              -1),n_cols/2,n_rows/2)
        tweak_powdisp
        tweak_sensitive, / none
        widget_control, hourglass = 0
        tweak_deconvolve
    END

    tweak_par.crop_label: BEGIN
        tweak_sensitive,/none
        getbox,xv,yv,/device

        widget_control, hourglass=1
        x1 = fix(min(xv))/img_zoom
        x2 = fix(max(xv))/img_zoom
        y1 = fix(min(yv)-textregion_ypix)/img_zoom
        y2 = fix(max(yv)-textregion_ypix)/img_zoom
        tweaked_image = tweaked_image(x1:x2,y1:y2)
        x_start = original_start_stop(0)+(float(x1)/float(n_cols)) * $
            float(original_start_stop(2)-original_start_stop(0))
        x_stop = original_start_stop(0)+(float(x2)/float(n_cols)) * $
            float(original_start_stop(2)-original_start_stop(0))
        y_start = original_start_stop(1)+(float(y1)/float(n_rows)) * $
            float(original_start_stop(3)-original_start_stop(1))
        y_stop = original_start_stop(1)+(float(y2)/float(n_rows)) * $
            float(original_start_stop(3)-original_start_stop(1))
        n_cols = n_elements(tweaked_image(*,0))
        n_rows = n_elements(tweaked_image(0,*))
        tweak_imgdisp
        tweak_sensitive,/main
        widget_control, hourglass = 0
    END

   tweak_par.header_label: BEGIN
        temp_string = ''
        widget_control, tweak_par.header_label,$
            get_value = temp_string
        on_ioerror, header_label_oops
        filename_header = strtrim(temp_string(0),2)
        dotpos = strpos(filename_header,'.')
        IF (dotpos NE (-1)) THEN BEGIN
            filename_header = strmid(filename_header,0,dotpos)
        ENDIF
        header_label_oops:
        IF (strlen(filename_header) NE 0) THEN BEGIN
            widget_control, tweak_par.save_gif_label, $
                sensitive = 1
            widget_control, tweak_par.save_eps_label, $
                sensitive = 1
            widget_control, tweak_par.save_ncdf_label, $
                sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, tweak_par.save_gif_label, $
                sensitive = 0
            widget_control, tweak_par.save_eps_label, $
                sensitive = 0
            widget_control, tweak_par.save_ncdf_label, $
                sensitive = 0
        ENDELSE
        widget_control, tweak_par.header_label, $
          set_value = filename_header
    END

    tweak_par.save_gif_label: BEGIN
        widget_control, hourglass=1
        wset,tweak_par.image_win
        byte_image = tvrd(0,0,n_cols*img_zoom,(n_rows*img_zoom+textregion_ypix))
        write_gif,filename_header+'.gif',byte_image,r,g,b
        print,'Wrote file "'+filename_header+'.gif"'
        widget_control,hourglass=0
    END

    tweak_par.save_eps_label: BEGIN
        widget_control, hourglass=1

        xdpi = n_cols/5.
        ydpi = n_rows/5.
        dpi = max([xdpi,ydpi])
        dpi = 10.*fix(0.5+dpi/10.)
        ximinch = n_cols/float(dpi)
        yiminch = n_rows/float(dpi)

        ycharinch = 0.12
        xinches = ximinch
        yinches = yiminch + 1.5*ycharinch

        old_plot = !d.name
        old_font = !p.font
        set_plot,'ps'
        device,file=filename_header+'.eps',xsize=xinches,ysize=yinches,/encap,bits=8
        !p.font = 0
        byte_image = byte(0.5+255.*(( $
                          (((tweaked_image-disp_min) / $
                          float(disp_max-disp_min))^disp_gamma) $
                          >0.)<1.))<255
        tv,byte_image,0.,(1.5*ycharinch),/inch,xsize=ximinches,ysize=yiminches
        bar_inches = ximinch*(bar_microns/float(abs(x_stop-x_start)))
        tv,bytarr(1,1),(ycharinch)/xinches,$
            (0.35*ycharinch)/yinches,/norm,$
            xsize=bar_inches/xinches,ysize=(0.8*ycharinch)/yinches
        xyouts,(3.*ycharinch+bar_inches)/xinches,$
               (0.25*ycharinch)/yinches,/norm,bar_psstring

        device,/close
        print,'Wrote file "'+filename_header+'.eps"'

        set_plot, old_plot
        !p.font = old_font
        wset,tweak_par.image_win
        widget_control,hourglass=0
    END

    tweak_par.save_ncdf_label: BEGIN
        widget_control,hourglass=1
        image_data = tweaked_image
        write_ncdf,filename_header+'.nc'
        print,'Wrote file "'+filename_header+'.nc"'
        widget_control,hourglass=0
    END

    tweak_par.revert_label: BEGIN
        widget_control, hourglass = 1
        print,'Reverting to original image.'
        tweaked_image = original_image
        x_start = original_start_stop(0)
        x_stop = original_start_stop(2)
        y_start = original_start_stop(1)
        y_stop = original_start_stop(3)
        n_cols = n_elements(original_image(*,0))
        n_rows = n_elements(original_image(0,*))
        flatten_roi = 0
        fourfilt_roi = 0
        tweak_imgdisp
        widget_control, hourglass = 0
    END

    tweak_par.exit_label: BEGIN
        widget_control,tweak_par.main_base,/destroy
    END

    tweak_par.image_label: BEGIN
    END

ENDCASE

END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO tweak, image, zoom=zoom, help=help

@bsif_common
COMMON tweak_common, $
    tweak_par, tweaked_image, fft_image, $
    original_image, original_start_stop, $
    img_zoom, this_roi, flatten_roi, fourfilt_roi, $
    r, g, b, old_r, old_g, old_b, $
    roi_color_index, top_color_index, roi_plot_index, top_plot_index, $
    flatten_order_list, flatten_order_text_list, flatten_order, $
    disp_min, disp_max, disp_gamma, filename_header, $
    textregion_ypix, char_ypix, charsize, $
    bar, bar_microns, bar_pixels, bar_string, bar_psstring, $
    freq,psd,freq_indices,noise_floor,wiener_filter,deconvolve_filter,$
    sig_slope,sig_yintercept,sig1_xy,sig2_xy,$
    zp_d_outer_um,zp_d_stop_um, zp_drn_nm

@sxm_common

IF (keyword_set(help) OR (n_elements(image) EQ 0)) THEN BEGIN
    print,'tweak, image, byte_image, [zoom=]'
    return
ENDIF

img_zoom = 1
flatten_order = 1
IF (n_elements(zoom) NE 0) THEN img_zoom = zoom
img_zoom = img_zoom>1

flatten_roi = 0
fourfilt_roi = 0
filename_header =''

svec = size(image)
IF (svec(0) EQ 1) THEN BEGIN
    print, 'Image must be 2D, not 1D.  Nothing done...'
    return
ENDIF ELSE IF (svec(0) GE 3) THEN BEGIN
    print, 'Image must be 2D, not >= 3D.  Nothing done...'
    return
ENDIF

char_ypix = 16
window,0,xsize=50,ysize=50
wset,0
xyouts,5,30,/device,'Please!Cwait...',font=0
charsize=char_ypix/float(!d.y_ch_size)
textregion_ypix=fix(1.5*char_ypix)
wdelete,0

n_cols = long(n_elements(image(*, 0)))
n_rows = long(n_elements(image(0, *)))
original_image = image
original_start_stop = [x_start,y_start,x_stop,y_stop]
tweaked_image = original_image

got_displimits = 0
IF (n_tags(sxm_par) NE 0) THEN BEGIN
    IF ((sxm_par.disp_min NE 0.) AND (sxm_par.disp_max NE 0.) AND $
        (sxm_par.disp_gamma NE 0.)) THEN BEGIN
        disp_min = sxm_par.disp_min
        disp_max = sxm_par.disp_max
        disp_gamma = sxm_par.disp_gamma
        got_displimits = 1
    ENDIF
ENDIF

IF (got_displimits NE 1) THEN BEGIN
    disp_min = min(original_image, max=disp_max)
    disp_gamma = 1.
ENDIF

tweak_par = 0
tweak_par = $
    { tweak_par, $
      main_base: 0L, $
      disp_min_label: 0L, $
      disp_max_label: 0L, $
      disp_gamma_label: 0L, $
      disp_auto_label: 0L, $
      flatten_label: 0L, $
      flatten_add_roi_label: 0L, $
      flatten_reset_roi_label: 0L, $
      flatten_order_label: 0L, $
      flatten_doit_label: 0L, $
      fourfilt_label: 0L, $
      fourfilt_add_roi_label: 0L, $
      fourfilt_reset_roi_label: 0L, $
      fourfilt_doit_label: 0L, $
      wienerfilt_label: 0L, $
      wiener_base: 0L, $
      wiener_text_label: 0L, $
      wiener_accept_label: 0L, $
      wiener_ignore_label: 0L, $
      wiener_plot_label: 0L, $
      wiener_plot_win: 0L, $
      wiener_step: 0L, $
      deconvolve_label: 0L, $
      deconvolve_base: 0L, $
      deconvolve_text_label: 0L, $
      deconvolve_calc_label: 0L, $
      deconvolve_accept_label: 0L, $
      deconvolve_ignore_label: 0L, $
      deconvolve_plot_label: 0L, $
      deconvolve_plot_win: 0L, $
      deconvolve_step: 0L, $
      zp_d_outer_um_label: 0L, $
      zp_d_stop_um_label: 0L, $
      zp_drn_nm_label: 0L, $
      zp_d_outer_gotit: 0L, $
      zp_d_stop_gotit: 0L, $
      zp_drn_gotit: 0L, $
      crop_label: 0L, $
      header_label: 0L, $
      save_gif_label: 0L, $
      save_eps_label: 0L, $
      save_ncdf_label: 0L, $
      revert_label: 0L, $
      exit_label: 0L, $
      type_of_tweak: 0L, $      ; 1 for fit background, 2 for fourier filter
      roi_base: 0L, $
      roi_accept_label: 0L, $
      roi_reject_label: 0L, $
      image_label: 0L, $
      image_win: 0L $
    }

tweak_par.main_base = $
    widget_base(title='Tweak', /row )
col1 = widget_base(tweak_par.main_base,/col)
col2 = widget_base(tweak_par.main_base,/col)

base = widget_base(col1,/column,/frame)
row = widget_base(base,/row)
label = widget_label(row,value='Display min, max: ')   
tweak_par.disp_min_label = $
  widget_text(row,/frame,/editable,xsize=10)
tweak_par.disp_max_label = $
  widget_text(row,/frame,/editable,xsize=10)
row = widget_base(base,/row)
label = widget_label(row,value='Display gamma: ')
tweak_par.disp_gamma_label = $
  widget_text(row,/frame,/editable,xsize=10)
tweak_par.disp_auto_label = $
  widget_button(row,value='Full range')

base = widget_base(col1,/col,/frame)
row = widget_base(base, /row)
tweak_par.flatten_label = $
    widget_button(row, value='Flatten background')
tweak_par.flatten_doit_label = $
    widget_button(row,value='Do it!')
row = widget_base(base,/row)
tweak_par.flatten_add_roi_label = $
    widget_button(row,value='Add (another) region')
tweak_par.flatten_reset_roi_label = $
    widget_button(row,value='Reset regions')
row = widget_base(base,/row)
label = widget_label(row,value='Fit order: ')
flatten_order_list = [1]
flatten_order_textlist = ['1 (linear)']
tweak_par.flatten_order_label = $
    widget_list(row,ysize=1,value=flatten_order_textlist)

base = widget_base(col1,/col,/frame)
row = widget_base(base,/row)
tweak_par.fourfilt_label = $
    widget_button(row,value='Fourier filter')
tweak_par.fourfilt_doit_label = $
    widget_button(row,value='Do it!')
row = widget_base(base,/row)
tweak_par.fourfilt_add_roi_label = $
    widget_button(row,value='Zero (another) region')
tweak_par.fourfilt_reset_roi_label = $
    widget_button(row,value='Reset regions')

base = widget_base(col1,/column,/frame)
tweak_par.wienerfilt_label = $
    widget_button(base,value='Wiener filter')
tweak_par.deconvolve_label = $
    widget_button(base,value='Deconvolution w/Wiener')

tweak_par.crop_label = $
    widget_button(col1,value='Crop image')

base = widget_base(col1,/col,/frame)
row = widget_base(base,/row)
label = widget_label(row, value='File header: ')
tweak_par.header_label = $
    widget_text(row,/editable,/frame,xsize=20)
row = widget_base(base,/row)
label = widget_label(row, value='Save: ')
tweak_par.save_gif_label = $
    widget_button(row,value='".gif"')
tweak_par.save_eps_label = $
    widget_button(row,value='".eps"')
tweak_par.save_ncdf_label = $
    widget_button(row,value='NetCDF ".nc"')

base = widget_base(col1,/col,/frame)
row = widget_base(base,/row)
tweak_par.revert_label = $
    widget_button(row,value='Undo all changes')
tweak_par.exit_label = $
    widget_button(row,value='Exit')

tweak_par.image_label = $
  widget_draw(col2,$
              xsize=n_cols*img_zoom,$
              ysize=n_rows*img_zoom+textregion_ypix,$
              retain=2,/button_events)

widget_control, tweak_par.main_base, /realize

widget_control, tweak_par.disp_min_label, $
    set_value = strtrim(string(disp_min,format='(f10.2)'),2)
widget_control, tweak_par.disp_max_label, $
    set_value = strtrim(string(disp_max,format='(f10.2)'),2)
widget_control, tweak_par.disp_gamma_label, $
    set_value = strtrim(string(disp_gamma,format='(f10.2)'),2)

widget_control,tweak_par.flatten_order_label, set_list_select=0
widget_control,tweak_par.image_label,get_value=window
tweak_par.image_win = window

tvlct,old_r,old_g,old_b,/get
roi_color_index = !d.table_size-1
top_color_index = !d.table_size-2
r = byte(0.5+255.*findgen(top_color_index+1) / $
         float(top_color_index))
g = [r,byte(0)]
b = [r,byte(0)]
r = [r,byte(255)]
wset,tweak_par.image_win
tvlct,r,g,b

IF (long(!d.n_colors) EQ 255L) THEN BEGIN
    roi_plot_index = roi_color_index
    top_plot_index = top_color_index
ENDIF ELSE IF (long(!d.n_colors) EQ 16777216L) THEN BEGIN
    ; For 24 bit color, use (r+256L*(g+256L*b))
    roi_plot_index = 255L
    top_plot_index = 255L+256L*(255L+256L*255L)
ENDIF ELSE BEGIN
    print,'Unknown display depth'
    roi_plot_index = roi_color_index
    top_plot_index = top_color_index
ENDELSE

widget_control, hourglass = 1
tweak_imgdisp
widget_control, hourglass = 0

tweak_sensitive, /main

xmanager, 'tweak', tweak_par.main_base, $
  group_leader = tweak_par.main_base

tvlct,old_r,old_g,old_b
image = tweaked_image

return
END

