; Copyright (c) 1998-20109 A.P. Hitchcock  All rights reserved
;+
;NAME:
;  STACK_ALIGN
;
;LAST CHANGED: ----------------------------------- 11 Jan 10
;
; PURPOSE:
;	This procedure aligns images of a stack
;
; CATEGORY:
;	stack processing - part of axis2000 stack analyze package
;
; CALLING SEQUENCE:
;	STACK_ALIGN, filename_ev_msec_list,shift_filename,zoom=zoom,realign=realign
;
; INPUTS:
; 	filename_ev_msec_list 	array with details of filenames, energies, dwells
;	shift_filename			name of file written with (x,y) pixel shifts (mapper format)
;	zoom					display multiplier (integer only)
;	realign					if 1, do alignment; if 0, read from file
;
; KEYWORDS: none
;
; OUTPUTS: 	*.aln file with list of (x,y) pixel shifts to align images
;
; COMMON BLOCKS:
; BSIF_com
; volume_data, image_stack
; pix_shift
; stack_process_align_common
;
; SIDE EFFECTS:
;	A window is created/destroyed.
;
; RESTRICTIONS: none
;
; MODIFICATION HISTORY:
; (25-mar-98 cjj) to deal with 24 bit graphics
; (11-Jul-98 aph) to deal with changes to align.pro
; (12-dec-98 aph) remove all bsif_common
; (08-may-00 aph) add xpix_shift, ypix_shift to transfer size of grey area
; (17-Sep-08 aph) replace analcom with stack_process_com  (there were no occurrences)
;                 standard header added
; (07-mar-09 aph) replace read_mapper with zstack_read_mapper to get around problem with zimba align files (line 423)
; (11-Jan-10 aph) replace @aligncom with @stack_process_align_com to get around conflict with CJJ's stack_analyze
;-

; stack_align.pro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;PRO stack_align_complete_event,event
;
;@bsif_com            !******!! (watch for 8-char limit on names !!)
;COMMON volume_data, image_stack
;
;CASE event.id OF
;    stack_align_par.acknowledge_label: BEGIN
;        widget_control, stack_align_par.main_base, /destroy
;    END
;
;ENDCASE
;
;return
;END

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

PRO stack_align_doalign

@bsif_com
@stack_process_align_com
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

widget_control, stack_align_par.sobel_edge_label, sensitive = 0
widget_control, stack_align_par.roberts_edge_label, sensitive = 0
widget_control, stack_align_par.no_edge_label, sensitive = 0
widget_control, stack_align_par.precede_match_label, sensitive = 0
widget_control, stack_align_par.constant_match_label, sensitive = 0
widget_control, stack_align_par.alignto_list_label, sensitive = 0
widget_control, stack_align_par.xcor_peak_label, sensitive = 0
widget_control, stack_align_par.xcor_cm_label, sensitive = 0
widget_control, stack_align_par.xcor_maxshift_label, sensitive = 0
widget_control, stack_align_par.doit_label, sensitive = 0
widget_control, stack_align_par.skipit_label, sensitive = 0

n_files = n_elements(image_stack(0,0,*))

sobel = 0
roberts = 0
IF (stack_align_par.do_edge EQ 1) THEN sobel = 1
IF (stack_align_par.do_edge EQ 2) THEN roberts = 1

x_shift = fltarr(n_files)
y_shift = fltarr(n_files)

wset,stack_align_par.plot_win
plot_min = -10.
plot_max = +10.
plot,x_shift,/nodata,yrange=[plot_min,plot_max],$
    xtitle='File #', ytitle='Shift (pixels)',$
    color=white_plot_index
xyouts,3,6,/data,color=x_shift_plot_index,'X'
xyouts,3,-6,/data,color=y_shift_plot_index,'Y'

start_time = systime(1.)
ref_image = image_stack(*,*,0)
;; ref_dc = total(ref_image)/float(n_cols*n_rows)
;; ref_image = ref_image - ref_dc
;; edgegauss, ref_image, 4.
;; ref_image = ref_image + ref_dc

peak = 0
cm = 0

widget_control,hourglass=1

FOR i_file = 0,(n_files-1) DO BEGIN
    IF (stack_align_par.constant_match NE 0) THEN BEGIN
        ;; nothing
    ENDIF ELSE IF (i_file GT 0) THEN BEGIN
        ref_image = image_stack(*,*,i_file-1)
        ;; ref_dc = total(ref_image)/float(n_cols*n_rows)
        ;; ref_image = ref_image - ref_dc
        ;; edgegauss, ref_image, 4.
        ;; ref_image = ref_image + ref_dc
    ENDIF

    this_image = image_stack(*,*,i_file)
    ;; this_dc = total(this_image)/float(n_cols*n_rows)
    ;; this_image = this_image - this_dc
    ;; edgegauss, this_image, 4.
    ;; this_image = this_image + this_dc

    CASE stack_align_par.match_type OF
        0: BEGIN
            peak = 1
            widget_control, stack_align_par.diff_text_label, $
                set_value = 'Cross-correlation image'
            align,ref_image,this_image,this_x_shift,this_y_shift,$
              shifted_image, sobel = sobel, roberts=roberts, $
              maxshift=maxshift, /meanfill, $
              xcorimg_win = stack_align_par.diff_image_win, $
              xcorimg_zoom = img_zoom
        END

        1: BEGIN
            cm = 1
            widget_control, stack_align_par.diff_text_label, $
                set_value = 'Cross-correlation image'
            align,ref_image,this_image,this_x_shift,this_y_shift,$
              shifted_image, sobel = sobel, roberts=roberts, $
              maxshift=maxshift, /meanfill, /cm, $
              xcorimg_win = stack_align_par.diff_image_win, $
              xcorimg_zoom = img_zoom
        END
    ENDCASE
    x_shift(i_file) = this_x_shift
    y_shift(i_file) = this_y_shift

    ;; Now shift the image without edge smoothing
    ;; IF ((abs(this_x_shift) GT 0.2) OR (abs(this_y_shift) GT 0.2)) THEN BEGIN
    ;;     this_image = image_stack(*,*,i_file)
    ;;     p = [this_x_shift,0.,1.,0.]
    ;;     q = [this_y_shift,1.,0.,0.]
    ;;     missing = total(this_image)/float(n_cols*n_rows)
    ;;     shifted_image = poly_2d(this_image,p,q,1,missing=missing)
    ;;     image_stack(*,*,i_file) = shifted_image
    ;; ENDIF

    widget_control, stack_align_par.this_imagetitle_label, $
      set_value = $
      filename_info_list(stack_align_par.constant_image_index)
    widget_control, stack_align_par.this_imagecount_label,$
      set_value=' ('+strtrim(string(i_file+1),2)+' of '+$
      strtrim(string(n_files),2)+'; shift was ['+$
      strtrim(string(this_x_shift,format='(f10.1)'),2)+','+$
      strtrim(string(this_y_shift,format='(f10.1)'),2)+'])'
    wset,stack_align_par.this_image_win
    percent_image = 100.*shifted_image/max(shifted_image)
    byte_image = byte(0.5+float(top_color_index)*$
                      (( (((percent_image-disp_min) / $
                           float(disp_max-disp_min))^disp_gamma) $
                         >0.)<1.))<byte(top_color_index)
    tv,rebin(byte_image,n_cols*img_zoom,n_rows*img_zoom,/sample),0,0

;    IF (cm NE 0) THEN BEGIN
;        diff_image = shifted_image - image_stack(*,*,0)
;        wset,stack_align_par.diff_image_win
;        percent_image = 100.*diff_image/max(diff_image)
;        tv,rebin(bytscl(percent_image, top=top_color_index, $
;                        min=-0.1*disp_max, max=0.1*disp_max), $
;                 n_cols*img_zoom,n_rows*img_zoom,/sample),0,0
;    ENDIF


    IF (i_file GT 0) THEN BEGIN
        wset,stack_align_par.plot_win
        plots,[i_file-1,i_file],x_shift(i_file-1:i_file),/data,$
          color=x_shift_plot_index
        plots,[i_file-1,i_file],y_shift(i_file-1:i_file),/data,$
          color=y_shift_plot_index
        ;; This flushes the graphics buffer
        wait,0.0001
    ENDIF
ENDFOR

widget_control,hourglass=0
; ----- aph added 8-may-00
			xpix_shift=fltarr(2) & ypix_shift=fltarr(2)
			xpix_shift(0) = min(x_shift, max = t1)
			xpix_shift(1) = t1
			ypix_shift(0) = min(y_shift, max = t1)
			ypix_shift(1) = t1
;			print, xpix_shift, ypix_shift
; ------------
end_time = systime(1.)
total_time = end_time - start_time
minutes = fix(total_time/60)
seconds = total_time-60.*minutes
IF (minutes GT 0) THEN BEGIN
    print,'Elapsed time for stack alignment: '+$
      strtrim(string(minutes),2)+' minutes '+$
      strtrim(string(seconds,format='(f10.1)'),2)+' seconds.
ENDIF ELSE BEGIN
    print,'Elapsed time for stack alignment: '+$
      strtrim(string(seconds,format='(f10.1)'),2)+' seconds.
ENDELSE

plot_min = min([min(x_shift),min(y_shift)])<(-1.)
plot_max = max([max(x_shift),max(y_shift)])>(1.)
plot,x_shift,/nodata,yrange=[plot_min,plot_max],$
  xtitle='File #', ytitle='Shift (pixels)',$
  color=white_plot_index
xyouts,3,(plot_min+0.7*(plot_max-plot_min)),/data,$
  color=x_shift_plot_index,'X'
xyouts,3,(plot_min+0.3*(plot_max-plot_min)),/data,$
  color=y_shift_plot_index,'Y'
oplot,findgen(n_files),x_shift,$
  color=x_shift_plot_index
oplot,findgen(n_files),y_shift,$
  color=y_shift_plot_index

IF (strlen(shift_file) NE 0) THEN BEGIN
    get_lun,lun
    on_ioerror, bailout
    openw,lun,shift_file
    printf,lun,'! Pixel shifts after alignment'
    printf,lun,'PLOTIT('+strtrim(string(n_files),2)
    FOR i=0,(n_files-1) DO BEGIN
        printf,lun,strtrim(string(i),2)+','+$
          strtrim(string(x_shift(i),format='(f10.4)'),2)+','+$
          strtrim(string(y_shift(i),format='(f10.4)'),2)
    ENDFOR
    bailout:
    close,lun
    free_lun,lun
    print,'Wrote pixel shifts to MAPPER-type file "'+shift_file+'"'
ENDIF

widget_control, stack_align_par.skipit_label, $
  set_value = 'Complete; go to stack_analyze'
widget_control, stack_align_par.skipit_label, sensitive = 1

;stack_align_par.complete_base = widget_base(title='Alignment Complete', /column )
;
;tlabel = $
;    widget_text(stack_align_par.complete_base,$
;                xsize=30,ysize=5,/scroll,/wrap, $
;                value='Alignment is complete.  If you do not like '+$
;                      'the alignment, hit "Exit" in the '+$
;                      'stack_analyze menu')
;stack_align_par.acknowledge_label = $
;    widget_button(stack_align_par.complete_base, $
;                  value = 'Go to stack_analyze')
;
;widget_control, stack_align_par.complete_base, /realize
;xmanager, 'stack_align_complete', stack_align_par.complete_base, $
;  group_leader = stack_align_par.main_base

return
END

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

PRO stack_align_event,event

@bsif_com
@stack_process_align_com
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

CASE event.id OF
    stack_align_par.sobel_edge_label: BEGIN
        stack_align_par.do_edge = 1
        widget_control, stack_align_par.no_edge_label, set_button = 0
        widget_control, stack_align_par.roberts_edge_label, set_button = 0
        widget_control, stack_align_par.sobel_edge_label, set_button = 1
    END

    stack_align_par.roberts_edge_label: BEGIN
        stack_align_par.do_edge = 2
        widget_control, stack_align_par.no_edge_label, set_button = 0
        widget_control, stack_align_par.sobel_edge_label, set_button = 0
        widget_control, stack_align_par.roberts_edge_label, set_button = 1
    END

    stack_align_par.no_edge_label: BEGIN
        stack_align_par.do_edge = 0
        widget_control, stack_align_par.sobel_edge_label, set_button = 0
        widget_control, stack_align_par.roberts_edge_label, set_button = 0
        widget_control, stack_align_par.no_edge_label, set_button = 1
    END

    stack_align_par.precede_match_label: BEGIN
        stack_align_par.constant_match = 0
        widget_control, stack_align_par.constant_match_label, set_button = 0
        widget_control, stack_align_par.precede_match_label, set_button = 1
    END

    stack_align_par.constant_match_label: BEGIN
        stack_align_par.constant_match = 1
        widget_control, stack_align_par.precede_match_label, set_button = 0
        widget_control, stack_align_par.constant_match_label, set_button = 1
    END

    stack_align_par.alignto_list_label: BEGIN
        stack_align_par.constant_image_index = event.index
        widget_control, stack_align_par.this_imagetitle_label, $
            set_value = $
            filename_info_list(stack_align_par.constant_image_index)
        wset,stack_align_par.this_image_win
        percent_image = $
          100.*image_stack(*,*,stack_align_par.constant_image_index) / $
          max(image_stack(*,*,stack_align_par.constant_image_index))
        byte_image = byte(0.5+float(top_color_index)*(( $
                          (((percent_image-disp_min) / $
                          float(disp_max-disp_min))^disp_gamma) $
                          >0.)<1.))<byte(top_color_index)
        tv,rebin(byte_image,n_cols*img_zoom,n_rows*img_zoom,/sample),0,0
    END

    stack_align_par.xcor_peak_label: BEGIN
        ; 0 for xcor_peak, 1 for xcor_cm
        stack_align_par.match_type = 0
        widget_control, stack_align_par.xcor_cm_label, set_button = 0
        widget_control, stack_align_par.xcor_peak_label, set_button = 1
    END

    stack_align_par.xcor_cm_label: BEGIN
        ; 0 for xcor_peak, 1 for xcor_cm
        stack_align_par.match_type = 1
        widget_control, stack_align_par.xcor_peak_label, set_button = 0
        widget_control, stack_align_par.xcor_cm_label, set_button = 1
    END

    stack_align_par.xcor_maxshift_label: BEGIN
        temp_string = ''
        widget_control, stack_align_par.xcor_maxshift_label, $
          get_value = temp_string
        on_ioerror, xcor_maxshift_label_oops
        IF (strlen(temp_string(0)) EQ 0) THEN goto, xcor_maxshift_label_oops
        reads,temp_string(0),maxshift
        IF (maxshift LT 1) THEN maxshift = 1
        IF (maxshift GT min([n_cols/2,n_rows/2])) THEN $
            maxshift = min([n_cols/2,n_rows/2])
        xcor_maxshift_label_oops:
        widget_control, stack_align_par.xcor_maxshift_label, $
          set_value = strtrim(string(maxshift,format='(i6)'),2)
    END

    stack_align_par.doit_label: BEGIN
        stack_align_doalign
    END

    stack_align_par.skipit_label: BEGIN
        widget_control, stack_align_par.main_base, /destroy
    END

ENDCASE

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; For compatibility with the SLICER, this gets its
; data from COMMON volume_data, image_stack

PRO stack_align,filename_ev_msec_list,shift_filename,zoom=zoom,realign=realign

@bsif_com
@stack_process_align_com
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

IF (NOT keyword_set(realign)) THEN realign = 0

filename_info_list = filename_ev_msec_list

shift_file = ''
have_shift_file = 0
IF (n_elements(shift_filename) NE 0) THEN BEGIN
    shift_file = shift_filename
    IF (strlen(shift_file) NE 0) THEN have_shift_file = 1
ENDIF

IF (have_shift_file EQ 1) THEN BEGIN
    it = findfile(shift_file)
    IF ( (strpos(strupcase(it(0)), strupcase(shift_file)) NE (-1)) AND $
         (realign EQ 0)) THEN BEGIN
        ; What we want to do is to read in the shifts
        ; and use them for alignment without recalculating alignment
;        read_mapper,shift_file, indices, shifts		; USE  zstack_read_mapper instead to make compatible with zimba align
        zstack_read_mapper,shift_file, indices, shifts, parm	; APH  7-Mar-09  zstack_read_mapper,stack_align_filename, indices, shifts, parameters
        n_files = n_elements(image_stack(0,0,*))
        svec = size(shifts)
        test1 = 0
        IF (svec(0) EQ 2) THEN test1 = 1
        test2 = 0
        IF (svec(1) EQ 2) THEN test2 = 1
        test3 = 0
        IF (svec(2) EQ n_files) THEN test3 = 1
        test4 = 0
        IF (n_elements(indices) EQ n_elements(image_stack(0,0,*))) THEN test4 = 1
        IF ((test1 EQ 1) AND (test2 EQ 1) AND (test3 EQ 1) AND $
            (test4 EQ 1)) THEN BEGIN
            print,'Shifting images to stored shift values'
            FOR i=0,(n_files-1) DO BEGIN
                xcenter = shifts(0,i)
                ycenter = shifts(1,i)
                IF ((abs(xcenter) GT 0.2) OR (abs(ycenter) GT 0.2)) THEN BEGIN
                    p = [xcenter,0.,1.,0.]
                    q = [ycenter,1.,0.,0.]
                    this_image = image_stack(*,*,i)
                    missing = total(this_image)/float(n_cols*n_rows)
                    this_image = poly_2d(this_image,p,q,1,missing=missing)
                    image_stack(*,*,i) = this_image
                ENDIF
            ENDFOR
; ----- aph added 8-may-00
			xpix_shift=fltarr(2) & ypix_shift=fltarr(2)
			t = reform(shifts(0,*))
			xpix_shift(0) = min(t, max = t1)
			xpix_shift(1) = t1
			t = reform(shifts(1,*))
			ypix_shift(0) = min(t, max = t1)
			ypix_shift(1) = t1
;			print, xpix_shift, ypix_shift
; ------------
            return
        ENDIF ELSE BEGIN
            print,'Could not read shifts from file; realigning.'
        ENDELSE
    ENDIF
ENDIF

IF keyword_set(zoom) THEN BEGIN
    img_zoom = zoom
ENDIF ELSE BEGIN
    img_zoom = 1
ENDELSE

plot_rows = 200
plot_cols = (n_cols*img_zoom)>300
IF (n_tags(stack_align_par) EQ 0) THEN BEGIN
    stack_align_par = $
      { stack_align_par, $
        main_base: 0L, $
        sobel_edge_label: 0L, $
        roberts_edge_label: 0L, $
        no_edge_label: 0L, $
        do_edge: 0L, $
        constant_match_label: 0L, $
        precede_match_label: 0L, $
        constant_match: 0L, $
        constant_image_index: 0L, $
        alignto_list_label: 0L, $
        xcor_peak_label: 0L, $
        xcor_cm_label: 0L, $
        xcor_maxshift_label: 0L, $
        match_type: 0L, $
        doit_label: 0L, $
        skipit_label: 0L, $
        complete_base: 0L, $
        acknowledge_label: 0L, $
        this_imagetitle_label: 0L, $
        this_imagecount_label: 0L, $
        this_image_label: 0L, $
        this_image_win: 0L, $
        diff_text_label: 0L, $
        diff_image_label: 0L, $
        diff_image_win: 0L, $
        plot_label: 0L, $
        plot_win: 0L $
      }
ENDIF

stack_align_par.main_base = widget_base(title='Stack Align', /row )
col1 = widget_base(stack_align_par.main_base,/column)
col2 = widget_base(stack_align_par.main_base,/column)

frame = widget_base(col1,/column,/frame)
edge_text = 'Edge enhance before aligning?'
tlabel = widget_text(frame,value=edge_text,xsize=(strlen(edge_text)+4)) ; ***** aph 28-jun-99
base = widget_base(frame,/column,/exclusive)
stack_align_par.sobel_edge_label = $
    widget_button( base, value='Sobel')
stack_align_par.roberts_edge_label = $
    widget_button( base, value='Roberts')
stack_align_par.no_edge_label = $
    widget_button( base, value='None')

frame = widget_base(col1,/column,/frame)
tlabel = widget_text(frame,value='Image to align to:')
base = widget_base(frame,/column,/exclusive)
stack_align_par.precede_match_label = $
    widget_button( base, value='Each preceding image');
stack_align_par.constant_match_label = $
    widget_button( base, value='Constant reference image:');
stack_align_par.alignto_list_label = $
    widget_list( frame, xsize=40, ysize=4, $
                 value = filename_info_list )

frame = widget_base(col1,/column,/frame)
tlabel = widget_text(frame,value='How to align')
base = widget_base(frame,/column,/frame,/exclusive)
stack_align_par.xcor_peak_label = $
    widget_button( base, value='X-cor peak');
stack_align_par.xcor_cm_label = $
    widget_button( base, value='X-cor CM');
row = widget_base( frame, /row )
tlabel = widget_text( row, value='X-cor pixel shift limit: ')
maxshift = min([n_cols/2,n_rows/2])
stack_align_par.xcor_maxshift_label = $
    widget_text( row, xsize=8, /editable, /frame, $
                 value=strtrim(string(maxshift,format='(i6)'),2))

frame = widget_base(col1,/column,/frame)
stack_align_par.doit_label = $
    widget_button(frame,value='Start aligning')
stack_align_par.skipit_label = $
    widget_button(frame,value='Skip alignment............................')

row = widget_base(col2,/row)
base = widget_base(row,/column)
stack_align_par.this_imagetitle_label = $
    widget_text(base,value='Image ',xsize=40)
stack_align_par.this_imagecount_label = $
    widget_text(base,value='',xsize=40)
stack_align_par.this_image_label = $
    widget_draw(base,xsize=n_cols*img_zoom,ysize=n_rows*img_zoom,retain=2)

base = widget_base(row,/column)
stack_align_par.diff_text_label = $
    widget_text(base,value='Difference from first')
stack_align_par.diff_image_label = $
    widget_draw(base,xsize=n_cols*img_zoom,ysize=n_rows*img_zoom,retain=2)

stack_align_par.plot_label = $
    widget_draw(col2,xsize=plot_cols,ysize=plot_rows,retain=2)

x_shift_color_index = !d.table_size-1
y_shift_color_index = !d.table_size-2
white_color_index = !d.table_size-3
top_color_index = !d.table_size-4

r = byte(0.5+255.*findgen(!d.table_size)/float(top_color_index))
g = r
b = r
r(x_shift_color_index) = 255
g(x_shift_color_index) = 0
b(x_shift_color_index) = 0
r(y_shift_color_index) = 0
g(y_shift_color_index) = 255
b(y_shift_color_index) = 0
r(white_color_index) = 255
g(white_color_index) = 255
b(white_color_index) = 255

IF (long(!d.n_colors) EQ 255L) THEN BEGIN
    white_plot_index = white_color_index
    x_shift_plot_index = x_shift_color_index
    y_shift_plot_index = y_shift_color_index
ENDIF ELSE IF (long(!d.n_colors) EQ 16777216L) THEN BEGIN
    ; For 24 bit color, use (r+256L*(g+256L*b))
    white_plot_index = long(white_color_index)+ $
      256L*(long(white_color_index)+256L*long(white_color_index))
    y_shift_plot_index = 256L*long(y_shift_color_index)
    x_shift_plot_index = long(x_shift_color_index)
ENDIF ELSE BEGIN
    print,'Unknown display depth'
    white_plot_index = white_color_index
    x_shift_plot_index = x_shift_color_index
    y_shift_plot_index = y_shift_color_index
ENDELSE

widget_control, stack_align_par.main_base, /realize

stack_align_par.do_edge = 1
widget_control, stack_align_par.sobel_edge_label, set_button = 0
widget_control, stack_align_par.roberts_edge_label, set_button = 0
widget_control, stack_align_par.no_edge_label, set_button = 1

stack_align_par.constant_match = 1
widget_control, stack_align_par.precede_match_label, set_button = 0
widget_control, stack_align_par.constant_match_label, set_button = 1

; 0 for xcor_peak, 1 for xcor_cm
stack_align_par.match_type = 0
widget_control, stack_align_par.xcor_cm_label, set_button = 0
widget_control, stack_align_par.xcor_peak_label, set_button = 1

widget_control,stack_align_par.this_image_label,get_value=window
stack_align_par.this_image_win = window
wset,window
tvlct,r,g,b

widget_control,stack_align_par.diff_image_label,get_value=window
stack_align_par.diff_image_win = window
wset,window
tvlct,r,g,b

widget_control,stack_align_par.plot_label,get_value=window
stack_align_par.plot_win = window
wset,window
tvlct,r,g,b

disp_min = 0.
disp_max = 110.
disp_gamma = 1.
stack_align_par.constant_image_index = 0
widget_control, stack_align_par.this_imagetitle_label, $
    set_value = filename_info_list(stack_align_par.constant_image_index)
wset,stack_align_par.this_image_win
percent_image = $
  100.*image_stack(*,*,stack_align_par.constant_image_index) / $
  max(image_stack(*,*,stack_align_par.constant_image_index))
byte_image = byte(0.5+float(top_color_index)*(( $
                  (((percent_image-disp_min) / $
                  float(disp_max-disp_min))^disp_gamma) $
                  >0.)<1.))<byte(top_color_index)
tv,rebin(byte_image,n_cols*img_zoom,n_rows*img_zoom,/sample),0,0

xmanager, 'stack_align', stack_align_par.main_base, $
  group_leader = stack_align_par.main_base

return
END
