; Copyright (c) 1998-2009 C. Zimba & A.P. Hitchcock  All rights reserved
;+
; NAME:
;	ZSTACK_TUNE.PRO
;
; LAST CHANGED: ----------------------------------- 27-Jul-09
;
; AUTHORS:
;	Carl G. Zimba (NIST), Chris Jacobsen (SUNY - Stonybrook)
; PURPOSE:
;	Alignment of images abtained on an x-ray microscope.
;	Called by ZSTACK_ALIGN.PRO
; CATEGORY:
;	Data analysis.
; CALLING SEQUENCE:
;	zstack_tune
; INPUTS:
;	NONE
;	filename_list,ev_list,msec_list,filename_display_list, and image_stack of zstack_common
;		must be previously defined via ZSTACK_ANALYZE.PRO
; KEYWORD PARAMETERS:
;	NONE
; OUTPUTS:
;	x_shift, y_shift, corr_dim_stack, corr_stack, shifted_image_stack of zstack_align_common
;		are computed as output
; COMMON BLOCKS:
;	zstack_common	:
;		data_source				:	type of x-ray microscopy data: STXM:1, SXM:2, SM:3, ALS:4, POLY:5
;		data_directory				:	directory of data files
;		image_stack				:	3-D matrix of multiple x-ray microscope images
;		filename_list				:	list of filename corresponding to images in image_stack
;		ev_list					:	list of x-ray energies corresponding to images in image_stack
;		msec_list					:	list of dwell times corresponding to images in image_stack
;		filename_display_list			:	list of filename, x-ray energy, and dwell time corresponding to images in image_stack
;		displayed_file_index			:	index in image_stack, filename_list, msec_list, and filename_display_list currently being displayed or processed
;		n_files					:	number of images
;		list_filename				:	name of file to save or retrieve list of data files
;		shift_filename				:	filename of alignment shifts
;		x_shift					:	array of x-coordinate alignment shifts
;		y_shift					:	array of y-coordinate alignment shifts
;		data_shifted				:	0: data was not shifted and should not be clipped, 1: data was shifted and should be clipped, -1: denotes ZSTACK_PROFILE.PRO is being run as a stand-alone procedure
;		n_clipped_cols				:	number of columns in clipped image
;		n_clipped_rows				:	number of rows in clipped image
;		clipbox					:	vector of four points defining dimensions of region unclipped by alignment: [xleft,xright,ybot,ytop]
;	zstack_align_common
;		zstack_align_par			:	variables controlling ZSTACK Align dialog window
;		file_num					:	vector of file numbers of image files
;		dragbox					:	vector of four points defining dimensions of region selected for alignment: [xleft,xright,ybot,ytop]
;		edge_enhance				:	edge enhancement parameter: 0: none, 1: sobel, 2: roberts
;		edgegauss_pixels			:	number of pixels used for edgeguass smoothing in ZSTACK_ALIGN_IMAGES.PRO, default = 3
;		edgefill					:	type of filling to occur at edges of shifted images: mean, median, max, min, zero
;		image_match				:	Image to align to: -1: preceding image, 0: constant image, 1: following image
;		constant_file_index			:	image of index to use as reference when aligning to a constant image
;		corr_max					:	0: use 3-pt fitted maximum of correlation function, 1: use center of mass of correlation function
;		maxshift					:	2-point vector of minimum and maximum values of x-shift and y_shift, and temp_x_shift and temp_y_shift within ZSTACK_ALIGN_TUNE
;		doalign_complete			:	-1: alignment in progress, 0: alignment not started, 1: alignment finished, 2	: using alignment from stored file
;		low_memory					:	Reflects keyword LOW_MEM: 0: use full memory allocation, 1: use reduced memory allocation
;		corr_stack					:	3-D matrix of correlation functions corresponding to image_stack
;		shifted_image_stack			:	3-D matrix of shifted images corresponding to image_stack
;		corr_dim_stack				:	3-D matrix (i,j,k) of maxima of correlation functions: i: x maximum, j: y maximum, k: image file
;		shift_threshold				:	mimimum shift required to actually shift the image
;	zstack_tune_common
;		zstack_tune_par				:	variables controlling ZSTACK Tune Alignment dialog window
;		temp_x_shift				:	vector of alignment shifts along x-coordinate for images in image_stack, obtained within ZSTACK_ALIGN_TUNE
;		temp_y_shift				:	vector of alignment shifts along y-coordinate for images in image_stack, obtained within ZSTACK_ALIGN_TUNE
;		init_x_shift				:	vector of initial alignment shifts along x-coordinate for images in image_stack
;		init_y_shift				:	vector of initial alignment shifts along y-coordinate for images in image_stack
;		image_center				:	array of pixel coordinates specifying the center (in pixels) of each image
;		corr_center				:	array of pixel coordinates specifying the center (in pixels) of each correlation function image
;		shifted_center				:	array of pixel coordinates specifying the center (in pixels) of each shifted image
;		subimage_center				:	array of pixel coordinates specifying the center (in pixels) of each subimage
;		subcorr_center				:	array of pixel coordinates specifying the center (in pixels) of each correlation function subimage
;		subshifted_center			:	array of pixel coordinates specifying the center (in pixels) of each shifted subimage
;		subimage_pixels				:	size of subimages in pixels
;		fid_pt					:	pixel coordinates of present fiducial point(s)
;		n_fid_pt					:	number of fiducial points
;		all_fid_pt					:	array of all fiducial points
;		fid_pt_index				:	index of fiducial point(s)
;	zstack_display_common
;		zstack_display_par			:	variables controlling ZSTACK Display dialog window
;		image_zoom					:	zoom factor for displaying images
;		subimage_zoom				:	zoom factor for subimages
;		movie_delay				:	delay used to display movie images of data stacks, dependent upon machine speed
;		disp_min					:	minimum percentage intensity for display of images
;		disp_max					:	maximum percentage intensity for display of images
;		disp_gamma					:	gamma factor for display of images
;		spectrum_display			:	Display spectra as: 1: Single Beam, 2: Percent Transmittance, 3: Absorbance
;		spectrum_offset				:	Offset used to plot spectra
;		init_zoom					:	initial zoom factor for displaying images (used in ZSTACK_SAVE and ZSTACK_TUNE)
;		movie_active				:	movie of images is active: 0: NO, 1: YES
;		profile_zoom				:	zoom factor for file number axis on profile images
;		image_range				:	scale images using: 0: intensity range of each image, 1: intensity range of full image stack
;		image_ratio				:	Display images normalized by: 0: inv_image_stack, 1: i0 spectrum
;		ratio_image_index			:	index of image to use when ratio images to a constant image
;		image_scale				:	Display images normalized by: 0: inv_image_stack, 1: i0 spectrum
;		image_invert				:	invert color bar: 0: NO, 1: YES
;		temp_old_display			:	initial array of display parameters, set at beginning of ZSTACK_DISPLAY
;		temp_new_display			:	array of display parameters updated as display options are changed
;		zstack_subroutine			:	subroutine from which ZSTACK_DISPLAY was called
;		spectra_x_min				:	mimimum x-ray energy value to plot spectra
;		spectra_x_max				:	maximum x-ray energy value to plot spectra
;		spectra_y_min				:	mimimum intensity value to plot spectra
;		spectra_y_max				:	maximum intensity value to plot spectra
;		x_autoscale				:	autoscale x-ray energy scale: 0: NO, 1: YES
;		y_autoscale				:	autoscale spectra intensity scale: 0: NO, 1: YES
;	zstack_color_common
;		bottom_color_index			:	index of lowermost color of gradient colorscale
;		top_color_index				:	index of uppermost color of gradient colorscale
;		black_color_index			:	index of black color
;		white_color_index			:	index of white color
;		plot_bkgd_color_index			:	color index for plot background, either black or white
;		plot_axes_color_index			:	color index for plot axes, either whilte or black
;		image_border_color_index		:	color index for image border in zstack_buildlist and zstack_profile dialog windows
;		dragbox_color_index			:	color index for dragbox used to define subregion for alignment
;		corr_ctr_color_index			:	color index for crosshair showing center of correlation function
;		corr_max_color_index			:	color index for crosshair showing maximum of correlation function
;		x_shift_color_index			:	color index for plotting of x-shift
;		y_shift_color_index			:	color index for plotting of y-shift
;		shift_cursor_color_index		:	color index for cursor in shift plot, indicating file number
;		tune_fiducial_color_index		:	color index for fiducial points in closeup of shifted image in zstack_tune dialog window
;		spectra_color_index			:	color indices (14) for plotting of spectra
;		spectra_cursor_color_index		:	color index for cursor in spectra plot, indicating x-ray energy
;		profile_color_index			:	color index for plotting of intensity profile and cursor in profile image indicating row or column
;		profile_cursor_color_index		:	color index for cursor in profile image, indicating x-ray energy
;		profile_spectrum_color_index	:	color index for plotting of profile spectrum
;		test1_color_index			:	color index #1 for testing
;		test2_color_index			:	color index #2 for testing
;		test3_color_index			:	color index #3 for testing
; SIDE EFFECTS:
;
; RESTRICTIONS:
;
; PROCEDURE:
;	Called by ZSTACK_ALIGN.PRO
; EXAMPLE:
;
; MODIFICATION HISTORY:
; Modified 25-mar-1998 to deal with 24 bit graphics, CJJ
; Modified July 11 and 13, 1998 to deal with changes to align.pro, CJJ
; Modified 28-aug-1998 to work with corrected 24 bit graphics. CJJ
; Modified 31-Aug-1998 to add x_shift, y_shift to argument list, and
;   remove shift_filename!, CJJ
;
; Modified 20feb99, CGZ
; Extensively modified and rewritten STACK_ALIGN.PRO to form ZSTACK_ALIGN.PRO
; Changes and additions are numerous:
;
; All procedures and common variables starting with 'stack' were changed to 'zstack'
; so that the existing routine, STACK_ALIGN.PRO, can be run in parallel
;
; Added the following procedures:
;	zstack_align_prep		:	sets color table and color indices
;	zstack_tune_imgdisp		:	displays images and shift plot
;	zstack_align_save_shift	:	saves alignment shift into MAPPER file, *.aln
;	zstack_align_read_shift	:	reads alignment shifts from MAPPER file, *.aln
;	zstack_tune_event	:	event routine for zstack_tune
;	zstack_tune		:	interactive adjustment of individual alignment shifts
;
; Rewrote stack_align_sensitive to be two separate procedures with better control
;	zstack_align_sensitive	:	activate features on Stack Align dialog window
;	zstack_align_desensitive	:	deactivate features on Stack Align dialog window
;
; Pre-existing procedures
;	zstack_align_doalign		:	controls alignment of image stack with active display
;	zstack_align_event		:	event routine for zstack_align
;	zstack_align			:	main procedure for alignment of STXM images
;
; Modified user interface window to include
;	display and movie of image, correlation function, shifted image
;		dragbox is plotted on both image and shifted image
;		center of correlation function displayed as crosshair overlay (same as CJJ)
;		maximum of correlation function displayed as 1-pixel box overlay (same as CJJ)
;	modified plot of alignment shifts
;		- use actual file numbers instead of file sequence number (relative number)
;		- added plot_x_min and plot_x_max
;		? is it useful to plot vs x-ray energy instead - would require considerable work
;			might be able to plot both using upper and lower x-axes
;	movie can be played before and after alignment to inspect position of dragbox
;		and quality of alignment
;	cursor bar added to plot of alignment shifts highlighting shift and file
;		during movie or static display
;	displayed file can be selected either using file list or alignment plot
;		clicking on alignment plot, prints file info and alignment shift in Output Log
;	text fields added to display image and shift information during movie or static display
;	added "Load New Color Table" to change color table of image
;	saving and retrieving of file of alignment shifts
;	added ability to redo alignment
;		- can now do multiple alignments using different conditions, saving each
;
; Changed zstack_align_par.dragbox_label routine in zstack_align_event
;	Replaced getbox routine with box_cursor routine, more robust on multiple platforms, CGZ
;
; Adapted display routines to use zstack_tune_imgdisp
;	One display algorithm which can be easily modified
;	Only exception is real-time plotting of alignment shift in zstack_align_doalign
;
; Changed the way the color table is specified: zstack_align_prep
;	- much simpler now, only executed once, allows multiple colors easily
;
; New variables:
;	corr_stack			:	stack of correlation functions
;	shift_image_stack	:	stack of shifted images
;	corr_dim_stack		:	stack of dimensions specifying center and maxima of
;							correlation function
;							used for displaying correlation function
;	edgefill			:	 type of filling to occur at edges of shifted images
;							(edges can contain no data due to shifting)
;							set within zstack_align_doalign
;		meanfill 		:	replace with mean of image
;		medianfill 	:	replace with median of image
;		maxfill 		:	replace with maximum of image
;		minfill 		:	replace with minimum of image
;		zero			:	replace with zero (default)
; 	doalign_complete	:	specifies state of alignment
;							(modified from use in stack_align.pro)
;		-1			:	alignment in progress
;		 0			:	alignment not started
;		 1			:	alignment finished
;		 2			:	using alignment from stored file
;
; Restored shift_filename to argument list
;
; Changed dragbox conditional from
;	IF ((dragbox(0) NE 0) AND (dragbox(1) NE 0) AND $
;		(dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
;	to IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
;	to accomodate dragbox = [0,0,*,*], i.e., lower left corner
;
; Save alignment / Do not save alignment choice wasn't working before - fixed
;
; Stack_align would give non-zero shift for first image
;	This is fixed with modification of call to zstack_align_images (updated version of align.pro)
;
; Added dragbox coordinates to header of MAPPER file of alignment shifts
;
; Added zstack_align_tune to interactively adjust alignment shifts
;	essentially superceding stack_manalign.pro.
;	This can be improved upon to incorporate features of stack_manalign.pro
;
; Moved nearly all widget_control,var,sensitive = 0/1 statements to
;	zstack_align_sensitive and zstack_align_desensitive for more reliable operation
;	and better organization of code (instead of being widely dispersed)
;	zstack_align_sensitive has situation-dependent conditionals to control appearance of window
;
; Need to restore virtual memory allocation when working with large data arrays
; 	so corr_stack, shift_image_stack, and corr_dim_stack) set to zero at end
;
; Added alignment to following image - useful if image quality is better at high energy
;	This is in addition to existing alignment to preceeding image and to a constant image
;	Eliminated variable, zstack_align_par.constant_match
;	Added variable, image_match with valid values:
;		-1			:	alignment using preceeding image
;		 0			:	alignment using constant image
;		 1			:	alignment using following image
;
; Added low_mem keyword to STACK_ANALYZE.PRO and STACK_ALIGN.PRO
;	If set, then shifted_image_stack is not formed with STACK_ALIGN.PRO
;	This reduces memory use by 1/3 and is useful when large arrays are being processed.
;		This comes at some reduction in speed for displaying new images,
;		most noticeable during playing of image movies
;	If set, display of shifted images within STACK_ALIGN.PRO is done by calculating
;		shifted image from x_shift, y_shift, and image_stack
;		every time an image is displayed.
;	With low_mem set, IDL partition should be approx. >9 times n_elements(image_stack)
;	With low_mem not set, IDL partition should be approx. >13 times n_elements(image_stack)
;		(based on tests on a Macintosh)
;
; Modified COMMON block structure so that common variables are shared with all zstack routines
;	i.e., zstack_common contains variables used by
;		ZSTACK_ANALYZE.PRO, ZSTACK_READLIST.PRO, ZSTACK_BUILDLIST.PRO, and ZSTACK_ALIGN.PRO
; Common variables are now defined only once in each file, not repetitively as before.
; Common variables for data are now determined within ZSTACK_BUILDLIST.PRO or ZSTACK_READLIST.PRO:
;	image_stack, filename_list, ev_list, msec_list, filename_display_list
;	This requires that files be read only once, eliminated time-intensive duplicate calls of
;		STXM_READ.PRO or SXM_READ.PRO
;
; Modified zstack_align_par, zstack_tune_par
;	so that they only contain only variables associated with dialog window.
;	All other variables have been moved to zstack_align_common
;
; Added n_files, list_filename, and shift_filename variables to zstack_common variable
;
; End of Modifications 20feb99, CGZ
;
; Divided align and tune functions into two separate procedures: ZSTACK_ALIGN.PRO and ZSTACK_TUNE.PRO
; ZSTACK_TUNE.PRO could be used as a replacement for ZSTACK_MANALIGN.PRO
;
; Fixed problem in zstack_tune_desensitive and zstack_tune_sensitive
;	if stored shift file was used, CGZ 27jun99
;
; Problem with returning to ZSTACK_ALIGN dialog if new zoom factor is selected
;	Images not properly displayed.  Fixed CGZ 12aug99
;
; (05oct00 cgz)
;	Created zstack_save_common to include variables for saving various image and movie formats
;		Moved zstack_save_par and save_filename_header from zstack_spectra_common
; (28nov00 cgz) migrated zstack_profile_colorbar routine to zstack_analyze.pro
; (04jan01 cgz) modified display routine of subimage of correlation function
;			wasn't working properly for alignments using an off-center subregion
;			still some issues here for selecting subregion for display
;			desensitized corr_win for now
; (22feb02 aph) correct transfer back from manual alignment to zstack_align
; (03-Mar-08 MJ) Keyword /SCROLL in widget_base() needs X_SCROLL_SIZE.
;                Use of /SCROLL and /MODAL at the same time not allowed.
; (13-apr-08 aph) turn on pre-set window size (X_Scroll_size, Y_Scroll_size) only for non-Windows OS
; (07-mar-09 aph) added binary_filenmane to zstack_common
; (27-jul-09 aph) external common
;-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_prep
; This routine sets up COMMON variables, color maps, and graphics parameters
;print,'zstack_tune_prep'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

zstack_color
return
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_desensitive
;print,'zstack_tune_desensitive'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

IF (movie_active EQ 0) THEN BEGIN
	widget_control, zstack_tune_par.display_list_label, sensitive = 0
ENDIF ELSE BEGIN
	widget_control, zstack_tune_par.display_list_label, sensitive = 1
ENDELSE
widget_control, zstack_tune_par.add_fiducial_label, sensitive = 0
widget_control, zstack_tune_par.reset_fiducial_label, sensitive = 0
widget_control, zstack_tune_par.x_shift_new_label, sensitive = 0
widget_control, zstack_tune_par.x_shift_slider_label, sensitive = 0
widget_control, zstack_tune_par.y_shift_new_label, sensitive = 0
widget_control, zstack_tune_par.y_shift_slider_label, sensitive = 0
widget_control, zstack_tune_par.keep_new_label, sensitive = 0
widget_control, zstack_tune_par.keep_old_label, sensitive = 0
widget_control, zstack_tune_par.reset_label, sensitive = 0
widget_control, zstack_tune_par.this_image_label, sensitive = 0
;widget_control, zstack_tune_par.closeup_this_image_label, sensitive = 0
IF (doalign_complete LE 1) THEN BEGIN		; don't plot if using manual alignment shifts or stored shift file
;IF (doalign_complete NE 2) THEN BEGIN		; don't plot if using stored shift file
	widget_control, zstack_tune_par.corr_image_label, sensitive = 0
;	widget_control, zstack_tune_par.closeup_corr_image_label, sensitive = 0
ENDIF
widget_control, zstack_tune_par.shift_image_label, sensitive = 0
;widget_control, zstack_tune_par.closeup_shift_image_label, sensitive = 0
widget_control, zstack_tune_par.prev_image_label, sensitive = 0
widget_control, zstack_tune_par.next_image_label, sensitive = 0
widget_control, zstack_tune_par.play_movie_label, sensitive = 0
widget_control, zstack_tune_par.display_parameters_label, sensitive = 0
widget_control, zstack_tune_par.plot_parameters_label, sensitive = 0
widget_control, zstack_tune_par.shift_plot_label, sensitive = 0
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_sensitive
;print,'zstack_tune_sensitive'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

widget_control, zstack_tune_par.display_list_label, sensitive = 1
widget_control, zstack_tune_par.add_fiducial_label, sensitive = 1
IF (n_fid_pt EQ 0) THEN BEGIN
	widget_control, zstack_tune_par.reset_fiducial_label, sensitive = 0
ENDIF ELSE BEGIN
	widget_control, zstack_tune_par.reset_fiducial_label, sensitive = 1
ENDELSE
widget_control, zstack_tune_par.x_shift_new_label, sensitive = 1
widget_control, zstack_tune_par.x_shift_slider_label, sensitive = 1
widget_control, zstack_tune_par.y_shift_new_label, sensitive = 1
widget_control, zstack_tune_par.y_shift_slider_label, sensitive = 1
widget_control, zstack_tune_par.keep_old_label, sensitive = 1
dummy = where(([x_shift,y_shift] NE [temp_x_shift,temp_y_shift]),count)
IF (count EQ 0) THEN BEGIN
	widget_control, zstack_tune_par.keep_new_label, sensitive = 0
	widget_control, zstack_tune_par.reset_label, sensitive = 0
ENDIF ELSE BEGIN
	widget_control, zstack_tune_par.keep_new_label, sensitive = 1
	widget_control, zstack_tune_par.reset_label, sensitive = 1
ENDELSE
widget_control, zstack_tune_par.this_image_label, sensitive = 1
;widget_control, zstack_tune_par.closeup_this_image_label, sensitive = 1
IF (doalign_complete LE 1) THEN BEGIN		; don't plot if using manual alignment shifts or stored shift file
;IF (doalign_complete NE 2) THEN BEGIN		; don't plot if using stored shift file
	widget_control, zstack_tune_par.corr_image_label, sensitive = 0
;	widget_control, zstack_tune_par.closeup_corr_image_label, sensitive = 1
ENDIF
widget_control, zstack_tune_par.shift_image_label, sensitive = 1
;widget_control, zstack_tune_par.closeup_shift_image_label, sensitive = 1
widget_control, zstack_tune_par.prev_image_label, sensitive = 1
widget_control, zstack_tune_par.next_image_label, sensitive = 1
widget_control, zstack_tune_par.play_movie_label, sensitive = 1
widget_control, zstack_tune_par.display_parameters_label, sensitive = 1
IF (doalign_complete GT 0) THEN BEGIN
	widget_control, zstack_tune_par.plot_parameters_label, sensitive = 1
ENDIF ELSE BEGIN
	widget_control, zstack_tune_par.plot_parameters_label, sensitive = 0
ENDELSE
widget_control, zstack_tune_par.shift_plot_label, sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_imgdisp,i_file
;print,'zstack_tune_imgdisp'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

zstack_analyze_imgprep,i_file,image
zstack_analyze_bytescale, image, byte_image
; Display image, applying zoom factor
wset,zstack_tune_par.this_image_win
IF (image_zoom GE 1.0) THEN BEGIN
	IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
	ENDIF ELSE BEGIN
		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
	ENDELSE
ENDIF ELSE BEGIN
	IF ( ((1./image_zoom) EQ fix(1./image_zoom)) AND $
			((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
			((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
	ENDIF ELSE BEGIN
		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
	ENDELSE
ENDELSE
;  Plot dragbox (if it exists) over raw image
IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
    ; Determine dimensions of dragbox
;    xleft = min([dragbox(0),dragbox(2)],max=xright)
;    ybot = min([dragbox(1),dragbox(3)],max=ytop)
    xleft = dragbox(0)>0
    xright = dragbox(1)<n_cols
    ybot = dragbox(2)>0
    ytop = dragbox(3)<n_rows
ENDIF ELSE BEGIN  ; set dimensions of dragbox to entire image
    xleft = 0
    xright = n_cols-1
    ybot = 0
    ytop = n_rows-1
ENDELSE
;  Plot dragbox over raw image
IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
	px = image_zoom*[xleft, xright, xright, xleft, xleft] ;X points
	py = image_zoom*[ybot, ybot, ytop, ytop, ybot] ;Y values
	plots,px,py,/device,color=dragbox_color_index
ENDIF
; Display correlation and shift images if alignment is complete
IF (doalign_complete NE 0) THEN BEGIN
	; Display shifted image with dragbox
	IF (low_memory EQ 1) THEN BEGIN
		; Shift image here to form shifted image for display
		; Conserves memory since shifted_image_stack is not formed and used
		IF ((abs(x_shift(i_file)) GT shift_threshold) OR (abs(y_shift(i_file)) GT shift_threshold)) THEN BEGIN
			; Shift the image to form this_image
			zstack_shift,image_stack(*,*,i_file),x_shift(i_file),y_shift(i_file),shifted_image,edgefill=edgefill
		ENDIF ELSE BEGIN
			; Shift smaller than threshold
			shifted_image = image_stack(*,*,i_file)
		ENDELSE
	ENDIF ELSE BEGIN
		; Get shifted image from stored array
		shifted_image = shifted_image_stack(*,*,i_file)
	ENDELSE

	zstack_analyze_bytescale, shifted_image, byte_image
	; Display shifted image, applying zoom factor
	wset,zstack_tune_par.shift_image_win
	IF (image_zoom GE 1.0) THEN BEGIN
		IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
		ENDIF ELSE BEGIN
			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
		ENDELSE
	ENDIF ELSE BEGIN
		IF ( ((1./image_zoom) EQ fix(1./image_zoom)) AND $
				((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
				((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
		ENDIF ELSE BEGIN
			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
		ENDELSE
	ENDELSE
	;  Plot dragbox (if it exists) over shifted image
	IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
		plots,(xleft-x_shift(i_file))*image_zoom,(1+ytop-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index
		plots,(1+xright-x_shift(i_file))*image_zoom,(1+ytop-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
		plots,(1+xright-x_shift(i_file))*image_zoom,(ybot-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
		plots,(xleft-x_shift(i_file))*image_zoom,(ybot-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
		plots,(xleft-x_shift(i_file))*image_zoom,(1+ytop-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
	ENDIF
ENDIF
widget_control, zstack_tune_par.display_list_label, set_droplist_select = i_file
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_corrdisp,i_file
;print,'zstack_tune_corrdisp'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

;IF (doalign_complete NE 0) THEN BEGIN
; Display correlation function (if available) with center crosshair and maximum box
;IF (abs(doalign_complete) EQ 1) THEN BEGIN		; don't deal with correlation image if using stored shift file
;  Plot dragbox (if it exists) over raw image
IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
    ; Determine dimensions of dragbox
    xleft = dragbox(0)>0
    xright = dragbox(1)<n_cols
    ybot = dragbox(2)>0
    ytop = dragbox(3)<n_rows
ENDIF ELSE BEGIN  ; set dimensions of dragbox to entire image
    xleft = 0
    xright = n_cols
    ybot = 0
    ytop = n_rows
ENDELSE

; why recalculate the correlation function maximum ?  can this be editted later ?
;	it was already done in zstack_align_images
xcenter = corr_dim_stack(0,i_file)
ycenter = corr_dim_stack(1,i_file)
;print,'Center :',xcenter,ycenter

; determine maximum of correlation function
cleft  = (n_cols/2. - maxshift)>0
cright = (n_cols/2. + maxshift)<(n_cols-1)
cbot   = (n_rows/2. - maxshift)>0
ctop   = (n_rows/2. + maxshift)<(n_rows-1)
;	cm_image = corr_stack(*,*,i_file)
;	cm_image(*,*) = 0
;	cm_image(cleft:cright,cbot:ctop) = corr_stack(cleft:cright,cbot:ctop,i_file)
;	cm_image = fltarr(n_cols,n_rows)
cm_image = corr_stack(*,*,i_file)
max_corr = max(cm_image,max_corr_pixel,min=min_corr)
x_corr = max_corr_pixel mod n_cols
y_corr = max_corr_pixel / n_rows
;print,'1 max_corr_pixel,x_corr,y_corr : ',max_corr_pixel,x_corr,y_corr

; determine points used for finding center of mass
IF (corr_max EQ 1) THEN BEGIN	; align using center of mass of correlation function
	cm_threshold = min_corr + (0.5*(max_corr - min_corr))	; mean intensity of correlation function
	cm_image = corr_stack(*,*,i_file)
	cm_indices=where((corr_stack(*,*,i_file) GE cm_threshold),n_cm)

	; the following works well but probably cuts off some pixels within the correlation peak
	cm_image(*,*) = 0
	cleft  = (x_corr - maxshift)>0
	cright = (x_corr + maxshift)<(n_cols-1)
	cbot   = (y_corr - maxshift)>0
	ctop   = (y_corr + maxshift)<(n_rows-1)
	cm_image(cleft:cright,cbot:ctop) = corr_stack(cleft:cright,cbot:ctop,i_file)
	cm_indices = where((cm_image GE cm_threshold),n_cm)
	x_corr_pts = cm_indices mod n_cols
	y_corr_pts = cm_indices / n_rows
ENDIF ELSE BEGIN
	x_corr_pts = x_corr
	y_corr_pts = y_corr
ENDELSE

; determine maximum of correlation function
max_corr = max(corr_stack(*,*,i_file),max_corr_pixel,min=min_corr)
x_corr = max_corr_pixel mod n_cols
y_corr = max_corr_pixel / n_rows
;print,'2 max_corr_pixel,x_corr,y_corr : ',max_corr_pixel,x_corr,y_corr

; Scale correlation function to fill gray scale range
IF ((dragbox(1) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
	this_image = fltarr(n_cols,n_rows)
	;print,'size(corr_stack) : ',size(corr_stack(*,*,i_file))
	;print,'size(this_image) : ',size(this_image(xleft:xright,ybot:ytop))
	this_image(xleft:xright,ybot:ytop) = corr_stack(*,*,i_file) - min(corr_stack(*,*,i_file))
ENDIF ELSE BEGIN
	this_image = corr_stack(*,*,i_file) - min(corr_stack(*,*,i_file))
ENDELSE
percent_image = 100. * this_image / max(this_image)
display_image = (( ((percent_image - disp_min) $
			/ ((disp_max - disp_min)^disp_gamma)) >0.)<1.)
byte_image = byte( float(bottom_color_index) + $
			float(top_color_index - bottom_color_index) * display_image)

; Display correlation function, applying zoom factor
wset,zstack_tune_par.corr_image_win
IF (image_zoom GE 1.0) THEN BEGIN
	IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
	ENDIF ELSE BEGIN
		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
	ENDELSE
ENDIF ELSE BEGIN
	IF ( ((1./image_zoom) EQ fix(1./image_zoom)) AND $
			((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
			((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
	ENDIF ELSE BEGIN
		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
	ENDELSE
ENDELSE

; Draw cross hair to note center of correlation function
corr_zoom = image_zoom>1
IF ((dragbox(1) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
	; define center of correlation function
	cxcenter = xleft+((xright-xleft)/2.)
	cycenter = ybot+((ytop-ybot)/2.)
	; draw cross hair to note center of correlation function
	plots,cxcenter*image_zoom+[-10*corr_zoom,-5*corr_zoom],$
		cycenter*image_zoom+[0,0],$
		/device,color=corr_ctr_color_index
	plots,cxcenter*image_zoom+[5*corr_zoom,10*corr_zoom],$
		cycenter*image_zoom+[0,0],$
		/device,color=corr_ctr_color_index
	plots,cxcenter*image_zoom+[0,0],$
		cycenter*image_zoom+[-10*corr_zoom,-5*corr_zoom],$
		/device,color=corr_ctr_color_index
	plots,cxcenter*image_zoom+[0,0],$
		cycenter*image_zoom+[5*corr_zoom,10*corr_zoom],$
		/device,color=corr_ctr_color_index
;			; draw diamond for pixel of maximum correlation intensity (shifts with alignment)
;			plots,[fix(0.5+x_corr*image_zoom)],$
;				[fix(0.5+y_corr*image_zoom)],/device,$
;				color=test1_color_index,psym=4
;			; draw points for pixels used for center of mass determination
;			plots,[fix(0.5+x_corr_pts*image_zoom)],$
;				[fix(0.5+y_corr_pts*image_zoom)],/device,$
;				color=test2_color_index,psym=3
			; draw box for pixel of correlation maximum from zstack_align_images (shifts with alignment)
;			plots,[fix(0.5+xcenter*image_zoom)],$
;				[fix(0.5+ycenter*image_zoom)],/device,$
;				color=corr_max_color_index,psym=6
;			plots,[0.5+xcenter*image_zoom],$
;				[0.5+ycenter*image_zoom],/device,$
;				color=corr_max_color_index,psym=6

;			plots,xcenter*image_zoom+[-5*corr_zoom,5*corr_zoom],ycenter*image_zoom, $
;				/device,color=corr_max_color_index
;			plots,xcenter*image_zoom,ycenter*image_zoom+[-5*corr_zoom,5*corr_zoom], $
;				/device,color=corr_max_color_index
	plots,(xleft+xcenter)*image_zoom+[-5*corr_zoom,5*corr_zoom],(ybot+ycenter)*image_zoom, $
		/device,color=corr_max_color_index
	plots,(xleft+xcenter)*image_zoom,(ybot+ycenter)*image_zoom+[-5*corr_zoom,5*corr_zoom], $
		/device,color=corr_max_color_index
	; Plot dragbox over shifted image
	px = image_zoom*[xleft, xright, xright, xleft, xleft] ;X points
	py = image_zoom*[ybot, ybot, ytop, ytop, ybot] ;Y values
	plots,px,py,/device,color=dragbox_color_index
ENDIF ELSE BEGIN
	; draw cross hair to note center of correlation function
	plots,(n_cols/2.)*image_zoom+[-10*corr_zoom,-5*corr_zoom],$
		(n_rows/2.)*image_zoom+[0,0],$
		/device,color=corr_ctr_color_index
	plots,(n_cols/2.)*image_zoom+[5*corr_zoom,10*corr_zoom],$
		(n_rows/2.)*image_zoom+[0,0],$
		/device,color=corr_ctr_color_index
	plots,(n_cols/2.)*image_zoom+[0,0],$
		(n_rows/2.)*image_zoom+[-10*corr_zoom,-5*corr_zoom],$
		/device,color=corr_ctr_color_index
	plots,(n_cols/2.)*image_zoom+[0,0],$
		(n_rows/2.)*image_zoom+[5*corr_zoom,10*corr_zoom],$
		/device,color=corr_ctr_color_index
;			; draw diamond for pixel of maximum correlation intensity (shifts with alignment)
;			plots,[fix(0.5+x_corr*image_zoom)],$
;				[fix(0.5+y_corr*image_zoom)],/device,$
;				color=test1_color_index,psym=4
;			; draw points for pixels used for center of mass determination
;			plots,[fix(0.5+x_corr_pts*image_zoom)],$
;				[fix(0.5+y_corr_pts*image_zoom)],/device,$
;				color=test2_color_index,psym=3
			; draw box for pixel of correlation maximum from zstack_align_images (shifts with alignment)
;			plots,[fix(0.5+xcenter*image_zoom)],$
;				[fix(0.5+ycenter*image_zoom)],/device,$
;				color=corr_max_color_index,psym=6
;			plots,[0.5+xcenter*image_zoom],$
;				[0.5+ycenter*image_zoom],/device,$
;				color=corr_max_color_index,psym=6
	plots,xcenter*image_zoom+[-5*corr_zoom,5*corr_zoom],ycenter*image_zoom, $
		/device,color=corr_max_color_index
	plots,xcenter*image_zoom,ycenter*image_zoom+[-5*corr_zoom,5*corr_zoom], $
		/device,color=corr_max_color_index
ENDELSE
; Print image description info
;widget_control, zstack_tune_par.filename_display_list_label,$
;		set_droplist_select=i_file
widget_control, zstack_tune_par.x_shift_init_label,$
	set_value=' '+strtrim(string(x_shift(i_file),format='(f10.3)'),2)
widget_control, zstack_tune_par.x_shift_new_label,$
	set_value=' '+strtrim(string(temp_x_shift(i_file),format='(f10.3)'),2)
widget_control, zstack_tune_par.x_shift_slider_label,$
	set_value=temp_x_shift(i_file)
widget_control, zstack_tune_par.y_shift_init_label,$
	set_value=' '+strtrim(string(y_shift(i_file),format='(f10.3)'),2)
widget_control, zstack_tune_par.y_shift_new_label,$
	set_value=' '+strtrim(string(temp_y_shift(i_file),format='(f10.3)'),2)
widget_control, zstack_tune_par.y_shift_slider_label,$
	set_value=temp_y_shift(i_file)
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_subimgdisp,i_file
;print,'zstack_tune_subimgdisp'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

zstack_analyze_imgprep,i_file,image
zstack_analyze_bytescale, image, byte_image
; sub_xleft	: left edge of subimage region in image
; sub_xright	: right edge of subimage region in image
; sub_ybot		: bottom edge of subimage region in image
; sub_ytop		: top edge of subimage region in image
; Determine boundaries of closeup image
sub_xleft = (subimage_center[0] - subimage_pixels/2.)>0
sub_xright = sub_xleft+subimage_pixels-1.
IF (sub_xright GE n_cols) THEN BEGIN
	sub_xleft = n_cols - subimage_pixels
	sub_xright = n_cols-1.
ENDIF
sub_ybot = (subimage_center[1] - subimage_pixels/2.)>0
sub_ytop = sub_ybot+subimage_pixels-1.
IF (sub_ytop GE n_rows) THEN BEGIN
	sub_ybot = n_rows - subimage_pixels
	sub_ytop = n_rows - 1.
ENDIF
; Determine closeup image
byte_image = byte_image(sub_xleft:sub_xright,sub_ybot:sub_ytop)
; Display closeup of image, applying zoom and subzoom factors
wset,zstack_tune_par.closeup_this_image_win
;IF (image_zoom GE 1.0) THEN BEGIN
;	IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
;		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;	ENDIF ELSE BEGIN
;		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;	ENDELSE
;ENDIF ELSE BEGIN
;	IF ( ((1./image_zoom) EQ fix(1./image_zoom)) AND $
;			((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
;			((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
;		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;	ENDIF ELSE BEGIN
;		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;	ENDELSE
;ENDELSE
tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;  Plot dragbox (if it exists) over closeup of raw image
IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
	;  Determine dimensions of dragbox
	xleft = min([dragbox(0),dragbox(2)],max=xright)
	ybot = min([dragbox(1),dragbox(3)],max=ytop)
	dist = subimage_center[0] - xleft
	box_xleft = image_center[0] - subimage_zoom*dist
	dist = subimage_center[0] - xright
	box_xright = image_center[0] - subimage_zoom*dist
	dist = subimage_center[1] - ybot
	box_ybot = image_center[1] - subimage_zoom*dist
	dist = subimage_center[1] - ytop
	box_ytop = image_center[1] - subimage_zoom*dist
	;  Plot dragbox over image
	plots,box_xleft*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index
	plots,1+box_xright*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index,/continue
	plots,1+box_xright*image_zoom,box_ybot*image_zoom,/device,color=dragbox_color_index,/continue
	plots,box_xleft*image_zoom,box_ybot*image_zoom,/device,color=dragbox_color_index,/continue
	plots,box_xleft*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index,/continue
ENDIF
; display closeup of correlation function and shifted image if alignment is complete
IF (doalign_complete NE 0) THEN BEGIN
	; Display shifted image with dragbox
	IF (low_memory EQ 1) THEN BEGIN
		; Shift image here to form shifted image for display
		; Conserves memory since shifted_image_stack is not formed and used
		IF ((abs(x_shift(i_file)) GT shift_threshold) OR (abs(y_shift(i_file)) GT shift_threshold)) THEN BEGIN
			; Shift the image to form this_image
			zstack_shift,image,x_shift(i_file),y_shift(i_file),shifted_image,edgefill=edgefill
		ENDIF ELSE BEGIN
			; Shift smaller than threshold
			; leave byte_image alone
			shifted_image = image
		ENDELSE
	ENDIF ELSE BEGIN
		; Get shifted image from stored array
		shifted_image = shifted_image_stack(*,*,i_file)
	ENDELSE

	zstack_analyze_bytescale, shifted_image, byte_image
	; Display closeup of shifted image
	; Determine boundaries of closeup shifted image
	sub_xleft = (subshifted_center[0] - subimage_pixels/2)>0
	sub_xright = sub_xleft+subimage_pixels-1
	IF (sub_xright GE n_cols) THEN BEGIN
		sub_xleft = n_cols - subimage_pixels
		sub_xright = n_cols-1
	ENDIF
	sub_ybot = (subshifted_center[1] - subimage_pixels/2)>0
	sub_ytop = sub_ybot+subimage_pixels-1
	IF (sub_ytop GE n_rows) THEN BEGIN
		sub_ybot = n_rows - subimage_pixels
		sub_ytop = n_rows - 1
	ENDIF
	; Determine closeup image
	byte_image = byte_image(sub_xleft:sub_xright,sub_ybot:sub_ytop)
	; Display shifted image, applying zoom factor
	wset,zstack_tune_par.closeup_shift_image_win
;	IF (image_zoom GE 1.0) THEN BEGIN
;		IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
;			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;		ENDIF ELSE BEGIN
;			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;		ENDELSE
;	ENDIF ELSE BEGIN
;		IF ( ((1./image_zoom) EQ fix(1./image_zoom)) AND $
;				((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
;				((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
;			tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;		ENDIF ELSE BEGIN
;			tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;		ENDELSE
;	ENDELSE
	tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
	;  Plot dragbox (if it exists) over shifted image
	IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
		; prepare dimensions of dragbox: xleft,xright,ytop,ybot
		xleft = min([dragbox(0),dragbox(2)],max=xright)
		ybot = min([dragbox(1),dragbox(3)],max=ytop)
		dist = subshifted_center[0] - xleft
		box_xleft = image_center - subimage_zoom*dist
		dist = subshifted_center[0] - xright
		box_xright = image_center - subimage_zoom*dist
		dist = subshifted_center[1] - ybot
		box_ybot = image_center - subimage_zoom*dist
		dist = subshifted_center[1] - ytop
		box_ytop = image_center - subimage_zoom*dist
		; draw box around dragbox region
		plots,box_xleft*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index
		plots,1+box_xright*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index,/continue
		plots,1+box_xright*image_zoom,box_ybot*image_zoom,/device,color=dragbox_color_index,/continue
		plots,box_xleft*image_zoom,box_ybot*image_zoom,/device,color=dragbox_color_index,/continue
		plots,box_xleft*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index,/continue
	ENDIF
	; Plot fiducial points and regions over shifted image
	fid_svec = size(all_fid_pt)
	IF (fid_svec(0) NE 0) THEN BEGIN
		byte_image(all_fid_pt) = tune_fiducial_color_index
;		tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
		tv,rebin(byte_image,image_zoom*subimage_zoom*subimage_pixels, $
					image_zoom*subimage_zoom*subimage_pixels,/sample),0,0
	ENDIF
	; display closeup of correlation function
	IF (doalign_complete LE 1) THEN BEGIN		; don't plot if using manual alignment shifts or stored shift file
;	IF (doalign_complete NE 2) THEN BEGIN		; don't plot if using stored shift file
		svec = size(corr_stack(*,*,i_file))
		sub_xleft = fix(0.5 + subcorr_center[0] - subimage_pixels/2)>0
		sub_xright = sub_xleft+subimage_pixels-1
		IF (sub_xright GE svec(1)) THEN BEGIN
			sub_xleft = fix((svec(1) - subimage_pixels)/2)
			sub_xright = fix((svec(1) + subimage_pixels)/2 - 1)
		ENDIF
		sub_ybot = fix(0.5 + subcorr_center[1] - subimage_pixels/2)>0
		sub_ytop = sub_ybot+subimage_pixels-1
		IF (sub_ytop GE svec(2)) THEN BEGIN
			sub_ybot = fix((svec(2) - subimage_pixels)/2)
			sub_ytop = fix((svec(2) + subimage_pixels)/2 -1)
		ENDIF
;print,'size(corr_stack(*,*,i_file)) : ', size(corr_stack(*,*,i_file))
;print,'sub_xleft:sub_xright,sub_ybot:sub_ytop : ', sub_xleft,sub_xright,sub_ybot,sub_ytop
		percent_image = 100.*corr_stack(sub_xleft:sub_xright,sub_ybot:sub_ytop,i_file) / $
						max(corr_stack(*,*,i_file))
		display_image = (( ((percent_image - disp_min) $
					/ ((disp_max - disp_min)^disp_gamma)) >0.)<1.)
		byte_image = byte( float(bottom_color_index) + $
					float(top_color_index - bottom_color_index) * $
					display_image)
		wset,zstack_tune_par.closeup_corr_image_win
;;		IF (image_zoom GE 1.0) THEN BEGIN
;;			IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
;;				tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;;			ENDIF ELSE BEGIN
;;				tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;;			ENDELSE
;;		ENDIF ELSE BEGIN
;;			IF ( ((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
;;				((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
;;				tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;;			ENDIF ELSE BEGIN
;;				tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;;			ENDELSE
;;		ENDELSE
;		IF (image_zoom GE 1.0) THEN BEGIN
;			IF ((image_zoom) EQ fix(image_zoom)) THEN BEGIN
;				tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;			ENDIF ELSE BEGIN
;				tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;			ENDELSE
;		ENDIF ELSE BEGIN
;			IF ( ((1./image_zoom) EQ fix(1./image_zoom)) AND $
;					((image_zoom*n_cols) EQ fix(image_zoom*n_cols)) AND $
;					((image_zoom*n_rows) EQ fix(image_zoom*n_rows)) ) THEN BEGIN
;				tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;			ENDIF ELSE BEGIN
;				tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
;			ENDELSE
;		ENDELSE
		tv,congrid(byte_image,n_cols*image_zoom,n_rows*image_zoom),0,0
		IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
			; prepare dimensions of dragbox: xleft,xright,ytop,ybot
			xleft = min([dragbox(0),dragbox(2)],max=box_xright)
			ybot = min([dragbox(1),dragbox(3)],max=box_ytop)
			dist = subcorr_center[0] - xleft
			box_xleft = image_center[0] - subimage_zoom*dist
			dist = subcorr_center[0] - xright
			box_xright = image_center[0] - subimage_zoom*dist
			dist = subcorr_center[1] - ybot
			box_ybot = image_center[1] - subimage_zoom*dist
			dist = subcorr_center[1] - ytop
			box_ytop = image_center[1] - subimage_zoom*dist
			; draw box around dragbox region
			plots,box_xleft*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index
			plots,1+box_xright*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index,/continue
			plots,1+box_xright*image_zoom,box_ybot*image_zoom,/device,color=dragbox_color_index,/continue
			plots,box_xleft*image_zoom,box_ybot*image_zoom,/device,color=dragbox_color_index,/continue
			plots,box_xleft*image_zoom,1+box_ytop*image_zoom,/device,color=dragbox_color_index,/continue
		ENDIF
		corr_max_x = corr_dim_stack(0,i_file)
		corr_max_y = corr_dim_stack(1,i_file)
;print,'Maximum 2 :',corr_max_x,corr_max_y
		dist = subcorr_center[0] - corr_max_x
		subcorr_max_x = image_center[0] - subimage_zoom*dist
		dist = subcorr_center[1] - corr_max_y
		subcorr_max_y = image_center[1] - subimage_zoom*dist
		; draw crosshair for correlation maximum (shifts with alignment)
		plots,subcorr_max_x*image_zoom+[-15.,15.],subcorr_max_y*image_zoom+[0.,0.],$
			/device,color=corr_max_color_index
		plots,subcorr_max_x*image_zoom+[0.,0.],subcorr_max_y*image_zoom+[-15.,15.],$
			/device,color=corr_max_color_index
; KEEP THE FOLLOWING SECTION - helpful for confirming maximum of correlation function
;		dleft  = (n_cols/2. - maxshift)>0
;		dright = (n_cols/2. + maxshift)<(n_cols-1)
;		dbot   = (n_rows/2. - maxshift)>0
;		dtop   = (n_rows/2. + maxshift)<(n_rows-1)
;		dummy_percent_image = percent_image
;		dummy_percent_image(*,*) = 0
;		dummy_percent_image(dleft:dright,dbot:dtop) = percent_image(dleft:dright,dbot:dtop)
;
; Following section is to draw a different crosshair - incomplete
; meant to display position in correlation function as shifted using zstack_tune
;		dummy = max(percent_image,subcorr_max)
;		dummy = min(percent_image,subcorr_min)
;		; set (corr_max_x,corr_max_y) at maximum of correlation function
;		corr_max_x = subcorr_max mod (n_cols/subimage_zoom)
;		corr_max_y = fix(subcorr_max / (n_rows/subimage_zoom))
;;	print,'Maximum 4 :',subcorr_max,corr_max_x,corr_max_y
;;	print,size(percent_image)
;;	print,subcorr_center
;		; this is the initial value of correlation maximum
;		; it is refined further below using either center of mass or quadratic fit
;
;		dist = subcorr_center[0] - corr_max_x
;		subcorr_max_x = image_center[0] - image_zoom*dist
;		dist = subcorr_center[1] - corr_max_y
;		subcorr_max_y = image_center[1] - image_zoom*dist
;
;		; draw crosshair for correlation maximum (shifts with alignment)
;		plots,subcorr_max_x*image_zoom+[-10.,10.],subcorr_max_y*image_zoom+[0.,0.],$
;				/device,color=test2_color_index
;		plots,subcorr_max_x*image_zoom+[0.,0.],subcorr_max_y*image_zoom+[-10.,10.],$
;				/device,color=test2_color_index
; KEEP THE FOLLOWING SECTION - helpful for confirming maximum of correlation function
;		dummy_percent_image = rebin(percent_image,image_zoom*subimage_zoom*subimage_pixels, $
;							image_zoom*subimage_zoom*subimage_pixels,/sample)
;
;		dummy = max(dummy_percent_image,subcorr_max)
;		dummy = min(dummy_percent_image,subcorr_min)
;		; set (corr_max_x,corr_max_y) at maximum of correlation function
;		corr_max_x = subcorr_max mod (subimage_pixels*subimage_zoom*image_zoom)
;		corr_max_y = fix(subcorr_max / (subimage_pixels*subimage_zoom*image_zoom))
;		; this is the initial value of correlation maximum
;		; it is refined further below using either center of mass or quadratic fit
;
;		IF (corr_max NE 0) THEN BEGIN	; align using center of mass of correlation function;
;			cm_image = dummy_percent_image
;			cm_threshold = subcorr_min + (0.5*(subcorr_max - subcorr_min))	; mean intensity of correlation function
;			cm_indices=where((cm_image GE cm_threshold),n_cm)
;
;			IF (n_cm GE 4) THEN BEGIN
;				xpositions = cm_indices mod nx
;				ypositions = floor(cm_indices/nx)
;				inverse_mass_total = 1./total(cm_image(cm_indices))
;				corr_max_x=total(xpositions*cm_image(cm_indices))*inverse_mass_total
;				corr_max_y=total(ypositions*cm_image(cm_indices))*inverse_mass_total
;
;				IF keyword_set(debug) THEN BEGIN
;					print,'Center of mass is at ['+$
;						strtrim(string(corr_max_x,format='(f10.2)'),2)+','+$
;						strtrim(string(corr_max_y,format='(f10.2)'),2)+']'
;				ENDIF
;			ENDIF
;		ENDIF ELSE BEGIN	; align using quadratic fit of maximum of correlation function
;			xpts = corr_max_x+[-1,0,1]
;			ypts = dummy_percent_image((corr_max_x-1):(corr_max_x+1),corr_max_y)
;			tri_fit,xpts,ypts,xfit,xpeak
;			xpts = dummy_percent_image(corr_max_x,(corr_max_y-1):(corr_max_y+1))
;			ypts = corr_max_y+[-1,0,1]
;			tri_fit,ypts,xpts,yfit,ypeak
;			corr_max_x = xpeak
;			corr_max_y = ypeak
;			IF keyword_set(debug) THEN BEGIN
;				print,'Quadratic center is at ['+$
;					strtrim(string(corr_max_x,format='(f10.2)'),2)+','+$
;					strtrim(string(corr_max_y,format='(f10.2)'),2)+']'
;			ENDIF
;		ENDELSE
;
;		subcorr_max_x = corr_dim_stack(0,i_file)
;		subcorr_max_y = corr_dim_stack(1,i_file)
;		print,'Maximum 2 :',subcorr_max_x,subcorr_max_y
;
;		dist = subcorr_center[0] - subcorr_max_x
;		subcorr_max_x = image_center[0] - subimage_zoom*dist
;		dist = subcorr_center[1] - subcorr_max_y
;		subcorr_max_y = image_center[1] - subimage_zoom*dist
;
;		; draw crosshair for correlation maximum (shifts with alignment)
;		plots,subcorr_max_x*image_zoom+[-10.,10.],subcorr_max_y*image_zoom+[0.,0.],$
;				/device,color=test1_color_index
;		plots,subcorr_max_x*image_zoom+[0.,0.],subcorr_max_y*image_zoom+[-10.,10.],$
;				/device,color=test1_color_index
;END OF SECTION
	ENDIF
ENDIF
return
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_plotshifts,i_file
;print,'zstack_tune_plotshifts'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

; Plot alignment shift vs file number
wset,zstack_tune_par.shift_plot_win
; Determine range of x-values in plot
;!x.range = [min(file_num),max(file_num)]
; Determine range of x-values in plot
IF (x_autoscale EQ 1)	 THEN BEGIN	; autoscale x-axis
	!x.range = [min(file_num),max(file_num)]
ENDIF ELSE BEGIN
	!x.range = [plot_x_min, plot_x_max]
ENDELSE
dummy = where(file_num GE !x.range[0] AND file_num LE !x.range[1], count)
;!y.range = [min([min(x_shift),min(y_shift),min(temp_x_shift),min(temp_y_shift)]), $
;		max([max(x_shift),max(y_shift), max(temp_x_shift),max(temp_y_shift)])]
;!y.range[0] = (1.05 * !y.range[0]) < (0.95 * !y.range[0])
;!y.range[1] = (1.05 * !y.range[1]) > (0.95 * !y.range[1])
; Determine range of y-values in plot
IF (y_autoscale EQ 1) THEN BEGIN	; autoscale y-axis
;	!y.range = [min([min(x_shift),min(y_shift)]),max([max(x_shift),max(y_shift)])]
	!y.range = [min([min(x_shift[dummy]),min(y_shift[dummy]),min(temp_x_shift),min(temp_y_shift)]), $
			max([max(x_shift[dummy]),max(y_shift[dummy]),max(temp_x_shift),max(temp_y_shift)])]
	!y.range[0] = (1.05 * !y.range[0]) < (0.95 * !y.range[0])
	!y.range[1] = (1.05 * !y.range[1]) > (0.95 * !y.range[1])
	; if all shifts are zero, artificially set the range
	IF (!y.range[0] EQ 0) THEN BEGIN
		!y.range[0] = -0.1
	ENDIF
	IF (!y.range[1] EQ 0) THEN BEGIN
		!y.range[1] = 0.1
	ENDIF
ENDIF ELSE BEGIN
	!y.range = [plot_y_min, plot_y_max]
ENDELSE
; Plot alignment shift vs file #
plot,file_num,x_shift,/nodata, $
		xtitle='File #', ytitle='Shift (pixels)',$
		color=plot_axes_color_index, background=plot_bkgd_color_index
oplot,file_num,x_shift,color=x_shift_color_index
oplot,file_num,y_shift,color=y_shift_color_index
oplot,file_num,temp_x_shift,color=x_shift_color_index,linestyle=1
oplot,file_num,temp_y_shift,color=y_shift_color_index,linestyle=1
; Plot X and Y labels on alignment shift plot
xyouts,3+!x.range[0],(!y.range[0]+0.8*(!y.range[1] - !y.range[0])),/data, $
		color=x_shift_color_index,charthick=2,'X'
xyouts,3+!x.range[0],(!y.range[0]+0.2*(!y.range[1] - !y.range[0])),/data, $
		color=y_shift_color_index,charthick=2,'Y'
; Plot a indicator bar marking shift for displayed image
oplot,file_num(i_file)+[0.,0.],!y.crange,color=shift_cursor_color_index
; End of plot of alignment shift vs file number
; KEEP THIS - DO NOT DELETE - OPTIONAL PORTION OF CODE
; PLOT SHIFT VS X-RAY ENERGY
; Determine range of x-values in plot
;	!x.range = [min(ev_list),max(ev_list)]
;	!y.range = [min([min(x_shift),min(y_shift),min(temp_x_shift),min(temp_y_shift)]), $
;			max([max(x_shift),max(y_shift), max(temp_x_shift),max(temp_y_shift)])]
;	!y.range[0] = (1.05 * !y.range[0]) < (0.95 * !y.range[0])
;	!y.range[1] = (1.05 * !y.range[1]) > (0.95 * !y.range[1])
;
;	; plot axes and alignment shifts
;	plot,ev_list,x_shift,/nodata, $
;		xtitle='X-ray Energy (eV)', ytitle='Shift (pixels)',$
;		color=plot_axes_color_index, background=plot_bkgd_color_index
;	oplot,ev_list,x_shift,color=x_shift_color_index
;	oplot,ev_list,y_shift,color=y_shift_color_index
;	oplot,ev_list,temp_x_shift,color=x_shift_color_index,linestyle=1
;	oplot,ev_list,temp_y_shift,color=y_shift_color_index,linestyle=1
;
; 	; Plot X and Y labels on alignment shift plot
;	xyouts,3+!x.range[0],(!y.range[0]+0.8*(!y.range[1] - !y.range[0])),/data, $
;			color=x_shift_color_index,charthick=2,'X'
;	xyouts,3+!x.range[0],(!y.range[0]+0.2*(!y.range[1] - !y.range[0])),/data, $
;			color=y_shift_color_index,charthick=2,'Y'
;
;	; Plot a indicator bar marking shift for displayed image
;	oplot,file_num(i_file)+[0.,0.],!y.crange,color=shift_cursor_color_index
;	; End of plot of alignment shift vs file number
; END OF PLOT SHIFT VS X-RAY ENERGY
return
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_event,event
;print,'zstack_tune_event'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

;svec = size(image_stack)	; added, CGZ
;n_files=svec(3)			; added, CGZ
IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
    ; prepare dimensions of dragbox: xleft,xright,ytop,ybot
    xleft = min([dragbox(0),dragbox(2)],max=xright)
    ybot = min([dragbox(1),dragbox(3)],max=ytop)
    xleft = xleft>0
    xright = xright<(n_cols-1)
    ybot = ybot>0
    ytop = ytop<(n_rows-1)
ENDIF ELSE BEGIN  ; set dimensions of dragbox to entire image
    xleft = 0
    xright = n_cols-1
    ybot = 0
    ytop = n_rows-1
ENDELSE
CASE event.id OF
    zstack_tune_par.display_list_label : BEGIN
        displayed_file_index = event.index
        zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
        zstack_tune_subimgdisp,displayed_file_index
        zstack_tune_plotshifts,displayed_file_index
    END
   zstack_tune_par.add_fiducial_label : BEGIN
		zstack_tune_desensitive
		widget_control, zstack_tune_par.closeup_shift_image_label, sensitive = 1
		fid_pt = cw_defroi(zstack_tune_par.closeup_shift_image_label, $
				zoom=[image_zoom*subimage_zoom,image_zoom*subimage_zoom])
			; need zoom parameter in case zoom NE 1, CGZ
		svec = size(fid_pt)
		IF (svec(0) NE 0) THEN BEGIN	; proceed only if regions of fiducial points is real region
			n_fid_pt = n_fid_pt +1	; n_fid_pt = 1 for first I region of fiducial points, 2 for second region of fiducial points, etc.
			svec = size(all_fid_pt)
			IF (svec(0) EQ 0) THEN BEGIN
				all_fid_pt = fid_pt
			ENDIF ELSE BEGIN
				all_fid_pt = [all_fid_pt,fid_pt]
			ENDELSE
			; create fid_pt_index
			IF (n_elements(fid_pt_index) EQ 1) THEN BEGIN
				fid_pt_index = fix([0,n_elements(all_fid_pt)])
			ENDIF ELSE BEGIN
				fid_pt_index = fix([fid_pt_index,n_elements(all_fid_pt)])
					; index of all_fid_pt where each element denotes beginning each individual fid_pt
					; i.e., all_fid_pt = [0,253,685,1165] means that
					; the first all_fid_pt region begins at index 0 and ends at index 252,
					; the second all_fid_pt begins at index 253 and ends at index 684, etc.
			ENDELSE
		ENDIF
		zstack_tune_sensitive
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
;x_fid_pt = fid_pt[0] mod subimage_pixels
;y_fid_pt = fix(fid_pt[0]/subimage_pixels)
;big_fid_pt = fid_pt - subimage_pixels/2
	END
	zstack_tune_par.reset_fiducial_label : BEGIN
		fid_pt = 0
		n_fid_pt = 0
		all_fid_pt = 0
		fid_pt_index = 0
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
		zstack_tune_sensitive
	END

    zstack_tune_par.add_edge_label : BEGIN
print,'adding edge countours'
; Display shifted image with dragbox
	wset,zstack_tune_par.shift_image_win
i_file = displayed_file_index
	IF (low_memory EQ 1) THEN BEGIN
		; shift image here to form shifted image for display
		; conserves memory since shifted_image_stack is not formed and used
		; Shift the image
		IF ((abs(x_shift(i_file)) GT 0.02) OR (abs(y_shift(i_file)) GT 0.02)) THEN BEGIN
			zstack_shift,image_stack(*,*,i_file),x_shift(i_file),y_shift(i_file), $
				shifted_image,edgefill='zero'
		ENDIF ELSE BEGIN
			shifted_image = image_stack(*,*,i_file)
		ENDELSE
		; prepare and display shifted image
		percent_image = 100.*shifted_image / max(shifted_image)
	ENDIF ELSE BEGIN
		; prepare and display shifted image
		percent_image = 100.*shifted_image_stack(*,*,i_file) / $
			max(shifted_image_stack(*,*,i_file))
	ENDELSE

	display_image = (( ((percent_image - disp_min) $
				/ ((disp_max - disp_min)^disp_gamma)) >0.)<1.)
	byte_image = byte( float(bottom_color_index) + $
				float(top_color_index - bottom_color_index) * $
				display_image)
	tv,rebin(byte_image,n_cols*image_zoom,n_rows*image_zoom,/sample),0,0
;image_cont,sobel(byte_image),/window_scale
;contour,sobel(byte_image),/overplot,nlevels=5,c_colors=[test3_color_index]
contour,sobel(byte_image),path_xy=xy,path_info=info
;print,xy
;print,info
FOR i=0, (n_elements(info)-1) DO BEGIN
	s = [indgen(info(i).N),0]
	plots,xy(*,info(i).offset + s),/norm,color=test3_color_index
ENDFOR
	;  Plot dragbox over shifted image
	IF ((dragbox(2) NE 0) AND (dragbox(3) NE 0)) THEN BEGIN
		plots,(xleft-x_shift(i_file))*image_zoom,(1+ytop-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index
		plots,(1+xright-x_shift(i_file))*image_zoom,(1+ytop-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
		plots,(1+xright-x_shift(i_file))*image_zoom,(ybot-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
		plots,(xleft-x_shift(i_file))*image_zoom,(ybot-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
		plots,(xleft-x_shift(i_file))*image_zoom,(1+ytop-y_shift(i_file))*image_zoom, $
			/device,color=dragbox_color_index,/continue
	ENDIF
	END
	zstack_tune_par.reset_edge_label : BEGIN
		fid_pt = 0
		n_fid_pt = 0
		all_fid_pt = 0
		fid_pt_index = 0
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
		zstack_tune_sensitive
	END

    zstack_tune_par.keep_new_label : BEGIN		; zzz
		doalign_complete = 2
		x_shift = temp_x_shift
		y_shift = temp_y_shift
		widget_control, zstack_tune_par.main_base, /destroy   ; APH remove commment out
		IF (image_zoom EQ init_zoom) THEN BEGIN
			wshow,zstack_align_par.main_base_win
;			widget_control, zstack_align_par.main_base, /destroy   ; APH commment out
			zstack_align_imgdisp,displayed_file_index
			; Display correlation function
			IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
				zstack_align_corrdisp,displayed_file_index
			ENDIF
			; Plot alignment shifts with cursor bar
			IF (doalign_complete GT 0) THEN BEGIN		; will only display if align is complete
				zstack_align_plotshifts,displayed_file_index
			ENDIF
			zstack_align_sensitive
		ENDIF ELSE BEGIN
;			widget_control, zstack_align_par.main_base, /destroy
			zstack_align
			widget_control, zstack_align_par.main_base, /destroy
		ENDELSE
    END
    zstack_tune_par.keep_old_label : BEGIN		; zzz
		IF (doalign_complete EQ 0) THEN BEGIN
			doalign_complete = 2
		ENDIF
		; Shift the image back to original shift, CGZ
		shift_indices = (x_shift EQ temp_x_shift) AND (y_shift EQ temp_y_shift)
		shift_indices = where((shift_indices EQ 0),count)
		IF (low_memory EQ 0) THEN BEGIN
			FOR i=1,count DO BEGIN
				i_file = shift_indices(i-1)
				IF ((abs(x_shift(i_file)) GT 0.02) OR (abs(y_shift(i_file)) GT 0.02)) THEN BEGIN
					zstack_shift,image_stack(*,*,i_file),x_shift(i_file),y_shift(i_file), $
						shifted_image,edgefill='zero'
				ENDIF ELSE BEGIN
					shifted_image = image_stack(*,*,i_file)
				ENDELSE
				shifted_image_stack(*,*,i_file) = shifted_image
			ENDFOR
		ENDIF
;        widget_control, zstack_tune_par.main_base, /destroy
		IF (image_zoom EQ init_zoom) THEN BEGIN
			wshow,zstack_align_par.main_base_win
			widget_control, zstack_tune_par.main_base, /destroy
			zstack_align_imgdisp,displayed_file_index
			; Display correlation function
			IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
				zstack_align_corrdisp,displayed_file_index
			ENDIF
			; Plot alignment shifts with cursor bar
			IF (doalign_complete GT 0) THEN BEGIN		; will only display if align is complete
				zstack_align_plotshifts,displayed_file_index
			ENDIF
			zstack_align_sensitive
		ENDIF ELSE BEGIN
;			widget_control, zstack_align_par.main_base, /destroy
			zstack_align, new_zoom = image_zoom
			widget_control, zstack_tune_par.main_base, /destroy
		ENDELSE
    END
    zstack_tune_par.reset_label : BEGIN
		temp_x_shift = x_shift
		temp_y_shift = y_shift
		image_center = [n_cols/2.,n_rows/2.]
		corr_center = [n_cols/2.,n_rows/2.]
		shifted_center = [n_cols/2.,n_rows/2.]
		subimage_center = [n_cols/2.,n_rows/2.]
		subcorr_center = [n_cols/2.,n_rows/2.]
		subshifted_center = [n_cols/2.,n_rows/2.]
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
		zstack_tune_sensitive
    END
	zstack_tune_par.this_image_label : BEGIN
		IF (event.press EQ 1) THEN BEGIN
			subimage_center[0] = 0.5 + event.x / image_zoom
			subimage_center[1] = 0.5 + event.y / image_zoom
			zstack_tune_subimgdisp,displayed_file_index
		ENDIF
	END

	zstack_tune_par.corr_image_label : BEGIN
		IF (event.press EQ 1) THEN BEGIN
			subcorr_center[0] = 0.5 - dragbox[0] + event.x / image_zoom >0
			subcorr_center[1] = 0.5 - dragbox[2] + event.y / image_zoom >0
;			print,'subcorr_center : ',subcorr_center
			zstack_tune_subimgdisp,displayed_file_index
		ENDIF
	END

	zstack_tune_par.shift_image_label : BEGIN
		IF (event.press EQ 1) THEN BEGIN
			subshifted_center[0] = fix(0.5 + event.x / image_zoom)
			subshifted_center[1] = fix(0.5 + event.y / image_zoom)
			; Reset fiducial points in shifted subimage
			fid_pt = 0
			n_fid_pt = 0
			all_fid_pt = 0
			fid_pt_index = 0
			zstack_tune_subimgdisp,displayed_file_index
		ENDIF
	END

	zstack_tune_par.closeup_this_image_label : BEGIN
	END

	zstack_tune_par.closeup_corr_image_label : BEGIN
	END

	zstack_tune_par.closeup_shift_image_label : BEGIN
	END

    zstack_tune_par.x_shift_new_label : BEGIN
		temp_string = ''
		widget_control, zstack_tune_par.x_shift_new_label, $
			get_value = temp_string
		on_ioerror, x_shift_new_label_oops
		IF (strlen(temp_string(0)) EQ 0) THEN GOTO, x_shift_new_label_oops
		reads,temp_string(0),trial_shift
;		IF (trial_shift GT maxshift) THEN trial_shift = maxshift
;		IF (trial_shift LT -maxshift) THEN trial_shift = -maxshift
		x_shift_new_label_oops:
		widget_control, zstack_tune_par.x_shift_new_label, $
			set_value = ' '+strtrim(string(trial_shift,format='(f10.3)'),2)
		temp_x_shift(displayed_file_index) = trial_shift
		;; Shift the image, CGZ
;		IF (abs(temp_x_shift(displayed_file_index)) GT 0.02) THEN BEGIN
		IF (abs(temp_x_shift(displayed_file_index)) GT shift_threshold) THEN BEGIN
			zstack_shift,image_stack(*,*,displayed_file_index), $
				temp_x_shift(displayed_file_index), $
				temp_y_shift(displayed_file_index), $
				shifted_image,edgefill='zero'
		ENDIF ELSE BEGIN
			shifted_image = image_stack(*,*,displayed_file_index)
		ENDELSE
		IF (low_memory EQ 0) THEN BEGIN
;			Create shifted_image_stack to temporarily save shifted image files, CGZ
			shifted_image_stack(*,*,displayed_file_index) = shifted_image
		ENDIF
		zstack_tune_sensitive
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
    END

    zstack_tune_par.x_shift_slider_label : BEGIN
		widget_control, zstack_tune_par.x_shift_slider_label, $
			get_value = trial_shift
		widget_control, zstack_tune_par.x_shift_new_label, $
			set_value = ' '+strtrim(string(trial_shift,format='(f10.3)'),2)
		temp_x_shift(displayed_file_index) = trial_shift
		;; Shift the image, CGZ
;		IF (abs(temp_x_shift(displayed_file_index)) GT 0.02) THEN BEGIN
		IF (abs(temp_x_shift(displayed_file_index)) GT shift_threshold) THEN BEGIN
			zstack_shift,image_stack(*,*,displayed_file_index), $
				temp_x_shift(displayed_file_index), $
				temp_y_shift(displayed_file_index), $
				shifted_image,edgefill='zero'
		ENDIF ELSE BEGIN
			shifted_image = image_stack(*,*,displayed_file_index)
		ENDELSE
		IF (low_memory EQ 0) THEN BEGIN
;			Create shifted_image_stack to temporarily save shifted image files, CGZ
			shifted_image_stack(*,*,displayed_file_index) = shifted_image
		ENDIF
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
		zstack_tune_sensitive
    END

    zstack_tune_par.y_shift_new_label : BEGIN
		temp_string = ''
		widget_control, zstack_tune_par.y_shift_new_label, $
			get_value = temp_string
		on_ioerror, y_shift_new_label_oops
		IF (strlen(temp_string(0)) EQ 0) THEN GOTO, y_shift_new_label_oops
		reads,temp_string(0),trial_shift
;		IF (trial_shift GT maxshift) THEN trial_shift = maxshift
;		IF (trial_shift LT -maxshift) THEN trial_shift = -maxshift
		y_shift_new_label_oops:
		widget_control, zstack_tune_par.y_shift_new_label, $
			set_value = ' '+strtrim(string(trial_shift,format='(f10.3)'),2)
		temp_y_shift(displayed_file_index) = trial_shift
		;; Shift the image, CGZ
;		IF (abs(temp_y_shift(displayed_file_index)) GT 0.02) THEN BEGIN
		IF (abs(temp_y_shift(displayed_file_index)) GT shift_threshold) THEN BEGIN
			zstack_shift,image_stack(*,*,displayed_file_index), $
				temp_x_shift(displayed_file_index), $
				temp_y_shift(displayed_file_index), $
				shifted_image,edgefill='zero'
		ENDIF ELSE BEGIN
			shifted_image = image_stack(*,*,displayed_file_index)
		ENDELSE
		IF (low_memory EQ 0) THEN BEGIN
;			Create shifted_image_stack to temporarily save shifted image files, CGZ
			shifted_image_stack(*,*,displayed_file_index) = shifted_image
		ENDIF
		zstack_tune_sensitive
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
    END
    zstack_tune_par.y_shift_slider_label : BEGIN
		widget_control, zstack_tune_par.y_shift_slider_label, $
			get_value = trial_shift
		widget_control, zstack_tune_par.y_shift_new_label, $
			set_value = ' '+strtrim(string(trial_shift,format='(f10.3)'),2)
		temp_y_shift(displayed_file_index) = trial_shift
		;; Shift the image, CGZ
;		IF (abs(temp_y_shift(displayed_file_index)) GT 0.02) THEN BEGIN
		IF (abs(temp_y_shift(displayed_file_index)) GT shift_threshold) THEN BEGIN
			zstack_shift,image_stack(*,*,displayed_file_index), $
				temp_x_shift(displayed_file_index), $
				temp_y_shift(displayed_file_index), $
				shifted_image,edgefill='zero'
		ENDIF ELSE BEGIN
			shifted_image = image_stack(*,*,displayed_file_index)
		ENDELSE
		IF (low_memory EQ 0) THEN BEGIN
;			Create shifted_image_stack to temporarily save shifted image files, CGZ
			shifted_image_stack(*,*,displayed_file_index) = shifted_image
		ENDIF
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
		zstack_tune_sensitive
    END
	zstack_tune_par.next_image_label : BEGIN
		IF (displayed_file_index LT (n_files-1)) THEN BEGIN
			displayed_file_index = displayed_file_index+1
		ENDIF ELSE BEGIN
			displayed_file_index = 0
		ENDELSE
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
	END

	zstack_tune_par.prev_image_label : BEGIN
		IF (displayed_file_index GT 0) THEN BEGIN
			displayed_file_index = displayed_file_index-1
		ENDIF ELSE BEGIN
			displayed_file_index = n_files-1
		ENDELSE
		zstack_tune_imgdisp,displayed_file_index
		IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
			zstack_tune_corrdisp,displayed_file_index
		ENDIF
		zstack_tune_subimgdisp,displayed_file_index
		zstack_tune_plotshifts,displayed_file_index
	END

	zstack_tune_par.play_movie_label : BEGIN
		movie_active = 1
		zstack_tune_desensitive
		FOR i=0,(n_files-1) DO BEGIN
			IF (displayed_file_index LT (n_files-1)) THEN BEGIN
				displayed_file_index = displayed_file_index+1
			ENDIF ELSE BEGIN
				displayed_file_index = 0
			ENDELSE
			zstack_tune_imgdisp, displayed_file_index
			IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
				zstack_tune_corrdisp,displayed_file_index
			ENDIF
			zstack_tune_subimgdisp,displayed_file_index
			zstack_tune_plotshifts,displayed_file_index
			wait,movie_delay
		ENDFOR
		movie_active = 0
		zstack_tune_sensitive
	END
	zstack_tune_par.display_parameters_label : BEGIN
		zstack_tune_desensitive
		wshow,zstack_tune_par.main_base_win,0
		zstack_display,'tune'
	END
	zstack_tune_par.plot_parameters_label : BEGIN
		zstack_tune_desensitive
		wshow,zstack_tune_par.main_base_win,0
		zstack_plot,'tune'
	END
	; Added to print eV locations of x and y shifts to Output Log, CGZ
	; Also updates display of image, corr_image, shifted_image and related text fields
	zstack_tune_par.shift_plot_label : BEGIN
		;; only act if alignment is complete, added, CGZ
		IF (doalign_complete GT 0) THEN BEGIN
		print,'doalign complete'
			;; only act on a down click of the mouse
			IF (event.type eq 0) THEN BEGIN
				wset,zstack_tune_par.shift_plot_win
				this_file_shift = convert_coord(event.x,event.y,/device,/to_data)
				this_file = this_file_shift(0)
					dummy = min(abs(this_file-file_num),this_i_file)
				print,'You clicked at File # '+$
					strtrim(string(file_num(this_i_file),format='(i3)'),2)+$
					', '+filename_display_list(this_i_file)+$
					', dx = '+strtrim(string(x_shift(this_i_file),format='(f10.2)'),2)+$
					', dy = '+strtrim(string(y_shift(this_i_file),format='(f10.2)'),2)
				displayed_file_index = (this_i_file>0)<(n_files-1)
				zstack_tune_imgdisp, displayed_file_index
				IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
					zstack_tune_corrdisp,displayed_file_index
				ENDIF
				zstack_tune_subimgdisp,displayed_file_index
				zstack_tune_plotshifts,displayed_file_index
			ENDIF
		ENDIF
	END
ENDCASE
return
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune_dialog, Group_Leader=groupLeader
;print,'zstack_tune_dialog'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

; Initialize variables if they have no value
;	needed when running zstack_align_dialog as stand-alone prior to running zstack_align
;	i.e., when programming dialog window
IF (n_elements(n_cols) EQ 0) THEN n_cols = 100
IF (n_elements(n_rows) EQ 0) THEN n_rows = 100
IF (n_elements(image_zoom) EQ 0) then image_zoom = 1
IF (n_elements(subimage_zoom) EQ 0) then subimage_zoom = 5
IF (n_elements(subimage_pixels) EQ 0) then subimage_pixels = 20
IF (n_elements(doalign_complete) EQ 0) then doalign_complete = 0
IF (n_elements(maxshift) EQ 0) then maxshift = 10
IF (n_tags(zstack_tune_par) EQ 0) THEN BEGIN
	zstack_tune_par = $
	   { zstack_tune_par				    , $
		main_base					: 0L, $
		display_list_label			: 0L, $
		this_imagetitle_label			: 0L, $
		this_imagecount_label			: 0L, $
		this_ev_label				: 0L, $
		this_wavelength_label			: 0L, $
		this_imageshift_label			: 0L, $
		pixel_dim_label				: 0L, $
		micron_dim_label			: 0L, $
		add_fiducial_label			: 0L, $
		reset_fiducial_label			: 0L, $
		add_edge_label				: 0L, $
		reset_edge_label			: 0L, $
		keep_new_label				: 0L, $
		keep_old_label				: 0L, $
		reset_label				: 0L, $
		this_image_label			: 0L, $
		corr_image_label			: 0L, $
		shift_image_label			: 0L, $
		colorbar_label				: 0L, $
		closeup_this_image_label		: 0L, $
		closeup_corr_image_label		: 0L, $
		closeup_shift_image_label		: 0L, $
		x_shift_init_label			: 0L, $
		x_shift_new_label			: 0L, $
		x_shift_slider_label			: 0L, $
		y_shift_init_label			: 0L, $
		y_shift_new_label			: 0L, $
		y_shift_slider_label			: 0L, $
		prev_image_label			: 0L, $
		next_image_label			: 0L, $
		play_movie_label			: 0L, $
		display_parameters_label		: 0L, $
		plot_parameters_label			: 0L, $
		shift_plot_label			: 0L, $
		main_base_win				: 0L, $
		this_image_win				: 0L, $
		corr_image_win				: 0L, $
		shift_image_win				: 0L, $
		colorbar_win				: 0L, $
		closeup_this_image_win		: 0L, $
		closeup_corr_image_win		: 0L, $
		closeup_shift_image_win		: 0L, $
		shift_plot_win				: 0L  $
	   }
     ENDIF
comp_screen_res=GET_SCREEN_SIZE()    ; need X_SCROLL_SIZE with keword /SCROLL for UNIX systems only !!

IF N_Elements(groupLeader) EQ 0 THEN BEGIN
	IF !version.os_family EQ 'Windows' then begin
		zstack_tune_par.main_base = widget_base(title='ZSTACK Tune Alignment', /row, /scroll, xoffset=100, yoffset=50)
	ENDIF else begin
		zstack_tune_par.main_base = widget_base(title='ZSTACK Tune Alignment', /row, /scroll, $
	           X_SCROLL_SIZE=comp_screen_res(0)*.90,Y_SCROLL_SIZE=comp_screen_res(1)*.90 )
	ENDELSE
ENDIF ELSE BEGIN
	zstack_tune_par.main_base = widget_base(title='ZSTACK Tune Alignment', /row, $    ; no keyword /SCROLL with /MODAL
			/Modal, Group_Leader=groupLeader )
ENDELSE
;zstack_tune_par.main_base = widget_base(title='ZSTACK Tune Alignment', /row, /scroll, $
;			xoffset=100, yoffset=50 )
			; use ofsets so that cw_defroi window will be apparent
col1 = widget_base(zstack_tune_par.main_base,/column)
col2 = widget_base(zstack_tune_par.main_base,/column)
base = widget_base(col1,/column,/frame,space=0)
row = widget_base(base,/row)
label = widget_label(row,value='X Alignment Shift:')
row = widget_base(base,/row)
label = widget_label(row, value='Initial :')
zstack_tune_par.x_shift_init_label = widget_text(row,xsize=9,value='')
label = widget_label(row, value='New :')
zstack_tune_par.x_shift_new_label = widget_text(row,xsize=9,/editable,value='')
zstack_tune_par.x_shift_slider_label = cw_fslider(base, /suppress_value, xsize=250, $
		maximum=maxshift, minimum=-maxshift, value=0.0)
base = widget_base(col1,/column,/frame,space=0)
row = widget_base(base,/row)
label = widget_label(row,value='Y Alignment Shift :')
row = widget_base(base,/row)
label = widget_label(row, value='Initial :')
zstack_tune_par.y_shift_init_label = widget_text(row,xsize=9,value='')
label = widget_label(row, value='New :')
zstack_tune_par.y_shift_new_label = widget_text(row,xsize=9,/editable,value='')
zstack_tune_par.y_shift_slider_label = cw_fslider(base, /suppress_value, xsize=250, $
		maximum=maxshift, minimum=-maxshift, value=0.0)
row = widget_base(col1,/row)
zstack_tune_par.display_list_label = widget_droplist( col1, $
			value = 'Select File', /align_center, scr_xsize=250);/dynamic_resize)
			;scr_xsize=150, scr_ysize=20)
zstack_tune_par.prev_image_label = widget_button(col1, value='Display Previous Image')
zstack_tune_par.next_image_label = widget_button(col1, value='Display Next Image')
zstack_tune_par.play_movie_label = widget_button(col1, value='Play movie')
row = widget_base(col1, /row,/align_center)
zstack_tune_par.display_parameters_label = widget_button(row,value='Display Parameters')
zstack_tune_par.plot_parameters_label = widget_button(row,value=' Plot  Parameters ')
row = widget_base(col1,/row)
frame = widget_base(col1,/col,/frame,xsize=260)
zstack_tune_par.add_fiducial_label = $
    widget_button(frame, value='Add Fiducial Points to Shifted Images')
zstack_tune_par.reset_fiducial_label = $
    widget_button(frame, value='Remove Fiducial Points')
;row = widget_base( frame, /row )
;zstack_tune_par.add_edge_label = $
;    widget_button(frame, value='Add Edge Outline to Shifted Images',xsize=270)
;row = widget_base( frame, /row )
;zstack_tune_par.reset_edge_label = $
;    widget_button(frame, value='Remove Edge Outline',xsize=270)

row = widget_base(col1,/row)
zstack_tune_par.keep_new_label   = $
	widget_button(col1,value='Keep new alignment -- Dashed Line')
zstack_tune_par.keep_old_label = $
	widget_button(col1,value='Keep old alignment -- Solid Line ')
zstack_tune_par.reset_label = $
	widget_button(col1,value='Reset Tune to old alignment')
frame = widget_base(col2,/col,/frame,/align_center)
base = widget_base(frame,/row,/align_center)
col2a = widget_base(base,/column)
label = widget_label(col2a, value='STXM Image',/align_center)
zstack_tune_par.this_image_label = $
  widget_draw(col2a,xsize=n_cols*image_zoom,ysize=n_rows*image_zoom,$
  retain=2,/button_events,/align_center)
zstack_tune_par.closeup_this_image_label = $
  widget_draw(col2a,xsize=subimage_pixels*subimage_zoom*image_zoom, $
  				ysize=subimage_pixels*subimage_zoom*image_zoom, $
  				retain=2,/button_events,/align_center)
IF (doalign_complete LE 1) THEN BEGIN		; don't plot if using manual alignment shifts or stored shift file
;IF ((doalign_complete NE 2) OR (n_elements(corr_stack) NE 1)) THEN BEGIN		; don't plot if using stored shift file
	col2b = widget_base(base,/column)
	label = widget_label(col2b, value='Correlation Fn',/align_center)
	zstack_tune_par.corr_image_label = widget_draw(col2b, $
			xsize=n_cols*image_zoom,ysize=n_rows*image_zoom,$
			retain=2,/button_events,/align_center)
	zstack_tune_par.closeup_corr_image_label = $
		widget_draw(col2b,xsize=subimage_pixels*subimage_zoom*image_zoom, $
  				ysize=subimage_pixels*subimage_zoom*image_zoom, $
				retain=2,/button_events,/align_center)
ENDIF
col2c = widget_base(base,/column)
label = widget_label(col2c, value='Shifted Image',/align_center)
zstack_tune_par.shift_image_label = widget_draw(col2c, $
			xsize=n_cols*image_zoom,ysize=n_rows*image_zoom, $
			retain=2,/button_events,/motion,/align_center)
zstack_tune_par.closeup_shift_image_label = widget_draw(col2c, $
			xsize=subimage_pixels*subimage_zoom*image_zoom, $
  			ysize=subimage_pixels*subimage_zoom*image_zoom, $
  			retain=2,/button_events,/motion,/align_center)
col2d = widget_base(base,/column)
label = widget_label(col2d, value='I',/align_center)
zstack_tune_par.colorbar_label = widget_draw(col2d, $
			xsize=10*(image_zoom>1),ysize=n_rows*image_zoom, $
 			retain=2, sensitive=0, /align_center)
label = widget_label(frame, value='Close-up Images')
label = widget_label(frame, value='Click on upper images to set center of close-up images')
row = widget_base(col2,/row,/align_center)
zstack_tune_par.shift_plot_label = $
		widget_draw(row,xsize=((3*n_cols*image_zoom+25)>250)<500, $
					ysize=((n_rows*image_zoom)>150)<250,retain=2,/button_events)
;zstack_tune_par.shift_plot_label = $
;		widget_draw(col2,xsize=(2*n_cols*image_zoom+35)>250, $
;					ysize=(n_rows*image_zoom)>150,retain=2,/button_events,/align_center)
;;;;;;;;;;
Device, get_screen_size=screen_size
screen_center = [ screen_size(0) / 2 , screen_size(1) / 2 ]
geom = Widget_Info(zstack_tune_par.main_base, /Geometry)
base_size = [geom.scr_xsize,geom.scr_ysize]
x_base_size = (fix(0.90*screen_size[0]) < base_size[0])
y_base_size = (fix(0.95*screen_size[1]) < base_size[1])
halfsize = [ x_base_size / 2 , y_base_size / 2 ]
widget_control, zstack_tune_par.main_base, $
	XOffset = screen_center[0] - halfsize[0], $
	YOffset = screen_center[1] - halfsize[1], $
	scr_xsize = x_base_size, $
	scr_ysize = y_base_size
widget_control, zstack_tune_par.main_base, /realize
zstack_tune_par.main_base_win = !d.window
widget_control,zstack_tune_par.this_image_label,get_value=window
zstack_tune_par.this_image_win = window
widget_control,zstack_tune_par.closeup_this_image_label,get_value=window
zstack_tune_par.closeup_this_image_win = window
IF (doalign_complete LE 1) THEN BEGIN		; don't plot if using manual alignment shifts or stored shift file
;IF ((doalign_complete NE 2) OR (n_elements(corr_stack) NE 1)) THEN BEGIN		; don't plot if using stored shift file
	widget_control,zstack_tune_par.corr_image_label,get_value=window
	zstack_tune_par.corr_image_win = window
	widget_control,zstack_tune_par.closeup_corr_image_label,get_value=window
	zstack_tune_par.closeup_corr_image_win = window
ENDIF
widget_control,zstack_tune_par.shift_image_label,get_value=window
zstack_tune_par.shift_image_win = window
widget_control,zstack_tune_par.closeup_shift_image_label,get_value=window
zstack_tune_par.closeup_shift_image_win = window
widget_control,zstack_tune_par.colorbar_label, get_value = window
zstack_tune_par.colorbar_win = window
widget_control,zstack_tune_par.shift_plot_label,get_value=window
zstack_tune_par.shift_plot_win = window
; make uneditable text widgets inactive
widget_control, zstack_tune_par.x_shift_init_label, sensitive = 0
widget_control, zstack_tune_par.y_shift_init_label, sensitive = 0
widget_control, zstack_tune_par.closeup_this_image_label, sensitive = 0
IF (doalign_complete LE 1) THEN BEGIN		; don't plot if using manual alignment shifts or stored shift file
	widget_control, zstack_tune_par.closeup_corr_image_label, sensitive = 0
ENDIF
widget_control, zstack_tune_par.closeup_shift_image_label, sensitive = 0
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO zstack_tune, new_zoom=new_zoom, Group_Leader=groupLeader
;print,'zstack_tune'

@bsif_common
@zstack_common
@zstack_analyze_common
@zstack_build_list_common
@zstack_align_common
@zstack_tune_common
@zstack_spectra_common
@zstack_profile_common
@zstack_save_common
@zstack_display_common
@zstack_color_common

on_error,2
IF NOT(keyword_set(new_zoom)) THEN BEGIN
	subimage_zoom = 4.0
	subimage_pixels = min([n_cols,n_rows])/subimage_zoom
	IF (subimage_pixels NE fix(subimage_pixels)) THEN BEGIN
		; if subimage_pixels is not an integer, round down to integer
		;	and erase display windows so edges will appear black
		subimage_pixels = floor(subimage_pixels)
	ENDIF
	; Create temporary files to keep shifts from previous auto / manual alignment
	; Use these to save shifts from interactive tuning until ready to keep or revert
	init_x_shift = x_shift
	init_y_shift = y_shift
	temp_x_shift = x_shift
	temp_y_shift = y_shift
ENDIF
fid_pt = 0
n_fid_pt = 0
all_fid_pt = 0
fid_pt_index = 0
;; Create temporary files to keep shifts from previous auto / manual alignment
;; Use these to save shifts from interactive tuning until ready to keep or revert
;init_x_shift = x_shift
;init_y_shift = y_shift
;temp_x_shift = x_shift
;temp_y_shift = y_shift
; set center of image windows - this is also center of subimage windows
;	this is the geometric center of all six image windows
image_center = [n_cols/2.,n_rows/2.]		; used to define the center of the image windows
corr_center = [n_cols/2.,n_rows/2.]		; used to draw the center of the correlation function area
shifted_center = [n_cols/2.,n_rows/2.]	; not used
; set center of closeup image - can be different from center of subimage window
;	selected using mouse position in image windows
subimage_center = [n_cols/2.,n_rows/2.]
subcorr_center = [n_cols/2.,n_rows/2.]
subshifted_center = [n_cols/2.,n_rows/2.]
zstack_tune_dialog, Group_Leader=groupLeader
widget_control, zstack_tune_par.display_list_label, set_value = filename_display_list
zstack_tune_sensitive
zstack_tune_imgdisp, displayed_file_index
IF (abs(doalign_complete) EQ 1) THEN BEGIN		; will only display if noy using stored shift file
	zstack_tune_corrdisp, displayed_file_index
ENDIF
zstack_analyze_colorbar, zstack_tune_par.colorbar_win
zstack_tune_subimgdisp, displayed_file_index
zstack_tune_plotshifts, displayed_file_index
xmanager, 'zstack_tune', zstack_tune_par.main_base, $
  group_leader = zstack_tune_par.main_base
return
end
