;Realse Note
;Author: Jiying Li, version 1.0
;Function:  For the BT7 a-axis powder mode data reduction. It can also be used to view the raw data
;collected under any modes using the psd
;

;***************************************************************
;The following function read the data for every psd channel
;Record the counting unit (time) or monitor
;It reads the independent variable and save it together with psd data
pro load_psd_data, event
	widget_control,event.top,get_uvalue = pstate
	varname = strupcase(['QX', 'QY', 'QZ', 'E', 'A3', 'A4','H','K','L','monitor','TEMP','Magfield','PsDet'])
	mypath=(*pstate).data_directory
	filename = dialog_pickfile(filter='*.bt7',title='Select your data file:',PATH=mypath)	
	print, filename
  if filename ne '' then begin
    try_read=dave_read_ice(filename,dstring = dstring,errmsg = errmsg)
  endif else begin
    return
  endelse
  if try_read eq 1 then begin
    widget_control, /hourglass
    try_parse=dave_parse_ice(dstring,dstruct    $
                            ,header=header_string $
                            ,indep_var_pos=indep_var_pos $
                            ,dep_var_pos=dep_var_pos $
                            ,lattice=lattice $
                            ,fixedEType=fixedEType $
                            ,fixedEValue=fixedEValue $
                            ,dSpaceM=dSpaceM $
                            ,dSpaceA=dSpaceA $
                            ,orientation=orientation $
                            ,sdesc=sdesc $
                            ,anaPkgStr=anaPkgStr $
                            ,errmsg = errmsg)
    ;print, 'anapkg', anapkgstr 
    if try_parse eq 0 then begin
      void = dialog_message(errmsg)
      return
    endif
    dstruct_members=tag_names(dstruct)
    ;print, 'tag names ', dstruct_members
    ch0=where(dstruct_members eq 'PSDC00')
    ch47=where(dstruct_members eq 'PSDC47')
    mon_pos=where(strlowcase(dstruct_members) eq 'monitor')
    mon_pos=mon_pos[0]
    mon=*dstruct.(mon_pos)
    (*pstate).unit=mon[0]
    temp_pos=where(strlowcase(dstruct_members) eq 'temp')
    magfield_pos=where(strlowcase(dstruct_members) eq 'magfield')
    nvar=n_elements(varname)
    npts=n_elements(*dstruct.(ch0))
    ;print, 'npts=',npts
    colname=dstruct_members(indep_var_pos)
    (*pstate).npoints=npts
    vardata=dblarr(nvar,(*pstate).npoints)
    for l=0,nvar-1 do begin
      var_pos=where(strlowcase(dstruct_members) eq strlowcase(varname(l)))
      if var_pos ne -1 then begin
        vardata(l,*)=*dstruct.(var_pos)
      endif
    endfor
   
    if  (*pstate).npoints lt 1 then begin
              void = dialog_message('The Data File is Empty!')
              return
    endif
    raw_data= dblarr(48,(*pstate).npoints)
    for j=0,47 do begin
      raw_data(j,*) = *dstruct.(j+ch0)
    endfor
    
  endif ; succesfully read file
 
  if strcmp(colname,'A4',/fold_case) || strcmp(colname,'TEMP',/fold_case) ||$
     strcmp(colname,'Magfield',/fold_case) then daxis_Ch_Eff, event
  if colname eq 'E'  then triaxis_Ch_Eff, event
  if colname eq 'PSDet' then daxis_Ch_Eff, event
  
 	*(*pstate).data = raw_data
 	*(*pstate).data_err = sqrt(raw_data)
	*(*pstate).vardata = vardata
	(*pstate).colname = colname
	*(*pstate).varname =varname
	(*pstate).ChBackGround=fltarr(48)
	(*pstate).filename=file_basename(filename)
	(*pstate).data_directory=FILE_DIRNAME(filename)
	(*pstate).working_directory=FILE_DIRNAME(filename)
	
	buttonvalue='Background Cleared'
	widget_control,(*pstate).Ch_BK_Button,set_value=buttonvalue
	sz = size(raw_data)
	if sz(0) eq 1 then nvars = 1 else nvars = sz[2]
	
  var_pos=where(strlowcase(varname) eq strlowcase('A4'))
  var_pos=var_pos[0]
  widget_control,(*pstate).A4begin,set_value=string(vardata(var_pos, 0))
  widget_control,(*pstate).A4end,set_value=string(vardata(var_pos, nvars-1))
  widget_control,(*pstate).var_slider,set_slider_max=nvars-1
  ;reset all the default values for the text box
  widget_control,(*pstate).Badch,set_value=''
	widget_control,(*pstate).A4step,set_value='0.1' 
	;erase all the data and background from the previous file
	widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Subtract Bkgd'
  widget_control,(*pstate).Subtract_File_Bg_Button,tooltip='subtract background file'
  (*pstate).File_Bg_Subtract_Flag = 0
	PSD_Ch_Plot,event
end ;Load_psd_data
;correct the intensity file for small A4 angle
pro PSD_Beamstop_Inensitycor, event

end;PSD_Beamstop_Inensitycor


;********************************************************
pro Exclude_PSD_Ch, event
	widget_control,event.top,get_uvalue = pstate
	widget_control,(*pstate).BadCh, get_value=BadCh
	if (*pstate).colname eq 'A4' || (*pstate).colname eq 'Temp' then daxis_Ch_Eff, event
  if (*pstate).colname eq 'E'  then triaxis_Ch_Eff, event
  if (*pstate).colname eq 'PSDet' then daxis_Ch_Eff, event
	if strlen(BadCh) gt 0 then begin
	  BadCh = strsplit(BadCh,',',/extract)
    for i=0,size(BadCh,/n_elements)-1 do	(*pstate).Ch_axis_Eff(fix(BadCh(i)))=0
  endif
end;Exclude_PSD_CH
;**********************************************
;this function does the channel efficience correction
pro daxis_Ch_Eff,event
	widget_control,event.top,get_uvalue = pstate
	Ch_Eff = fltarr(48)
	fn = (*pstate).psd_channel_eff
	print, 'daxis ',fn
	if (fn eq '') then channel_handler, event
  if fn eq '' then return 
	if fn ne '' then begin
		openr, fun, fn, /get_lun
		readf, fun, Ch_Eff
		free_lun, fun

	endif
   (*pstate).Ch_axis_Eff=Ch_Eff

end; Correct_data

;**********************************************
;this function does the channel efficience correction while using PSD
pro triaxis_Ch_Eff, event
	widget_control,event.top,get_uvalue = pstate
	Ch_dE = findgen(48)
	Ch_Eff = findgen(48)
	Ch_Eff = findgen(48)
	fn = (*pstate).psd_Ef_spacing
	if (fn eq '') then ef_handler, event
  if fn eq '' then return 
	if fn ne '' then begin
		openr, fun, fn, /get_lun
		readf, fun, Ch_dE,Ch_eff
		free_lun, fun
	endif
	(*pstate).Ch_axis_Eff=Ch_Eff
	(*pstate).Ch_Eng_Eff=Ch_dE
end; Correct_data


;***************************************************
;this function calculate the hkl for every psd channel in every step
;using the vardata file and the 2theta, E calibration data files
;the new hkl set for every channel is calculated using the algro from Igor
function scalarm, x1, y1, z1, x2, y2, z2,lattemp
	s=x1* x2*lattemp(0)^2+y1*y2*lattemp(1)^2+z1*z2*lattemp(2)^2+$
   		(x1*y2+x2*y1)*lattemp(0)*lattemp(1)*cos(lattemp(5))+$
   		(x1*z2+x2*z1)*lattemp(0)*lattemp(2)*cos(lattemp(4))+$
   		(z1*y2+z2*y1)*lattemp(2)*lattemp(1)*cos(lattemp(3))
	return, s
end;scalar

;calculate the reciprocal lattice parameter
function  star,lat
	V=2*lat(0)*lat(1)*lat(2)*sqrt(sin((lat(3)+lat(4)+lat(5))/2) * $
		sin((-lat(3)+lat(4)+lat(5))/2) * sin((lat(3)-lat(4)+lat(5))/2)*$
		sin((lat(3)+lat(4)-lat(5))/2))
	Vstar = (2*!PI)^3/V
	starlat = findgen(6)
	starlat[0] = 2*!pi*lat(1)*lat(2)*sin(lat(3))/V
	starlat[1] = 2*!pi*lat(0)*lat(2)*sin(lat(4))/V
	starlat[2] = 2*!pi*lat(1)*lat(0)*sin(lat(5))/V
	starlat[3] = acos((cos(lat(4))*cos(lat(5))-cos(lat(3)))/(sin(lat(4))*sin(lat(5))) )
	starlat[4] = acos((cos(lat(3))*cos(lat(5))-cos(lat(4)))/(sin(lat(3))*sin(lat(5))) )
	starlat[5] = acos((cos(lat(3))*cos(lat(4))-cos(lat(5)))/(sin(lat(3))*sin(lat(4))) )

	return, starlat
end; star function

function StandardSystem, lat,orient
	starlat = findgen(6)
	starlat = star(lat)
	orient1=findgen(3)
	orient2=findgen(3)
	orient1=orient(0:2)
	orient2=orient(3:5)
	modx = sqrt(scalarm(orient1(0),orient1(1),orient(2),orient1(0),orient1(1),orient(2),starlat))
	x=orient1/modx

	proj=scalarm(orient2(0),orient2(1), orient(2),x(0),x(1),x(2),starlat)
	y=orient2
	y=y-x*proj
	mody=sqrt(scalarm(y(0),y(1),y(2),y(0),y(1),y(2),starlat))
	if mody le 0 then begin
		void = dialog_message('Fatal error, orienting vectors are colinear!')
		return, 1
	endif
	y=y/mody
	z=y
	z(0)=x(1)*y(2)-y(1)*x(2)
	z(1)=x(2)*y(0)-y(2)*x(0)
	z(2)=x(0)*y(1)-y(0)*x(1)
	proj=scalarm(z(0),z(1),z(2),x(0),x(1),x(2),starlat)
	z(0)=z(0)-x(0)*proj
	z(1)=z(1)-x(1)*proj
	z(2)=z(2)-x(2)*proj
	proj=scalarm(z(0),z(1),z(2),y(0),y(1),y(2),starlat)
	z(0)=z(0)-y(0)*proj
	z(1)=z(1)-y(1)*proj
	z(2)=z(2)-y(2)*proj
	modz=sqrt(scalarm(z(0),z(1),z(2),z(0),z(1),z(2),starlat))
	z=z/modz
	q=[x,y,z]
	return,q
end;standardsystem

;****************************************************************
pro wherespectrometer, event,H=H,K=K,L=L,dE=dE
	widget_control,event.top,get_uvalue = pstate
	widget_control,(*pstate).PsdCenter, get_value=centerch
	centerch=fix(centerch)

	lat=findgen(6)
	orient=findgen(6)
	lat= (*pstate).lattice
	orient= (*pstate).orient
	lat(3:5)=!dtor*lat(3:5)
	Npn=(*pstate).npoints
	anatau=2*!PI/(*pstate).monspacing
	anatau=1.87325
	Ef=(*pstate).Ef
	Ef=14.7
	dE=(*(*pstate).vardata)(4,*)
	A3=!dtor*(*(*pstate).vardata)(5,*)
	A4=!dtor*(*(*pstate).vardata)(6,*)
	Ei=dE+Ef
	Efpsd=findgen(48)
	Ch_eff=findgen(48)
	dA4=findgen(48)
	fn = (*pstate).psd_Ef_spacing
	if (fn eq '') then ef_handler, event
  if fn eq '' then return 
	if fn ne '' then begin
		openr, fun, fn, /get_lun
		readf, fun, Efpsd,Ch_eff
		free_lun, fun
	endif
	Ki=sqrt(Ei/2.072142)
	Kfpsd=sqrt(Efpsd/2.072142)

	;calculate the difference between every channel to the center channel in A4
	for i=0,47 do dA4(i)=asin(anatau/2/Kfpsd(i))-asin(anatau/2/Kfpsd(centerch))
	A4=transpose(A4)#(fltarr(48)+1.)+(fltarr(Npn)+1.)#dA4
	A3=transpose(A3)#(fltarr(48)+1.)
	Ki=transpose(Ki)#(fltarr(48)+1)

	Kfpsd=(fltarr(Npn)+1)#Kfpsd
    M2 = 2*asin(anatau/(2*Ki))
   	A2 = 2*asin(anatau/(2*Kfpsd))
   	Q=sqrt(Ki^2+Kfpsd^2-2*Ki*Kfpsd*cos(A4))
	delta=abs(acos((Q^2+Ki^2-Kfpsd^2)/(2*Ki*Q)))
	psi=A3+delta-!pi/2
	qx=Q*cos(psi)
	qy=Q*sin(psi)
	unithkl=StandardSystem(lat,orient)

	unitH=unithkl(0:2)
	unitK=unithkl(3:5)
	unitL=unithkl(6:8)
	H=qx*unitH(0)+qy*unitK(0)
	K=qx*unitH(1)+qy*unitK(1)
	L=qx*unitH(2)+qy*unitK(2)
	Ei=transpose(Ei)#(fltarr(48)+1)
	Ef=(fltarr(Npn)+1)#Efpsd
  	dE=Ei-Ef

end;wherespectro
;********************************************************************
pro xstal3axis, event
	widget_control,event.top,get_uvalue = pstate
	widget_control,(*pstate).PsdCenter, get_value=centerch
	widget_control,(*pstate).PsdLeft, get_value=leftch
	widget_control,(*pstate).PsdRight, get_value=rightch
	wset,(*pstate).winpix
	chrange=indgen(3)
	chrange(0)=leftch
	chrange(1)=centerch
	chrange(2)=rightch
	Npn=(*pstate).npoints
   	data=(*(*pstate).data)
   	data=transpose(data)
   	wherespectrometer, event, H=H, K=K, L=L, dE=dE
   	;Now construct the data to one-dimensional array for using xplot3D
	usedch=abs(chrange(2)-chrange(0)+1)
	xdat=H(*,chrange(0):chrange(2))
	ydat=K(*,chrange(0):chrange(2))
	zdat=dE(*,chrange(0):chrange(2))
	idat=data(*,chrange(0):chrange(2))
	xdat=reform(xdat,usedch*Npn)
	ydat=reform(ydat,usedch*Npn)
	zdat=reform(zdat,usedch*Npn)
    idat=reform(idat,usedch*Npn)
   	device, decomposed=0
	loadct, 13
	zcolors=bytscl(idat,top=!D.N_colors-1)
	surface,dist(5),/Nodat,/save,xrange=[min(H),max(H)],yrange=[min(K),max(K)],zrange=[min(zdat),max(zdat)], $
		xstyle=1, ystyle=1, zstyle=1, charsize=2, color=!D.N_colors-1,xtitle='H',ytitle='K',ztitle='dE'
	plots,xdat,ydat,zdat,psym=4,color=zcolors,symsize=1,/T3D

	(*pstate).xdata = ptr_new(xdat)
	(*pstate).ydata = ptr_new(ydat)
	*(*pstate).stitchdata = zdat
	(*pstate).intdata = ptr_new(idat)
  wset,(*pstate).winvis
  device, copy=[0,0,500,500,0,0,(*pstate).winPix] ; 
 	;tmp = obj_new('dm_plot',xdat,ydat,zdat,idat,/surfplot)
  ;tmp->draw

end; xstal3axis
;*****************************************************************************
function bw2rgb2,grey,noscale=noscale
; grey is an array of gray scale colors
; returns a floating point array, 3 x N
; /noscale indicates grey values are between 0 and 1, and don't need
; to be scaled (default rescales grey array to floats between 0 and 1)

g=bytarr(256)
g(97:162)=255b
g(97-64:96)=indgen(64)*4
g(163:163+63)=252b-indgen(64)*4
r=shift(g,66)
b=shift(g,-66)

if keyword_set(noscale) then begin
	red=interpolate(r,255.99*grey)
	green=interpolate(g,255.99*grey)
	blue=interpolate(b,255.99*grey)
endif else begin
	maxg=max(grey)
	ming=min(grey)
	if maxg ne ming then begin
		scaleg=1.0/(maxg-ming)
	endif else begin
		message,'warning: all the same color, unpredictable results.',/inf
		scaleg=1.0
	endelse
	i=(255.99*(grey-ming)*scaleg)
	red=r(i) & green=g(i) & blue=b(i)
	red=interpolate(r,i)
	green=interpolate(g,i)
	blue=interpolate(b,i)
endelse

; this helps solve problems if 'grey' is higher dimensional
; (although it doesn't actually do what we'd like, which is to
; generate a 3 x whatever x whatever... array.)
result=fltarr(3,n_elements(grey))
result(0,*)=red/255.0
result(1,*)=green/255.0
result(2,*)=blue/255.0

return,result
end
;****************************************************
pro PSD_cleanup,tlb
	widget_control,tlb,get_uvalue = pstate
	wdelete,(*pstate).winpix
	ptr_free, (*pstate).data, (*pstate).stitchdata, (*pstate).vardata
	ptr_free, (*pstate).xdata, (*pstate).ydata, (*pstate).errdata, (*pstate).zdata
	ptr_free, (*pstate).xptr, (*pstate).yptr, (*pstate).intdata, (*pstate).daveptr
	heap_free,pstate
end
;**************************************
pro PSD_event,event
	uname = widget_info(event.id,/uname)
	if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'Display1D: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        ;eMsg = [eMsg,'Function/module name: calledfunc()',!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
  endif
	;the error handler	
	case uname of
		'LoadDat': Load_psd_data, event
		'QUIT':  widget_control,event.top,/destroy
		'PSD_CH': 	PSD_Ch_Plot,event
		'VAR':		PSD_Var_Plot, event
		'Ch_BKGD': Set_variable_bkgd, event
		'ExcludeCh':Exclude_PSD_Ch,event
		'SUM': 	PSD_Sum_Plot, event
		'STICH': PSD_Stitch_Plot, event
		'SaveStich': Save_PSD_Data, event
		'WIN': Psd_plot_refresh, event
		'file_bkgd': PSD_add_remove_file_bg, event
    'subtract_bkgd': PSD_subtract_clear_file_bg, event
	else:
	endcase
end
;*****************************************
;Plot the each channel vs the independent variable
pro PSD_Ch_Plot,event
	widget_control,event.top,get_uvalue = pstate
	datasize = size(*((*pstate).data))
	if datasize(1) le 0 then begin
    void = dialog_message('The Data File is Empty!')
    return
  endif
  Exclude_PSD_Ch, event
	Ch_Eff=findgen(48)
	varname=*(*pstate).varname
	(*pstate).plottype=0
	colname=(*pstate).colname
  var_pos=where(strlowcase(varname) eq strlowcase(colname))
  var_pos=var_pos[0]
	Ch_Eff=(*pstate).Ch_axis_Eff
	widget_control,(*pstate).ch_slider, get_value=slval
	vardata = *((*pstate).vardata)
	final_data = *((*pstate).data)
	x = vardata(var_pos,*)
	y = final_data(slval,*)*Ch_Eff(slval)
	yerr= (*(*pstate).data_err)
	yerr=yerr[slval,*]*Ch_Eff(slval)
	(*pstate).plot_title = (*pstate).filename+': '+'PSD channel Plot, Channel = '   $
	 		+strtrim(string(slval,format = '(I3)'),2)
	(*pstate).xtitle = (*pstate).colname
	(*pstate).ytitle = 'Intensity ( '+ string(strtrim((*pstate).unit, 2))+'  / '+(*pstate).unitname +' )'
	;wset,(*pstate).winpix
	*(*pstate).xdata = x
	*(*pstate).ydata = y
	*(*pstate).errdata = yerr
	*(*pstate).zdata = y
  PSD_Plot_graphs, pstate
  wset,(*pstate).winvis
  device, copy=[0,0,700,700,0,0,(*pstate).winpix] ; 
	;(*pstate).imageflage = 1
	sz=size(x)
	xrdata=fltarr(3,sz(2))
	xrdata[0,*]=x
	xrdata[1,*]=y
	xrdata[2,*]=yerr
	*(*pstate).stitchdata = xrdata
  widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Subtract Bkgd'
  widget_control,(*pstate).Subtract_File_Bg_Button,tooltip='subtract background file'
  (*pstate).File_Bg_Subtract_Flag = 0
end; PSD_Ch_Plot
;*******************************************************
;Plot all the psd channel at each indeendent variable step
pro PSD_Var_Plot,event
	widget_control,event.top,get_uvalue = pstate
	
  if  not ptr_valid(pstate) then begin
    return
  endif
	Ch_Eff = fltarr(48)
	if not ptr_valid((*pstate).data) then return
  Exclude_PSD_Ch, event
	Ch_Eff=(*pstate).Ch_axis_Eff
	datasize = size(*((*pstate).data))
	if datasize(1) le 0 then begin
		void = dialog_message('The Data File is Empty!')
		return
	endif
	widget_control,(*pstate).var_slider, get_value=slval
	widget_control,(*pstate).PsdCenter, get_value=centerch
	If (*pstate).Ch_Bg_Flage eq 0 then begin
    buttonvalue='Set step '+ string(strtrim(slval,2)) +' Bkgd'
    widget_control,(*pstate).Ch_BK_Button,set_value=buttonvalue
  endif 
  If (*pstate).Ch_Bg_Flage eq 1 then begin
    buttonvalue='Var '+string(strtrim(slval,2)) +': Clear Bkgd'
    widget_control,(*pstate).Ch_BK_Button,set_value=buttonvalue
  endif 
  if centerch lt 0 || centerch gt 47 then centerch =23
	x = findgen(48)
	final_data = *((*pstate).data)
	final_data_err = *((*pstate).data_err)
	vardata = *((*pstate).vardata)
	sz=size(final_data)
  if slval ge sz(2) then slval = sz(2)-1
  y = (final_data(*,slval))*Ch_Eff
  yerr = (final_data_err(*,slval))*Ch_Eff
  
	varname=*(*pstate).varname
  colname=(*pstate).colname
  var_pos=where(strlowcase(varname) eq strlowcase('A4'))
  var_pos=var_pos[0]
  indep_pos=where(strlowcase(varname) eq strlowcase(colname))
  indep_pos=indep_pos[0]  
	A4=(*(*pstate).vardata)(var_pos,slval)
	ch_space=findgen(48)
	ch_position=findgen(48)
	fn = (*pstate).PSD_A4_Spacing
	if (fn eq '') then a4_handler, event
  if fn eq '' then return 
	openr, fun, fn, /get_lun
	readf, fun, ch_position
	free_lun, fun
	;Now calculate the spacing between every channel and the specified center channel
	;for k = 0, 47 do begin
	;	ch_space(k) = ch_position(fix(centerch))-ch_position(k)+A4
	;endfor
	ch_space=(ch_position(fix(centerch)))[0]-ch_position+A4
	*(*pstate).xdata = ch_space
	*(*pstate).ydata = y
	*(*pstate).errdata = yerr
	xrdata=fltarr(3,48)
	xrdata[0,*]=ch_space
	xrdata[1,*]=y
	xrdata[2,*]=yerr
 	*(*pstate).stitchdata = xrdata
	minx = min(ch_space, max=maxx)
	miny = min(y, max=maxy)
	(*pstate).plot_title = (*pstate).filename+': '+'PSD Variable Plot,'$
		 +strtrim(string((*pstate).colname), 2) + ' = ' $
	     +strtrim(string(vardata(indep_pos,slval),format = '(f10.3)'),2)
	(*pstate).xtitle = 'A4 '
	(*pstate).ytitle ='Neutron ( '+ string(strtrim((*pstate).unit, 2))+'/'+(*pstate).unitname +' )'
	(*pstate).plottype = 1
	PSD_Plot_graphs, pstate
	wset,(*pstate).winvis
  device, copy=[0,0,700,700,0,0,(*pstate).winPix] ; 
  widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Subtract Bkgd'
  widget_control,(*pstate).Subtract_File_Bg_Button,tooltip='subtract background file'
  (*pstate).File_Bg_Subtract_Flag = 0
end;PSD_Var_Plot
;**********************************************************
; This function will set all the channels at certain variable as the background
pro Set_variable_bkgd, event
  widget_control,event.top,get_uvalue = pstate
  widget_control,(*pstate).var_slider, get_value=slval
  datasize = size(*((*pstate).data))
  if datasize(1) le 0 then begin
    void = dialog_message('The Data File is Empty!')
    return
  endif
  bkgd=0
  final_data = *((*pstate).data)
  final_data_err = *((*pstate).data_err)
  switch (*pstate).Ch_Bg_Flage of 
    0: begin
      buttonvalue='Var: '+ string(strtrim(slval,2)) +' is set as Bkgd'
      widget_control,(*pstate).Ch_BK_Button,set_value=buttonvalue
      (*pstate).ChBackGround = final_data(*,slval)
      (*pstate).Ch_Bg_Flage =1
      sz=size(final_data)
      ones=fltarr(sz[2])+1
      background_2d=(*pstate).ChBackGround#ones
      (*(*pstate).data)=final_data-background_2d
      (*(*pstate).data_err)=sqrt(final_data_err^2+background_2d)
      
      bkgd=slval
      break
      end
    1: begin
      buttonvalue='Background Cleared'
      widget_control,(*pstate).Ch_BK_Button,set_value=buttonvalue
      sz=size(final_data)
      ones=fltarr(sz[2])+1  
      background_2d=(*pstate).ChBackGround#ones
      (*(*pstate).data)=final_data+background_2d
      (*(*pstate).data_err)=sqrt(final_data_err^2-background_2d)
      (*pstate).ChBackGround = 0
      (*pstate).Ch_Bg_Flage =0 
      end
  endswitch

end;Set_variable_bkgd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro PSD_add_remove_file_bg, event
  widget_control,event.top,get_uvalue = pstate
  widget_control,(*pstate).PsdCenter, get_value=centerch
  widget_control,(*pstate).PsdLeft, get_value=leftch
  widget_control,(*pstate).PsdRight, get_value=rightch
  widget_control,(*pstate).BadCh, get_value=BadCh
  datasize = size((*(*pstate).data))
  if datasize(1) le 0 then begin
    void = dialog_message('There is no data file loaded!')
    return
  endif
  switch (*pstate).File_Bg_Flag of 
    0: begin
     (*pstate).bkgd_filename = (*pstate).filename
      widget_control,(*pstate).Set_File_Bg_Button,set_value='Remove File Bkgd'
      str='Current Background File - '+string(strtrim((*pstate).bkgd_filename,2))
      widget_control,(*pstate).Set_File_Bg_Button,tooltip=str
      if ptr_valid((*pstate).bkgd_xdata) then ptr_free,(*pstate).bkgd_xdata, (*pstate).bkgd_ydata, (*pstate).bkgd_errdata
      npts=n_elements(*(*pstate).xdata)
      xdata=dblarr(npts)
      ydata=dblarr(npts)
      errdata=dblarr(npts)
      xdata=*(*pstate).xdata
      ydata=*(*pstate).ydata
      errdata=*(*pstate).errdata
      (*pstate).bkgd_xdata=ptr_new(xdata)
      (*pstate).bkgd_ydata = ptr_new(ydata)
      (*pstate).bkgd_errdata = ptr_new(errdata)
      (*pstate).bkgd_colname = (*pstate).colname
      (*pstate).bkgd_unit = (*pstate).unit
      (*pstate).bkgd_chrange(0) = leftch
      (*pstate).bkgd_chrange(1) = centerch
      (*pstate).bkgd_chrange(2) = rightch
      (*pstate).bkgd_badch = Badch
      (*pstate).File_Bg_Flag =1
      break
      end
    1: begin
      if  (*pstate).File_Bg_Subtract_Flag eq 0 then begin
        widget_control,(*pstate).Set_File_Bg_Button,set_value='Set File Bkgd'
        widget_control,(*pstate).Set_File_Bg_Button,tooltip='Set Current File as Background'
        if ptr_valid((*pstate).bkgd_xdata) then ptr_free, (*pstate).bkgd_xdata, (*pstate).bkgd_ydata, (*pstate).bkgd_errdata
        (*pstate).File_Bg_Flag = 0
        (*pstate).bkgd_unit = 0
        (*pstate).bkgd_colname = ''
        (*pstate).bkgd_badch = ''
        break
      endif else begin
        void = dialog_message('Please clear the background subtraction first!')
        return
      endelse
      end
  endswitch
  print, (*pstate).File_Bg_Flag

end; add or remove file background
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro PSD_subtract_clear_file_bg, event
  widget_control,event.top,get_uvalue = pstate
  widget_control,(*pstate).PsdCenter, get_value=centerch
  widget_control,(*pstate).PsdLeft, get_value=leftch
  widget_control,(*pstate).PsdRight, get_value=rightch
  widget_control,(*pstate).BadCh, get_value=BadCh
  range=indgen(3)
  range(0) = leftch
  range(1) = centerch
  range(2) = rightch
  datasize = size((*(*pstate).data))
  if (*pstate).File_Bg_Flag eq 0 then begin
    void = dialog_message('There is no background file has been selected!')
    return
  endif
  switch (*pstate).File_Bg_Subtract_Flag of 
    0: begin
      if ~array_equal(range, (*pstate).bkgd_chrange) then begin
        text = 'Please use the channel left: '+ string(strtrim((*pstate).bkgd_chrange(0),2)) + ' center: '+$
                string(strtrim((*pstate).bkgd_chrange(1),2))+' right: '+string(strtrim((*pstate).bkgd_chrange(2),2))
        void = dialog_message(text)
        return
      endif
      if ~strcmp(Badch, (*pstate).bkgd_badch) then begin
        text = 'Please excluded the channels as background: '+ string(strtrim((*pstate).bkgd_badch,2))
        void = dialog_message(text)
        return
      endif
      (*pstate).File_Bg_Subtract_Flag =1
      if (*pstate).File_Bg_Flag eq 1 and (*pstate).File_Bg_Subtract_Flag eq 1 and $
          (*pstate).bkgd_colname eq (*pstate).colname  then begin
          ratio =float((*pstate).unit)/float((*pstate).bkgd_unit)
          if array_equal(size(*(*pstate).xdata),size(*(*pstate).bkgd_ydata)) then begin
            (*(*pstate).ydata) = (*(*pstate).ydata)-(*(*pstate).bkgd_ydata)*ratio
            (*(*pstate).errdata) = sqrt((*(*pstate).errdata)^2 + (*(*pstate).bkgd_errdata)^2*ratio)
            (*pstate).plot_title = (*pstate).filename +' - '+(*pstate).bkgd_filename +'  Plot' 
          endif else begin
            void=dialog_message('The current file either has different A4 range or different A4 step from the background file!')
            (*pstate).File_Bg_Subtract_Flag =0
            return
          endelse  
      endif
      widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Clear Subtraction'
      str='Currently Subtracted File - '+string(strtrim((*pstate).bkgd_filename,2))
      widget_control,(*pstate).Subtract_File_Bg_Button,tooltip=str
     (*pstate).plottype = 0
      PSD_Plot_graphs, pstate
      break
      end
    1: begin
      widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Subtract Bkgd'
      widget_control,(*pstate).Subtract_File_Bg_Button,tooltip='subtract background file'
     (*pstate).File_Bg_Subtract_Flag = 0
     if (*pstate).File_Bg_Flag eq 1 then begin
         ratio =float((*pstate).unit)/float((*pstate).bkgd_unit)
         (*(*pstate).ydata) = (*(*pstate).ydata)+(*(*pstate).bkgd_ydata)*ratio
         (*(*pstate).errdata) = sqrt((*(*pstate).errdata)^2 - (*(*pstate).bkgd_errdata)^2*ratio)
         (*pstate).plot_title = (*pstate).filename + ' Plot' 
     endif
     (*pstate).plottype = 0
      PSD_Plot_graphs, pstate
      break
      end
  
  endswitch
  wset,(*pstate).winvis
  device, copy=[0,0,700,700,0,0,(*pstate).winPix] ; 
  ;xrdata = dblarr(3, output_npt)
  (*(*pstate).stitchdata)(0,*) = (*(*pstate).xdata)
  (*(*pstate).stitchdata)(1,*) = (*(*pstate).ydata)
  (*(*pstate).stitchdata)(2,*) = (*(*pstate).errdata)
  ;xrdata(1,*) = output_data(0:output_npt-1)
  ;xrdata(2,*) = output_data_err(0:output_npt-1)
  ;*(*pstate).stitchdata = xrdata
end; PSD subtract or clear the file background



;**********************************************************
;Plot the sum of all the psd channel at each independent variable step
pro PSD_Sum_Plot, event
	widget_control,event.top,get_uvalue = pstate
	datasize = size(*((*pstate).data))
	if datasize(1) le 0 then begin
		void = dialog_message('The Data File is Empty!')
		return
	endif
	widget_control,(*pstate).PsdLeft, get_value=leftch
	widget_control,(*pstate).PsdRight, get_value=rightch
	if leftch eq '' || rightch eq '' then begin
    void = dialog_message('Please specify the channels want to use')
    return
  endif
  Exclude_PSD_Ch, event
	Ch_Eff=findgen(48)
	Ch_Eff=(*pstate).Ch_axis_Eff

	minch=leftch
	maxch=rightch
	range=indgen(2)
	range(0) = fix(leftch)
	range(1) = maxch
	if range(0) lt 0 || range(0) gt 47 then begin
		void = dialog_message('The left of the PSD is out of [0 47], set to default value [0 47]')
		range(0) = 0
		range(1) = 47
		widget_control,(*pstate).PsdLeft,set_value = '0'
		widget_control,(*pstate).PsdRight,set_value = '47'
	endif
	if range(1) lt range(0) || range(1) gt 47 then begin
		void = dialog_message('The left of the PSD is greater right, set default value to [0 47]')
		widget_control,(*pstate).PsdLeft,set_value = '0'
		widget_control,(*pstate).PsdRight,set_value = '47'
		range(0) = 0
		range(1) = 47
	endif
	data=(*(*pstate).data)
	data_err=(*(*pstate).data_err)
	vardata=(*(*pstate).vardata)
	sz=size(data)
	y=fltarr(sz(2))
	yerr=fltarr(sz(2))
	varname=*(*pstate).varname
	colname=(*pstate).colname
  var_pos=where(strlowcase(varname) eq strlowcase(colname))
  var_pos=var_pos[0]
	x = vardata(var_pos,*)
	;for i=0, sz(2)-1 do begin
	;	sum=0
	;	sumerr=0
	;	for j = range(0), range(1) do begin
	;		sum=sum+(data(j,i))*Ch_Eff(j)
	;		sumerr=sumerr+(data_err(j,i)^2)*Ch_Eff(j)^2
	;	endfor
	;	y(i)=sum
	;	yerr(i)=sqrt(sumerr)
	;endfor
  sz=size(data)
  ones=fltarr(sz[2])+1
  Ch_Eff_2d=Ch_Eff#ones
	y=total(data[range[0]:range[1],*]*Ch_eff_2d[range[0]:range[1],*],1)
	yerr=total(data_err[range[0]:range[1],*]^2*Ch_eff_2d[range[0]:range[1],*]^2,1)
	yerr=sqrt(yerr)
	wset,(*pstate).winpix
	(*pstate).plot_title =(*pstate).filename+': '+ string('Sum of the PSD Channel')
	(*pstate).xtitle = (*pstate).colname
	(*pstate).ytitle = 'Intensity ( '+ string(strtrim((*pstate).unit, 2))+'  / '+(*pstate).unitname +' )'
	minx = min(x, max=maxx)
	miny = min(y, max=maxy)
	*(*pstate).xdata = x
	*(*pstate).ydata = y
	*(*pstate).errdata = yerr
	xrdata=fltarr(3,fix(sz(2)))
	xrdata[0,*]=x
	xrdata[1,*]=y
	xrdata[2,*]=yerr
	*(*pstate).stitchdata = xrdata
	(*pstate).plottype =0
	PSD_Plot_graphs, pstate

	wset,(*pstate).winvis
  device, copy=[0,0,700,700,0,0,(*pstate).winPix] ; 
  widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Subtract Bkgd'
  widget_control,(*pstate).Subtract_File_Bg_Button,tooltip='subtract background file'
  (*pstate).File_Bg_Subtract_Flag = 0
end;PSD_Sum_Plot
;******************************************************
; This code will rebin the data regarding to A4. the channel spacing is read out from
; and data file. The output is a equal step 0.1 data file with A4 between the specified
; A4 minimium and A4 maximum. (The data points from the first front half of the psd and
; the last step of rear psd is removed.


pro PSD_Stitch_Plot, event
	widget_control,event.top,get_uvalue = pstate
	widget_control,(*pstate).A4begin, get_value=A4begin
	widget_control,(*pstate).A4end, get_value=A4end
  widget_control,(*pstate).A4step, get_value=A4step
  
	datasize = size(*((*pstate).data))
	if datasize(1) le 0 then begin
		void = dialog_message('The Data File is Empty!')
		return
	endif
	widget_control,(*pstate).PsdCenter, get_value=centerch
	widget_control,(*pstate).PsdLeft, get_value=leftch
	widget_control,(*pstate).PsdRight, get_value=rightch
  if centerch eq '' || leftch eq '' || rightch eq '' then begin
    void = dialog_message('Please specify the used channels and the center channel')
    return
  endif
	range=indgen(3)
	range(0) = leftch
	range(1) = centerch
	range(2) = rightch
	if range(1) lt 0 || range(1) gt 47 then begin
		void = dialog_message('The center of the PSD is out of [0 47], set to default value [0 23 47]')
		widget_control,(*pstate).PsdCenter,set_value = '23'
		widget_control,(*pstate).PsdLeft,set_value = '0'
		widget_control,(*pstate).PsdRight,set_value = '47'
		range(0) = 0
		range(1) = 23
		range(2) = 47
	endif
	if range(0) ge range(2) || range(0) lt 0 || range(0) gt 47 then begin
		void = dialog_message('The left of the PSD is greater center, set default value to [0 23 47]')
		widget_control,(*pstate).PsdCenter,set_value = '23'
		widget_control,(*pstate).PsdLeft,set_value = '0'
		widget_control,(*pstate).PsdRight,set_value = '47'
		range(0) = 0
		range(1) = 23
		range(2) = 47
	endif
	if range(2) lt range(0) || range(2) lt 0 || range(2) gt 47 then begin
		void = dialog_message('The left of the PSD is greater than the right, set default value to 0, 47')
		widget_control,(*pstate).PsdCenter,set_value = '23'
		widget_control,(*pstate).PsdLeft,set_value = '0'
		widget_control,(*pstate).PsdRight,set_value = '47'
		range(0) = 0
		range(1) = 23
		range(2) = 47
	endif
  Exclude_PSD_Ch, event
	Ch_eff=findgen(48)
	Ch_eff=(*pstate).Ch_axis_Eff
	if (*pstate).colname eq 'A4' then begin
		data = (*(*pstate).data)
		var =(*(*pstate).vardata)
		sz = size(data)
		data_err = dindgen(sz(1), sz(2))
		data_err = sqrt(data)
		varname=*(*pstate).varname
		colname=(*pstate).colname
    var_pos=where(strlowcase(varname) eq strlowcase('A4'))
    var_pos=var_pos[0]
    ;Now open the A4 spacing calibration file and readout
    ch_position = fltarr(48)
    fn = (*pstate).PSD_A4_Spacing
    if (fn eq '') then a4_handler, event
    if fn eq '' then return 
    if fn ne '' then begin
      openr, fun, fn, /get_lun
      readf, fun, ch_position
      free_lun, fun
    endif
    ;Now calculate the spacing between every channel and the specified center channel
    ch_space=ch_position(range(1))-ch_position
    ch_space_extend=fltarr(49)
    ch_space_extend(0:47)=ch_space
    ch_space_extend(48)=ch_space_extend(47)
    ch_space=ch_space_extend
    ; After align the middle of PSD with the every A4 position and then build
    ; the left and right coordinate for every psd position
    ch_left = dblarr(49)
    ch_right =dblarr(48)
    A4range = findgen(3)
    A4range(0) = float(A4begin)
    A4range(1) = float(A4end)
    A4range(2) = float(A4step)
    A4_begin = A4range(0)
    A4_end = A4range(1)
    output_width = A4range(2)
		;if A4_begin ge A4_end then begin
		;	void = dialog_message('The beginning A4 should be smaller than the A4 end !')
		;	return
		;endif
		output_npt = fix(round(abs(A4_end-A4_begin)/output_width))
		output_data = dblarr(output_npt)
		data_norm=dblarr(output_npt)+1
		output_data_err = dblarr(output_npt)
		output_data_left = findgen(output_npt+1)
		output_data_right = findgen(output_npt)
		;data_plus_count = findgen(output_npt)
		dis = dblarr(48, output_npt)
		frac = dblarr(48, output_npt)
		z_in = dblarr(48)
		dz_in = dblarr(48)
		output_data_left=min([A4_begin,A4_end])+output_data_left*output_width
		
		output_data_left(output_npt) = max([A4_begin,A4_end])
		output_data_right = output_data_left(1:output_npt)
		
		data_plus_count=dblarr(output_npt)
		mon_in=ch_left(0:47)+1.0
		for l=0,47 do begin
			if Ch_eff(l) lt 1E-2 then begin
			mon_in(l)=0
			endif
		endfor ; for
		output_tmp=data_plus_count
		dz_output_tmp=data_plus_count
		output_mon=data_plus_count
		dz_output_mon=data_plus_count
		;print,'sz=',sz(2)
		widget_control, /hourglass
		for i = 0, sz(2)-1 do begin
			
			ch_left=ch_space+0.5*(-ch_space+shift(ch_space,1))+var(var_pos,i)
			ch_left(0) = ch_space(0) + 0.5*(ch_space(0) - ch_space(1)) +var(var_pos, i)
			ch_left(48) = ch_space(47) - 1.0*(ch_space(46)-ch_space(47)) + var(var_pos, i)
			ch_right = ch_left(1:48)
			z_in = data(*, i)*Ch_eff
			dz_in = data_err(*,i)*Ch_eff
			;help,ch_left, z_in,dz_in,output_data_left
			ch_left=reverse(ch_left)
			z_in=reverse(z_in)
			dz_in=reverse(dz_in)
			;output_data_left=reverse(output_data_left)
			drebin,ch_left[range[0]:range[2]+1],z_in[range[0]:range[2]],dz_in[range[0]:range[2]],output_data_left,output_tmp,dz_output_tmp,/histogram,/to_histogram,err=err,emsg=emsg
			print, emsg
			drebin,ch_left[range[0]:range[2]+1],mon_in[range[0]:range[2]],mon_in[range[0]:range[2]],output_data_left,output_mon,dz_output_mon,/histogram,/to_histogram,err=err,emsg=emsg
			output_data=output_data+output_tmp*output_mon
			output_data_err=output_data_err+dz_output_tmp^2*output_mon^2
			data_norm=data_norm+output_mon
		endfor; i
		output_data=output_data/data_norm
		output_data_err=sqrt(output_data_err)/data_norm
		
		xrdata = dblarr(3, output_npt)
		xrdata(0,*) = output_data_left(0:output_npt-1)
		xrdata(1,*) = output_data(0:output_npt-1)
		xrdata(2,*) = output_data_err(0:output_npt-1)
		*(*pstate).stitchdata = xrdata
		wset,(*pstate).winpix
		minx = min(xrdata(0,*), max=maxx)
		miny = min(xrdata(1,*), max=maxy)
		(*pstate).xdata = ptr_new(xrdata(0,*))
		(*pstate).ydata = ptr_new(xrdata(1,*))
		(*pstate).errdata = ptr_new(xrdata(2,*))
		(*pstate).plot_title = (*pstate).filename+': '+(*pstate).colname +' Stitch Plot' 
		(*pstate).xtitle = (*pstate).colname
		(*pstate).ytitle = 'Intensity ( '+ string(strtrim((*pstate).unit, 2))+' / '+(*pstate).unitname +' )'
		(*pstate).plottype =0
    PSD_Plot_graphs, pstate
		
		wset,(*pstate).winvis
    device, copy=[0,0,700,700,0,0,(*pstate).winPix] ; 
	endif; for A4

	;now deal with the situation for single crystal Ei scan
	if (*pstate).colname eq 'E' then begin
		xstal3axis, event
	
	endif; for independent variable is E
	;Now deal with the independent is temperature situation
	if (*pstate).colname eq 'Temp' then begin
	endif;while independent variable is temp
  widget_control,(*pstate).Subtract_File_Bg_Button,set_value='Subtract Bkgd'
  widget_control,(*pstate).Subtract_File_Bg_Button,tooltip='subtract background file'
  (*pstate).File_Bg_Subtract_Flag = 0

end; Rebin_PSD_Data
;*************************************************
; used to save the XRD pattern
pro Save_PSD_Data, event
	widget_control,event.top,get_uvalue = pstate
	datasize = size(*((*pstate).stitchdata))
	if datasize(1) le 0 then begin
		void = dialog_message('The Stitched Data File is Empty!')
		return
	endif
	xrdata = (*(*pstate).stitchdata)
	mypath=(*pstate).working_directory
	str1=strsplit((*pstate).filename, '.',/extract)
	if str1[0] ne '' then	tempfile = str1[0] else tempfile = 'filename'
	fn = dialog_pickfile(filter='*.dat', default_extension='dat',/write, title='Select the data file to save XRD pattern:',path=mypath, $
	                      file=tempfile, /overwrite_prompt)
  if (*pstate).colname eq 'A4' then begin
    if fn ne '' then begin
       	openw,lun,fn,/get_lun
	   		printf,lun,xrdata
	   		free_lun,lun
		endif
	endif
	if (*pstate).colname eq 'E' then begin
	   if fn ne '' then begin
       		openw,lun,fn,/get_lun
       		printf, lun, 'X	','Y ','Z	', 'Intensity'
       		sz=size((*(*pstate).xdata))
       		for i=0, sz(1)-1 do printf,lun,(*(*pstate).xdata)(i),(*(*pstate).ydata)(i), (*(*pstate).stitchdata)(i),(*(*pstate).intdata)(i)
	   		free_lun,lun
		endif
	endif; for independent variable is E
	;print ,(*pstate).colname
	if strlowcase((*pstate).colname) eq 'temp' then begin
   		if fn ne '' then begin
       		openw,lun,fn,/get_lun
	   		printf,lun,xrdata
	   		free_lun,lun
	   		;print ,'saved ', fn
		endif
	endif
end;save_psd_data


; used to save data in dave format

pro psd_export_to_dave_dave_handler, event
  widget_control,event.top,get_uvalue = pstate
  datasize = size(*((*pstate).stitchdata))
  if datasize(1) le 0 then begin
    void = dialog_message('The Stitched Data File is Empty!')
    return
  endif
  xrdata = (*(*pstate).stitchdata)
  mypath=(*pstate).working_directory
  fn = dialog_pickfile(default_extension='dave',/write, title='Select a DAVE filename for the stitched data:',path=mypath)  
  x=reform(xrdata[0,*])
  y=0.0
  qty=reform(xrdata[1,*])
  err=reform(xrdata[2,*])
  xlabel=(*pstate).colname
  QTlabel='Intensity'
  treatment=''
  instrument='bt7'  
  
  
  RET_VAL = CREATE_DAVE_POINTER(daveptr,          $
                  INSTRUMENT = instrument,  $
                  QTY = qty,                          $
                  ERR = err,                          $
                  XLABEL = xlabel,                 $
                  QTLABEL = qtlabel,                $
                  YVALS = y,                          $
                  XVALS = x,                          $
                  XTYPE = 'POINTS',                   $
                  YTYPE = 'POINTS',                   $
                  TREATMENT = treatment)
        
  save,daveptr,filename=fn,/compress 
  
  heap_free, daveptr  
end;save_psd_data


; send data to pan

pro psd_send_to_pan_handler, event
  widget_control,event.top,get_uvalue = pstate
thisEvent = tag_names(event,/structure_name)
case thisEvent of
'WIDGET_BUTTON': begin
  datasize = size(*((*pstate).stitchdata))
  if datasize(1) le 0 then begin
    void = dialog_message('The Stitched Data File is Empty!')
    return
  endif
  xrdata = (*(*pstate).stitchdata)
  mypath=(*pstate).working_directory
  x=reform(xrdata[0,*])
  y=0.0
  xind=sort(x)
  x=x[xind]
  qty=reform(xrdata[1,*])
  err=reform(xrdata[2,*])
  
  qty=qty[xind]
  err=err[xind]
  xlabel=(*pstate).colname
  QTlabel='Intensity'
  treatment=''
  instrument='bt7'  
  
  
  RET_VAL = CREATE_DAVE_POINTER(daveptr,          $
                  INSTRUMENT = instrument,  $
                  QTY = qty,                          $
                  ERR = err,                          $
                  XLABEL = xlabel,                 $
                  QTLABEL = qtlabel,                $
                  YVALS = y,                          $
                  XVALS = x,                          $
                  XTYPE = 'POINTS',                   $
                  YTYPE = 'POINTS',                   $
                  TREATMENT = treatment)
  (*pstate).daveptr=daveptr      
  o = obj_new('opan',notifyId = [event.id,event.top], $
                         group_leader = event.top, $
                           davePtr = davePtr,   $
                           workdir =(*pstate).working_directory)  
  
end
'OPANEVENT': $
  begin
    obj = event.object  ; This is the object that just quit
   obj_destroy,obj
   heap_free, (*pstate).daveptr 
  end  
  
  endcase 
end;pan_psd_data


; send data to pan

pro psd_send_group_to_pan_handler, event
  widget_control,event.top,get_uvalue = pstate
  Ch_Eff = findgen(48)
  Ch_Eff=(*pstate).Ch_axis_Eff
  datasize = size(*((*pstate).data))
  if datasize(1) le 0 then begin
    void = dialog_message('The Data File is Empty!')
    return
  endif
  goodch=0
  for i=0,47 do begin  
    if Ch_Eff(i) ne 0 then goodch=goodch+1
  endfor
  
; Correct the data for efficiency
  data = *((*pstate).data)
  data_err =*((*pstate).data_err)
  
  data_corrected=fltarr(goodch,datasize(2)); make generic!!!
  data_err_corrected=fltarr(goodch,datasize(2))
  
  for i = 0, datasize(2)-1 do begin
    k=0
    for j=0,47 do begin
      if Ch_Eff(j) ne 0 then begin
        data_corrected[k,i] = data(j, i)*Ch_eff(j)
        data_err_corrected[k,i] = data_err(j,i)*Ch_eff(j)
        k=k+1
      endif
    endfor
  endfor

; convert channel id to A4
  widget_control,(*pstate).PsdCenter, get_value=centerch
  if centerch lt 0 || centerch gt 47 then centerch =23  
  vardata = *((*pstate).vardata)
  varname=*(*pstate).varname
  colname=(*pstate).colname
  var_pos=where(strlowcase(varname) eq strlowcase('A4'))
  var_pos=var_pos[0]
  indep_pos=where(strlowcase(varname) eq strlowcase(colname))
  indep_pos=indep_pos[0]  
  independent_var=(*(*pstate).vardata)(indep_pos,*)
  A4=(*(*pstate).vardata)(var_pos,0) ; extract first A4 position in the file
  a4_actual=fltarr(goodch)
  ch_position=fltarr(48)
  fn = (*pstate).PSD_A4_Spacing
  if (fn eq '') then a4_handler, event
  if fn eq '' then return 
  openr, fun, fn, /get_lun
  readf, fun, ch_position
  free_lun, fun
  ;Now calculate the spacing between every channel and the specified center channel

  i=0
  for k = 0, 47 do begin
    if Ch_Eff(k) ne 0 then  begin
      a4_actual(i) = ch_position(fix(centerch))-ch_position(k)+A4
      i=i+1
    endif
  endfor
  ;a4_actual=ch_position(centerch)-ch_position+A4
  
  
; send to pan  
thisEvent = tag_names(event,/structure_name)
case thisEvent of
'WIDGET_BUTTON': begin
  datasize = size(*((*pstate).stitchdata))
  if datasize(1) le 0 then begin
    void = dialog_message('The Stitched Data File is Empty!')
    return
  endif
  xrdata = (*(*pstate).stitchdata)
  mypath=(*pstate).working_directory
 
  x=reform(xrdata[0,*])
  y=0.0
  qty=reform(xrdata[1,*])
  err=reform(xrdata[2,*])
  ylabel=(*pstate).colname
  xlabel='A4'
  QTlabel='Intensity'
  treatment=''
  instrument='bt7'  
  
  y=reform(independent_var)
  RET_VAL = CREATE_DAVE_POINTER(daveptr,          $
                  INSTRUMENT = instrument,  $
                  QTY = data_corrected,                          $
                  ERR = data_err_corrected,                          $
                  YLABEL = ylabel,                 $
                  XLABEL = xlabel, $
                  QTLABEL = qtlabel,                $
                  XVALS = a4_actual,                          $
                  YVALS = y,                          $
                  XTYPE = 'POINTS',                   $
                  YTYPE = 'POINTS',                   $
                  TREATMENT = treatment)
  (*pstate).daveptr=daveptr      
  o = obj_new('opan',notifyId = [event.id,event.top], $
                         group_leader = event.top, $
                           davePtr = davePtr,   $
                           workdir =(*pstate).working_directory)  
  
end
'OPANEVENT': $
  begin
    obj = event.object  ; This is the object that just quit
   obj_destroy,obj
   heap_free, (*pstate).daveptr 
  end  
  
  endcase 
end;pan_psd_data

; send data to pan

pro psd_send_group_to_databrowser_handler, event
  widget_control,event.top,get_uvalue = pstate
  Ch_Eff = findgen(48)
  Ch_Eff=(*pstate).Ch_axis_Eff
  datasize = size(*((*pstate).data))
  if datasize(1) le 0 then begin
    void = dialog_message('The Data File is Empty!')
    return
  endif
  widget_control,(*pstate).PsdCenter, get_value=centerch
  widget_control,(*pstate).PsdLeft, get_value=leftch
  widget_control,(*pstate).PsdRight, get_value=rightch

; Correct the data for efficiency
  data = *((*pstate).data)
  data_err = sqrt(data)
  goodch=0
  for i=0,47 do begin  
    if Ch_Eff(i) ne 0 then goodch=goodch+1
  endfor
  data_corrected=fltarr(goodch,datasize(2)); make generic!!!
  data_err_corrected=fltarr(goodch,datasize(2))
  for i = 0, datasize(2)-1 do begin
    k=0
    for j=0,47 do begin
      if Ch_Eff(j) ne 0 then begin
        data_corrected[k,i] = data(j, i)*Ch_eff(j)
        data_err_corrected[k,i] = data_err(j,i)*Ch_eff(j)
        k=k+1
      endif
    endfor
  endfor
; convert channel id to A4
  widget_control,(*pstate).PsdCenter, get_value=centerch
  if centerch lt 0 || centerch gt 47 then centerch =23  
  vardata = *((*pstate).vardata)
  varname=*(*pstate).varname
  colname=(*pstate).colname
  var_pos=where(strlowcase(varname) eq strlowcase('A4'))
  var_pos=var_pos[0]
  indep_pos=where(strlowcase(varname) eq strlowcase(colname))
  indep_pos=indep_pos[0]  
  independent_var=(*(*pstate).vardata)(indep_pos,*)
  A4=(*(*pstate).vardata)(var_pos,0) ; extract first A4 position in the file
  a4_actual=fltarr(goodch)
  ch_position=fltarr(48)
  fn = (*pstate).PSD_A4_Spacing
  if (fn eq '') then a4_handler, event
  if fn eq '' then return 
  openr, fun, fn, /get_lun
  readf, fun, ch_position
  free_lun, fun
  ;Now calculate the spacing between every channel and the specified center channel
  i=0
  for k = 0, 47 do begin
    if Ch_Eff(k) ne 0 then  begin
      a4_actual(i) = ch_position(fix(centerch))-ch_position(k)+A4
      i=i+1
    endif
  endfor
; send to pan  
  thisEvent = tag_names(event,/structure_name)
  datasize = size(*((*pstate).stitchdata))
  if datasize(1) le 0 then begin
    void = dialog_message('The Stitched Data File is Empty!')
    return
  endif
  xrdata = (*(*pstate).stitchdata)
  mypath=(*pstate).working_directory
 
  x=reform(xrdata[0,*])
  y=0.0
  qty=reform(xrdata[1,*])
  err=reform(xrdata[2,*])
  ylabel=(*pstate).colname
  xlabel='A4'
  QTlabel='Intensity'
  treatment=''
  instrument='bt7'  
  
  y=reform(independent_var)
  RET_VAL = CREATE_DAVE_POINTER(daveptr,          $
                  INSTRUMENT = instrument,  $
                  QTY = data_corrected,                          $
                  ERR = data_err_corrected,                          $
                  YLABEL = ylabel,                 $
                  XLABEL = xlabel, $
                  QTLABEL = qtlabel,                $
                  XVALS = a4_actual,                          $
                  YVALS = y,                          $
                  XTYPE = 'POINTS',                   $
                  YTYPE = 'POINTS',                   $
                  TREATMENT = treatment)
  (*pstate).daveptr=daveptr
  display_name='Untitled';  Should be the name of the file being sent over!      
  if (xregistered('DaveDataBrowser')) then begin
              ;;print,'DB is running...'
              ;;print,'dbTLB = ',self.dataBrowserTLB
     if (widget_info((*pstate).dataBrowserTLB,/valid)) then begin
        DB_i_loadDataFromDavePtrs, (*pstate).dataBrowserTLB, data=davePtr, nametag=display_name
                 widget_control, (*pstate).dataBrowserTLB,/show
              endif else begin  ; 
                 title = 'View '+display_name+' in Data Browser'
                 msg = 'Cannot locate a running Data Browser instance!'
                 msg = [msg,'If an instance of the Data Browser is currently running,']
                 msg = [msg,'please, end it before trying this function again.']
                 void = dialog_message(msg,/info,title=title,dialog_parent=event.top)
              endelse
           endif else begin
              db_interface, GROUP_LEADER=event.top, WORKING_DIRECTORY=(*pstate).working_directory, $
                            data=davePtr, nameTag=display_name, dbTLB=dbTLB
              (*pstate).dataBrowserTLB=dbTLB
           endelse
           
           heap_free,davePtr

end;pan_databrowser

;*****************************************************************************
; The plot function to generate different type of plot regarding to the plottype
pro PSD_Plot_graphs, pstate, xrge=xrge, yrge=yrge, Txrge=Txrge
  x=*(*pstate).xdata
  y=*(*pstate).ydata
  err=*(*pstate).errdata
  z=*(*pstate).zdata
  wset,(*pstate).winpix
  case (*pstate).plottype of
    0: begin
      plot,x,y,psym = 4,thick = 4.0, title = (*pstate).plot_title, xtitle=(*pstate).xtitle,$
        xrange = xrge, yrange = yrge, ytitle = (*pstate).ytitle,xstyle=1
      errplot, x, (y-err),(y+err)  
      end
    1: begin
        plot,x,y,psym = 4,thick = 4.0, ymargin=[5, 3],subtitle = (*pstate).plot_title, xtitle=(*pstate).xtitle, $
          xrange = xrge, yrange = yrge, ytitle=(*pstate).ytitle,xstyle=9

        if n_elements(Txrge) eq 0 then Txrge = [47,0]
        if n_elements(xrge) eq 0 then begin
             (*pstate).xrge_orig = !x.crange
             Txrange = [47,0]
        endif else begin
          ratio=47/(((*pstate).xrge_orig(0)-(*pstate).xrge_orig(1)))
          cmax=!x.crange(1)
          cmin=!x.crange(0)
          xmin=(*pstate).xrge_orig(0)
          xmax=(*pstate).xrge_orig(1)
          min_Txrge=(cmin-xmin)*ratio+47
          max_Txrge=(cmax-xmin)*ratio+47
          Txrge=[min_Txrge, max_Txrge]
        endelse
        errplot, x, (y-err),(y+err)
        axis, xaxis=1, xrange=Txrge, xtitl=(*pstate).filename+': '+'PSD Channel Number',xstyle=1
        end
     3: begin
        
        end  
  endcase
end; PSD_Plot

;***********************************************************************
;Plot the zoom in funciton in the graphic window
pro Psd_plot_refresh, event
	widget_control, event.top, get_uvalue=pstate
	datasize = size(*((*pstate).data))
  if datasize(1) le 0 then begin
    ;void = dialog_message('The Data File is Empty!')
    return
  endif
	etype = tag_names(event,/structure_name)
	wset,(*pstate).winvis
	if etype eq 'WIDGET_DRAW' then begin
		if event.press eq 1 then begin ; left mouse pressed
			(*pstate).pressx = event.x
			(*pstate).pressy = event.y
			(*pstate).press = 1
		endif;press left mouse

		if event.release eq 1 then begin ;left mouse release
		  (*pstate).press = 0
			(*pstate).currentx = event.x
      (*pstate).currenty = event.y
			pressr   = convert_coord((*pstate).pressx,(*pstate).pressy,/device,/to_data)
			releaser = convert_coord((*pstate).currentx,(*pstate).currenty,/device,/to_data)
			minx = min([pressr[0],releaser[0]],max=maxx)
			miny = min([pressr[1],releaser[1]],max=maxy)
		  PSD_plot_graphs, pstate, xrge=[minx,maxx],yrge=[miny,maxy]
		  wset,(*pstate).winvis
      device, copy=[0,0,700,700,0,0,(*pstate).winPix] ; 
		endif;release

		;IF THE MOUSE IS HELD PRESSED, THEN PERFORM THE DRAG EVENTS
		if (*pstate).press eq 1 then begin ;mouse motion

			;RECORD THE CURRENT MOUSE POSITION
			(*pstate).currentx = event.x
			(*pstate).currenty = event.y
			x1 = [(*pstate).pressx,(*pstate).currentx,(*pstate).currentx,(*pstate).pressx,(*pstate).pressx]
			y1 = [(*pstate).pressy,(*pstate).pressy,(*pstate).currenty,(*pstate).currenty,(*pstate).pressy]
			green = ((2L)^8 - 1)*256L
			device, copy=[0,0,700,700,0,0,(*pstate).winPix] ; 
			plots,x1,y1,color=green,/device
			
		endif

		;FINALLY CHECK FOR RIGHT MOUSE BUTTON PRESS
		if event.press eq 4 then begin ; right mouse press
			PSD_Plot_graphs, pstate
			wset,(*pstate).winvis
      device, copy=[0,0,700,700,0,0,(*pstate).winPix] ;
		endif;event.press
	endif;etype

end; psd_plot_refresh,
;*******************************************************


;===============================================================================
; a4_handler
;
; PURPOSE:
;   Event handler. Let user specify the psd_a4_channel_spacing file. The specified
;   value is stored in a global variable and also saved for future DAVE
;   sessions.
;
; PARAMETERS:
;   event [in] - event structure.
;
pro a4_handler,event
widget_control, event.top, get_uvalue=pstate
dave_defs=*!dave_defaults
old_file=dave_defs.psd_a4_spacing
old_path=file_dirname(old_file)
calib_file = DIALOG_PICKFILE(title = 'Select a4 spacing file',path=old_path)
if (calib_file eq '') then return
dave_defs.psd_a4_spacing=calib_file
pdd=!dave_defaults
ptr_free,pdd
pdd=ptr_new(dave_defs)

  ;LRK 051507
  ;ADDING THE CHECKING BECAUSE OF POTENTIAL NETWORK DRIVE INACCESSIBLE ISSUES
  if file_test(!defaults_file,/write) eq 0 then begin

    yn = dialog_message('Your chosen home directory appears to be inaccessible.  Would you like to choose a new one?',/question)
    print,yn

    if strupcase(yn) eq 'YES' then begin
      print,'!defaults_file=',!defaults_file
      hmdir = dialog_pickfile(/directory)

      if hmdir ne '' then begin
        !defaults_file = hmdir+path_sep()+file_basename(!defaults_file)
        save,filename=!defaults_file,pdd
      endif
    endif

  endif else begin
    save,filename=!defaults_file,pdd
  endelse
; LRK 051507 COMMENTED THE FOLLOWING LINE
; save,filename=!defaults_file,pdd
defsysv,'!dave_defaults',pdd
(*pstate).psd_a4_spacing=calib_file
if (old_file ne calib_file) then $
  x=dialog_message("The new a4 channel spacing calibration file is "+(*!dave_defaults).psd_a4_spacing,/information)
return
end
;-------------------------------------------------------------------------------


;===============================================================================
; psd_channel_Eff_handler
;
; PURPOSE:
;   Event handler. Let user specify the psd_channel_efficiency file. The specified
;   value is stored in a global variable and also saved for future DAVE
;   sessions.
;
; PARAMETERS:
;   event [in] - event structure.
;
pro channel_handler,event
widget_control, event.top, get_uvalue=pstate
dave_defs=*!dave_defaults
old_file=dave_defs.psd_channel_Eff
old_path=file_dirname(old_file)
calib_file = DIALOG_PICKFILE(title = 'Select channel efficiciency calibration file',path=old_path)
if (calib_file eq '') then return
dave_defs.psd_channel_Eff=calib_file
pdd=!dave_defaults
ptr_free,pdd
pdd=ptr_new(dave_defs)

  ;LRK 051507
  ;ADDING THE CHECKING BECAUSE OF POTENTIAL NETWORK DRIVE INACCESSIBLE ISSUES
  if file_test(!defaults_file,/write) eq 0 then begin

    yn = dialog_message('Your chosen home directory appears to be inaccessible.  Would you like to choose a new one?',/question)
    print,yn

    if strupcase(yn) eq 'YES' then begin
      print,'!defaults_file=',!defaults_file
      hmdir = dialog_pickfile(/directory)

      if hmdir ne '' then begin
        !defaults_file = hmdir+path_sep()+file_basename(!defaults_file)
        save,filename=!defaults_file,pdd
      endif
    endif

  endif else begin
    save,filename=!defaults_file,pdd
  endelse
; LRK 051507 COMMENTED THE FOLLOWING LINE
; save,filename=!defaults_file,pdd
defsysv,'!dave_defaults',pdd
(*pstate).psd_channel_Eff=calib_file
if (old_file ne calib_file) then $
  x=dialog_message("The new channel efficiency calibration file is "+(*!dave_defaults).psd_channel_Eff,/information)
return
end
;-------------------------------------------------------------------------------




;===============================================================================
; psd_ef_handler
;
; PURPOSE:
;   Event handler. Let user specify the psd_Ef_spacing file. The specified
;   value is stored in a global variable and also saved for future DAVE
;   sessions.
;
; PARAMETERS:
;   event [in] - event structure.
;
pro ef_handler,event
widget_control, event.top, get_uvalue=pstate
dave_defs=*!dave_defaults
old_file=dave_defs.psd_Ef_spacing
old_path=file_dirname(old_file)
calib_file = DIALOG_PICKFILE(title = 'Select Ef spacing calibration file',path=old_path)
if (calib_file eq '') then return
dave_defs.psd_Ef_spacing=calib_file
pdd=!dave_defaults
ptr_free,pdd
pdd=ptr_new(dave_defs)

  ;LRK 051507
  ;ADDING THE CHECKING BECAUSE OF POTENTIAL NETWORK DRIVE INACCESSIBLE ISSUES
  if file_test(!defaults_file,/write) eq 0 then begin

    yn = dialog_message('Your chosen home directory appears to be inaccessible.  Would you like to choose a new one?',/question)
    print,yn

    if strupcase(yn) eq 'YES' then begin
      print,'!defaults_file=',!defaults_file
      hmdir = dialog_pickfile(/directory)

      if hmdir ne '' then begin
        !defaults_file = hmdir+path_sep()+file_basename(!defaults_file)
        save,filename=!defaults_file,pdd
      endif
    endif

  endif else begin
    save,filename=!defaults_file,pdd
  endelse
; LRK 051507 COMMENTED THE FOLLOWING LINE
; save,filename=!defaults_file,pdd
defsysv,'!dave_defaults',pdd
(*pstate).psd_Ef_spacing=calib_file
if (old_file ne calib_file) then $
  x=dialog_message("The new Ef channel calibration file is "+(*!dave_defaults).psd_Ef_spacing,/information)
return
end
;-------------------------------------------------------------------------------


pro calview_handler,event
widget_control, event.top, get_uvalue=pstate


a4_file=(*pstate).psd_a4_spacing
channel_file=(*pstate).psd_channel_Eff
ef_file=(*pstate).psd_Ef_spacing

msg_arr=['The current settings are:','A4 file='+a4_file,'channel efficiency file='+channel_file,$
         'Ef calibration file='+ef_file]

x=dialog_message(msg_arr,/information)
end
;-------------------------------------------------------------------------------
pro crystalbt7psd,group_leader = group_leader,workDir=workDir,dataDir=dataDir

	if n_elements(group_leader) eq 0 then group_leader = 0L

	if xregistered('PSD_plot') then return
	tlb = widget_base(/row,title = 'BT7 PSD data reduction', group_leader = group_leader,mbar=menubar)
	col_base = widget_base(tlb,/col, space =2)
	void = widget_button(col_base, value = 'Load Data File', font ='8', uname='LoadDat')
	void = widget_label(col_base, /align_center, font='8', Value = 'View Raw Data')
	RawCh_base = widget_base(col_base, /row, space =15)
	void = widget_label(Rawch_base, value = 'Channel',/align_center)
	Ch_slider = widget_slider(Rawch_base,/drag, maximum = 47, minimum=0, xsize=120, value=10, uname='PSD_CH' )
	
	Ch_BK_Button =widget_button(col_base,/align_right, xoffset=20, ysize='20',xsize=120, value = 'Set Step 0 as Bkgd',uname='Ch_BKGD')
	RawVar_base = widget_base(col_base, /row, space =10)
	void = widget_label(RawVar_base, value = 'Indep var')
	Var_slider = widget_slider(RawVar_base,/drag, maximum=1000, xsize =120, /suppress_value,uname='VAR')
	
	void = widget_label(col_base,/align_center, font='8',value = 'Used PSD Channels')
	subrow_base = widget_base(col_base, /row, space =27)
 	void=widget_label(subrow_base,/align_center,value = 'Center Channel')
 	PsdCenter  = widget_text(subrow_base,frame = 6, xsize=11, value='23',/editable,uname='Psd_Center')
 	leftrow_base = widget_base(col_base, /row, space = 40)
 	void=widget_label(leftrow_base,/align_center,value = 'Left Channel')
 	PsdLeft  = widget_text(leftrow_base,value='0',/editable,xsize =11, uname='Psd_Left')
 	rightrow_base = widget_base(col_base, /row, space=32)
	void=widget_label(rightrow_base,/align_center,value = 'Right Channel')
	PsdRight  = widget_text(rightrow_base,value='47',/editable,xsize = 11, uname='Psd_Right')
	badch_base= widget_base(col_base, /row, space=32)
	void=widget_label(badch_base,/align_center,xsize=67,value = 'Bad Channels')
	BadCh  = widget_text(badch_base, value='',/editable,event_func='Exclude_PSD_ch, event',xsize = 11, uname='ExcludeCh')
	void = widget_button(col_base,value = 'Sum Channel', font='8',uname = 'SUM')
	A4begin_base= widget_base(col_base, /row, space=32)
  void=widget_label(A4begin_base,/align_center,xsize=67,value = 'A4 Begin')
  A4begin  = widget_text(A4begin_base, value='',/editable,xsize = 11, uname='A4begin')
  A4end_base= widget_base(col_base, /row, space=32)
  void=widget_label(A4end_base,/align_center,xsize=67,value = 'A4 End')
  A4end  = widget_text(A4end_base, value='',/editable,xsize = 11, uname='A4end')
	
	A4step_base= widget_base(col_base, /row, space=32)
  void=widget_label(A4step_base,/align_center,xsize=67,value = 'A4 Step')
  A4step  = widget_text(A4step_base, value='',/editable,xsize = 11, uname='A4step')
	void = widget_button(col_base,value = 'Stitch Pattern', font='8',uname = 'STICH')
	Stitch_base =widget_base(col_base,/row)
  Set_File_Bg_Button = widget_button(Stitch_base, xsize='90',value = 'Set file as Bkgd',uname='file_bkgd')
  widget_control,Set_File_Bg_Button,tooltip='Set Current File as Background'
  Subtract_File_Bg_Button = widget_button(Stitch_base, xsize='90',value = 'Subtract Bkgd',uname='subtract_bkgd')
  widget_control,Subtract_File_Bg_Button,tooltip='Subtract the background file'
	void = widget_button(col_base, value = 'Save Plot Data', font='8',uname = 'SaveStich')
	void = widget_button(col_base,value = 'Quit', font='8',uname = 'QUIT')
	win = widget_draw(tlb,xsize = 700,ysize = 700, $
			/motion_events,/button_events,/tracking_events,	uname = 'WIN')
			
	fileId=widget_button(menubar,value='File')
	file_item=widget_button(fileId,value='Set A4 Spacing File',event_pro='a4_handler')
	file_item=widget_button(fileId,value='Set Channel Efficiency File',event_pro='channel_handler')
	file_item=widget_button(fileId,value='Set Ef Spacing File',event_pro='ef_handler')
	file_item=widget_button(fileId,value='View Calibration File Locations',event_pro='calview_handler')
	
	exportId=widget_button(menubar,value='Export')
	export_item=widget_button(exportId,value='Save As Dave File',event_pro='psd_export_to_dave_dave_handler')
	export_item=widget_button(exportId,value='Send Current Data to Pan',event_pro='psd_send_to_pan_handler')
	export_item=widget_button(exportId,value='Send Group Data to Pan',event_pro='psd_send_group_to_pan_handler')
	export_item=widget_button(exportId,value='Send Group Data to Data Browser',event_pro='psd_send_group_to_databrowser_handler')
	
	widget_control,tlb,/realize
	widget_control,win,get_value = winvis
	window,/pixmap,xsize = 700,ysize = 700
	winpix = !d.window
	;stitchdata = ptr_new(/allocate_heap)
	;data=ptr_new(/allocate_heap)
	;data_err=ptr_new(/allocate_heap)
	;vardata = ptr_new(/allocate_heap)
	;varname = ptr_new(/allocate_heap)
	state =  {winvis:		winvis,     $
            winpix:			winpix,   $
            win:			    win,		$
            npoints:		  0,			$ ;the number of column of data in the file after #Ncolumns
            colname: 		''      , $ ;the independent variable name after #Scan
            unit: 			0L		  , $ ;time or monitor after #reference
            unitname: 		'',			$ ;
            ef:				14.7,   		$ ;
            lattice:		findgen(6), $ ; The lattice parameter and angles
            orient:         indgen(6),	$ ; the orientation plane
            monspacing:     0L,			$ ;The d-spacing of the monochromator
            Ch_axis_Eff:	findgen(48),$ ; instore the channel efficiency
            Ch_Eng_Eff:		findgen(48),$ ; Instore the engery diffence for every channel in 3-axis mode
            plot_title: 	'',         $
            xtitle:			'',			$
            ytitle:			'',			$
            vardata:		ptr_new(/allocate_heap),    $ ; store all the other variables
            data: 			ptr_new(/allocate_heap),		$
            data_err:    ptr_new(/allocate_heap)   ,   $
            
            bkgd_filename: '',      $
            bkgd_unit: 0L,           $
            bkgd_colname: '',        $
            bkgd_xdata:     ptr_new(), $  ;the x, y data used to draw the current graph
            bkgd_ydata:      ptr_new(), $
            bkgd_errdata:    ptr_new(), $
            bkgd_chrange:    indgen(3),  $
            bkgd_badch:      '',    $
            Set_File_Bg_Button: Set_File_Bg_Button, $
            Subtract_File_Bg_Button: Subtract_File_Bg_Button, $
            File_Bg_Flag: 0,        $ ;If there is a stitch pattern as background
            File_Bg_Subtract_Flag: 0,  $; if the file has been subtract the background
            A4begin:     A4begin,      $
            A4end:     A4end,      $   
            A4step:     A4step,      $    
                   
            var_slider:		var_slider, $
            ch_slider:		ch_slider,  $
            Ch_BK_Button:  Ch_BK_Button,$
            PsdCenter:		PsdCenter,  $
            PsdLeft: 		PsdLeft,  	$
            PsdRight: 		PsdRight,  	$
            BadCh:			BadCh,      $
            stitchdata: 	ptr_new(/allocate_heap), $
            Ch_Bg_Flage:		0,			$   ;image flage =1 if there is a actived image in draw window
            ChBackGround: fltarr(48),  $
            xptr:			ptr_new(!x),$	;KEEP TRACK OF AXES SYSTEM VARIABLES
            yptr:			ptr_new(!y),$
            xrge_orig : dblarr(2),$            
            press:			0,			$	;THIS IS THE WAY TO KEEP TRACK OF DRAGGING
            pressx:			0,			$	;KEEP TRACK OF POSITION OF MOUSE PRESS
            pressy:			0,			$
            currentx:		0,			$	;KEEP TRACK OF POSITION OF CURRENT MOUSE POSITION
            currenty:		0,			$
            plottype:			0,			$;0: channel plot; 1:var plot; 2: sum plot; 3: stitch plot.
            xdata:			ptr_new(/allocate_heap), $  ;the x, y data used to draw the current graph
            ydata:			ptr_new(/allocate_heap), $
            errdata:		ptr_new(/allocate_heap), $
            zdata:			ptr_new(/allocate_heap), $
            psd_a4_spacing:  (*!dave_defaults).psd_a4_spacing,$
            psd_channel_Eff: (*!dave_defaults).psd_channel_Eff,$
            psd_Ef_spacing:(*!dave_defaults).psd_Ef_spacing, $      
            varname:ptr_new(/allocate_heap),$
            working_directory: workDir, $
            data_directory:dataDir,$
            daveptr:ptr_new(/allocate_heap),$
            dataBrowserTLB:0L,$
            filename: '',$
            intdata:		ptr_new(/allocate_heap)		  }
	pstate = ptr_new(state)
	widget_control,tlb,set_uvalue = pstate

	xmanager,'getbt7psd',tlb,/no_block, event_handler = 'PSD_event', cleanup = 'PSD_cleanup'

end; getbt7psd






