; $Id: dcs_choose_grouping.pro,v 1.18 2005/02/14 17:50:13 azuah Exp $
; Written by J.R.D. Copley.
;************************************************************************************************
;###############################################################################
;
; LICENSE:
;  The software in this file is written by an employee of 
;  National Institute of Standards and Technology 
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used or if the code in this file is
;  included in another product.
;
;###############################################################################
pro dcs_calculate_grouping,np,uml,qthchce,calc_vals,contents,nhedet,lambda,grouping,$
	tthmin,tthmax,qmin,qmax,elasticqvals
;************************************************************************************************
; This routine returns the variable "grouping".

compile_opt strictarr
;
; Input variables:
; np=0 to NOT "Combine negative and positive angle detectors"
; np=1 to     "Combine negative and positive angle detectors"
; uml=1 to "Combine lower, middle and upper banks"
; uml=2 to "Combine lower and upper banks only")
; uml=3 to "Do not combine detector banks"
; qthchce=1 to "Combine into groups with equal widths in 2theta" (calc_vals contains 2theta step)
; qthchce=2 to "Combine into groups with equal widths in ''Q''" (calc_vals contains Q step)
; qthchce=3 to "Specify 2theta boundaries of detector groups" (calc_vals contains 2theta values)
; qthchce=4 to "Specify ''Q'' boundaries of detector groups" (calc_vals contains Q values)
;	calc_vals contains quantities described above
;	contents contains the contents of "detpos2.dat"
; nhedet=913
; lambda=incident wavelength
; tthmin,tthmax are basically -30 and +140
; qmin,qmax are corresponding Q limits
;
grouping=fix(contents[0,1:nhedet])
bank=fix(contents[1,1:nhedet])
angle=float(contents[2,1:nhedet])
;
; Define the array vals, which contains the limits on 2theta.
case qthchce of
	1: begin
		tthstep=float(calc_vals[0])
		if (tthstep le 0.0) then begin
			res=dialog_message("Invalid 2theta step size:"+calc_vals[0],/error)
			grouping=0
			return
		endif
		if (np eq 0) then nneg=fix(-tthmin/tthstep+1.0) else nneg=0
		npos=fix(tthmax/tthstep+1.0)
		nvals=nneg+1+npos
		vals=fltarr(nvals)
		if (np eq 0) then vals[0]=tthmin else vals[0]=0.0
		if (nvals gt 2) then for i=1,nvals-2 do vals[i]=tthstep*(i-nneg)
		vals[nvals-1]=tthmax
	end
	2: begin
		qstep=float(calc_vals[0])
		if (qstep le 0.0) then begin
			res=dialog_message("Invalid Q step size:"+calc_vals[0],/error)
			grouping=0
			return
		endif
			if (np eq 0) then nneg=fix(-qmin/qstep+1.0) else nneg=0
		npos=fix(qmax/qstep+1.0)
		nvals=nneg+1+npos
		vals=fltarr(nvals)
		if (np eq 0) then vals[0]=tthmin else vals[0]=0.0
		if (nvals gt 2) then for i=1,nvals-2 do vals[i]=2.*asin(qstep*(i-nneg)*lambda/(4.0*!pi))*!radeg
		vals[nvals-1]=tthmax
	end
	3: begin
		vals=float(calc_vals)
		nvals=n_elements(vals)
		if (np eq 0) then nneg=n_elements(where (vals lt 0.0)) else nneg=0
		npos=nvals-nneg-1
	end
	4: begin
		vals=float(calc_vals)
		vals=2.*asin(vals*lambda/(4.0*!pi))*!radeg
		nvals=n_elements(vals)
		if (np eq 0) then nneg=n_elements(where (vals lt 0.0)) else nneg=0
		npos=nvals-nneg-1
	end
	else:
endcase
;
; Hence elasticqvals, which contains the limits on Q(elastic).
elasticqvals=4.0*!pi*sin(vals*!pi/360.0)/lambda
;
if (np eq 0) then begin
	for i=0,nneg-1 do begin
		vmin=vals[nneg-i-1]
		vmax=vals[nneg-i]
		indices=where((angle ge vmin) and (angle lt vmax))
		if (indices[0] gt -1) then grouping[indices]=1+i*uml
	endfor
	for i=nneg,nvals-2 do begin
		vmin=vals[i]
		vmax=vals[i+1]
		indices=where((angle ge vmin) and (angle lt vmax))
		if (indices[0] gt -1) then grouping[indices]=1+i*uml
	endfor
endif else begin
	for i=0,nvals-2 do begin
		vmin=vals[i]
		vmax=vals[i+1]
		indices=where((abs(angle) ge vmin) and (abs(angle) lt vmax))
		if (indices[0] gt -1) then grouping[indices]=1+i*uml
	endfor
endelse
;
if (uml eq 2) then grouping=grouping+abs(bank)
;
if (uml eq 3) then grouping=grouping+1+bank
;
grouping=transpose(grouping); turn grouping into a row vector.
;
; The final grouping array should include at least one instance of each integer from 1 to ngroups.
dcs_general_collapse,grouping,cgrouping
if (n_elements(cgrouping) eq 1) then message,'Fatal error in dcs_calculate_grouping.'
grouping=cgrouping+1
ngroups=max(grouping)
;
end



;************************************************************************************************
pro dcs_choose_grouping_handler,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=state
;
nhedet=state.nhedet
done=state.done
save=state.save
restore=state.restore
ngro=state.ngro
gng=state.gng
dpt=state.dpt
bbase=state.bbase
negpos=state.negpos
lomiup=state.lomiup
lowupp=state.lowupp
donotc=state.donotc
equal2=state.equal2
equalQ=state.equalQ
speci2=state.speci2
speciQ=state.speciQ
tthstepb=state.tthstepb
qstepb=state.qstepb
tthvalb=state.tthvalb
qvalb=state.qvalb
tthsteptext=state.tthsteptext
qsteptext=state.qsteptext
tthvaltext=state.tthvaltext
qvaltext=state.qvaltext
tthvalentry=state.tthvalentry
qvalentry=state.qvalentry
calc=state.calc
nxtrow=state.nxtrow
np=*state.ptr_np
uml=state.uml
qthchce=state.qthchce
calc_vals=state.calc_vals
contents=state.contents
lambda=state.lambda
info=state.info
;
elasticqvals=*state.ptr_elq
;
tthmin=state.tthmin
tthmax=state.tthmax
qmin=state.qmin
qmax=state.qmax
;
grouping=*state.ptr_gp
;
evid=event.id
;
case evid of
	gng: begin
;		Treat case that "DO NOT GROUP" button was unchecked, hence grouping.
		if (event.select eq 0) then begin
			widget_control,dpt,use_table_select=[4,1,4,nhedet],$
				set_value=transpose(strarr(nhedet))
			widget_control,calc,sensitive=1
			widget_control,state.bb1,sensitive=1
			widget_control,state.bb2,sensitive=1
			widget_control,state.bb3,sensitive=1
			widget_control,done,sensitive=0
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=""
			if (np) then begin
				tthvals=transpose([string(0.0),string(tthmax)])
				qvals=transpose([string(0.0),string(qmax)])
			endif else begin
				tthvals=transpose([string(tthmin),string(0.0),string(tthmax)])
				qvals=transpose([string(qmin),string(0.0),string(qmax)])
			endelse
;			widget_control,tthvaltext,use_table_select=[0,0,0,100],set_value=tthvals
;			widget_control,qvaltext,use_table_select=[0,0,0,100],set_value=qvals
;;			widget_control,tthsteptext,set_value=string(" 30.0")
;;			widget_control,qsteptext,set_value=string(" 0.5")
;;			calc_vals=string(" 0.5")
			if (qthchce eq 1) then widget_control,tthstepb,sensitive=1
			if (qthchce eq 2) then widget_control,qstepb,sensitive=1
		endif
;		Treat case that "DO NOT GROUP" button was checked, hence no grouping.
		if (event.select eq 1) then begin
			grouping=indgen(nhedet)+1
			contents[4,1:nhedet]=contents[0,1:nhedet]
			widget_control,dpt,set_value=contents
			widget_control,calc,sensitive=0
			widget_control,done,sensitive=1
			widget_control,save,sensitive=0
			widget_control,state.bb1,sensitive=0
			widget_control,state.bb2,sensitive=0
			widget_control,state.bb3,sensitive=0
			widget_control,done,sensitive=1
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=string(nhedet,format="(i4)")+" groups"
;			widget_control,tthvaltext,use_table_select=[0,0,0,100],set_value=strarr(1)
;			widget_control,qvaltext,use_table_select=[0,0,0,100],set_value=strarr(1)
			widget_control,tthstepb,sensitive=0
			widget_control,qstepb,sensitive=0
		endif
	end
;
	restore: begin
		file=!dcs_outp_directory+!dcs_rootname+".dgr"
		if (not file_test(file)) then file=!dcs_default_root+".dgr" $
			else file=!dcs_rootname+".dgr"
		fullfilename=dialog_pickfile(filter="*.dgr",/fix_filter,$
			path=!dcs_outp_directory,/must_exist,$
			file=file,get_path=file_path,$
			title="Select the detector grouping file.")
		cancel=fullfilename eq ""
		if (not cancel) then begin
			if (strlowcase(strmid(fullfilename,3,/reverse)) ne ".dgr") then $
				fullfilename=fullfilename+".dgr"
			restore,filename=fullfilename
; 		The quantities saved, hence restored, are as follows:
;				np,uml,qthchce,calc_vals,contents,nhedet,lambda,grouping,$
;				tthmin,tthmax,qmin,qmax,elasticqvals
			dcs_calculate_grouping,np,uml,qthchce,calc_vals,contents,nhedet,lambda,grouping,$
				tthmin,tthmax,qmin,qmax,elasticqvals
			widget_control,gng,set_button=0
			widget_control,calc,sensitive=1
			widget_control,state.bb1,sensitive=1
			widget_control,state.bb2,sensitive=1
			widget_control,state.bb3,sensitive=1
			widget_control,done,sensitive=1
			widget_control,save,sensitive=1
			widget_control,negpos,set_button=np
			case uml of
				1: begin
					widget_control,lomiup,set_button=1
					widget_control,lowupp,set_button=0
					widget_control,donotc,set_button=0
				end
				2: begin
					widget_control,lomiup,set_button=0
					widget_control,lowupp,set_button=1
					widget_control,donotc,set_button=0
				end
				3: begin
					widget_control,lomiup,set_button=0
					widget_control,lowupp,set_button=0
					widget_control,donotc,set_button=1
				end
			endcase
;;??			if (size(calc_vals,/n_dimensions) ne 0) then $
;;??				qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
			case qthchce of
				1: begin
					widget_control,equal2,set_button=1
					widget_control,equalQ,set_button=0
	;				widget_control,speci2,set_button=0
	;				widget_control,speciQ,set_button=0
					widget_control,tthstepb,sensitive=1
					widget_control,Qstepb,sensitive=0
	;				widget_control,tthvalb,sensitive=0
	;				widget_control,Qvalb,sensitive=0
					widget_control,tthsteptext,set_value=calc_vals[0]
				end
				2: begin
					widget_control,equal2,set_button=0
					widget_control,equalQ,set_button=1
	;				widget_control,speci2,set_button=0
	;				widget_control,speciQ,set_button=0
					widget_control,tthstepb,sensitive=0
					widget_control,Qstepb,sensitive=1
	;				widget_control,tthvalb,sensitive=0
	;				widget_control,Qvalb,sensitive=0
					widget_control,qsteptext,set_value=calc_vals[0]
				end
				3: begin
					widget_control,equal2,set_button=0
					widget_control,equalQ,set_button=0
	;				widget_control,speci2,set_button=1
	;				widget_control,speciQ,set_button=0
					widget_control,tthstepb,sensitive=0
					widget_control,Qstepb,sensitive=0
	;				widget_control,tthvalb,sensitive=1
	;				widget_control,Qvalb,sensitive=0
	;				widget_control,tthvaltext,use_table_select=[0,0,0,100],set_value=calc_vals
				end
				4: begin
					widget_control,equal2,set_button=0
					widget_control,equalQ,set_button=0
	;				widget_control,speci2,set_button=0
	;				widget_control,speciQ,set_button=1
					widget_control,tthstepb,sensitive=0
					widget_control,Qstepb,sensitive=0
	;				widget_control,tthvalb,sensitive=0
	;				widget_control,Qvalb,sensitive=1
	;				widget_control,qvaltext,use_table_select=[0,0,0,100],set_value=calc_vals
				end
			endcase
			widget_control,info,set_value=[$
				"Incident wavelength  "+string(lambda,format="(f8.3)")+" A",$
				"Minimum 2theta  "+string(tthmin,format="(f8.2)")+" deg",$
				"Maximum 2theta  "+string(tthmax,format="(f8.2)")+" deg",$
				"Minimum ''Q''   "+string(qmin,format="(f8.3)")+" A-1",$
				"Maximum ''Q''   "+string(qmax,format="(f8.3)")+" A-1"]
			contents[4,1:nhedet]=grouping
			widget_control,dpt,set_value=contents
			ngroups=max(grouping)
			widget_control,ngro,set_value=string(ngroups,format="(i4)")+" groups"
		endif
	end
;
	save: begin
		repeat begin
			file=!dcs_rootname+".dgr"
			filename=dialog_pickfile(filter="*.dgr",/fix_filter,$
				path=!dcs_outp_directory,$
				file=file,get_path=file_path,$
				title="Define the detector grouping file.")
			cancel=filename eq ""
			compok=strcmp(file_path,!dcs_outp_directory,/fold_case)
			if (not cancel and not compok) then res=dialog_message("You may not change the directory.")
		endrep until (cancel or compok)
		if (not cancel) then begin
			if (strmid(filename,3,/reverse) ne ".dgr") then filename=filename+".dgr"
			save,filename=filename,np,uml,qthchce,calc_vals,contents,nhedet,lambda,grouping,$
				tthmin,tthmax,qmin,qmax,elasticqvals
		endif
	end
;
	calc: begin
		dcs_calculate_grouping,np,uml,qthchce,calc_vals,contents,nhedet,lambda,grouping,$
			tthmin,tthmax,qmin,qmax,elasticqvals
		if (n_elements(grouping) gt 1) then begin
			widget_control,dpt,get_value=contents
			contents[4,1:nhedet]=grouping
			widget_control,dpt,set_value=contents
			ngroups=max(grouping)
			widget_control,ngro,set_value=string(ngroups,format="(i4)")+" groups"
			widget_control,done,sensitive=1
			widget_control,save,sensitive=1
		endif
	end
;
	done: begin
		widget_control,event.top,/destroy
		return
	end
;
	negpos: begin
		np=(event.select eq 1)
		if (np) then begin
			tthvals=transpose([string(0.0),string(tthmax)])
			qvals=transpose([string(0.0),string(qmax)])
		endif else begin
			tthvals=transpose([string(tthmin),string(0.0),string(tthmax)])
			qvals=transpose([string(qmin),string(0.0),string(qmax)])
		endelse
;		widget_control,tthvaltext,set_value=tthvals
;		widget_control,qvaltext,set_value=qvals
		widget_control,done,sensitive=0
		widget_control,save,sensitive=0
		widget_control,ngro,set_value=""
	end
;
	lomiup: begin
		if (event.select eq 1) then begin
			uml=1
			widget_control,done,sensitive=0
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=""
		endif
	end
;
	lowupp: begin
		if (event.select eq 1) then begin
			uml=2
			widget_control,done,sensitive=0
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=""
		endif
	end
;
	donotc: begin
		if (event.select eq 1) then begin
			uml=3
			widget_control,done,sensitive=0
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=""
		endif
	end
;
	equal2: begin
		if (event.select eq 1) then begin
			qthchce=1
			widget_control,done,sensitive=0
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=""
			widget_control,tthstepb,sensitive=1
			widget_control,Qstepb,sensitive=0
;			widget_control,tthvalb,sensitive=0
;			widget_control,Qvalb,sensitive=0
			widget_control,tthsteptext,get_value=calc_vals
;;			if (size(calc_vals,/n_dimensions) ne 0) then $
;;				qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
		endif
	end
;
	equalQ: begin
		if (event.select eq 1) then begin
			qthchce=2
			widget_control,done,sensitive=0
			widget_control,save,sensitive=0
			widget_control,ngro,set_value=""
			widget_control,tthstepb,sensitive=0
			widget_control,Qstepb,sensitive=1
;			widget_control,tthvalb,sensitive=0
;			widget_control,Qvalb,sensitive=0
			widget_control,qsteptext,get_value=calc_vals
;;			if (size(calc_vals,/n_dimensions) ne 0) then $
;;				qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
		endif
	end
;
;		speci2:begin
;			if (event.select eq 1) then begin
;				qthchce=3
;				widget_control,done,sensitive=0
;				widget_control,save,sensitive=0
;				widget_control,ngro,set_value=""
;				widget_control,tthstepb,sensitive=0
;				widget_control,Qstepb,sensitive=0
;				widget_control,tthvalb,sensitive=1
;				widget_control,Qvalb,sensitive=0
;				widget_control,tthvaltext,use_table_select=[0,0,0,100],get_value=calc_vals
;;;??				if (size(calc_vals,/n_dimensions) ne 0) then $
;;;??					qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
;			endif
;		end
;
;		speciQ: begin
;			if (event.select eq 1) then begin
;				qthchce=4
;				widget_control,done,sensitive=0
;				widget_control,save,sensitive=0
;				widget_control,ngro,set_value=""
;				widget_control,tthstepb,sensitive=0
;				widget_control,Qstepb,sensitive=0
;				widget_control,tthvalb,sensitive=0
;				widget_control,Qvalb,sensitive=1
;				widget_control,qvaltext,use_table_select=[0,0,0,100],get_value=calc_vals
;;;??				if (size(calc_vals,/n_dimensions) ne 0) then $
;;;??					qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
;			endif
;		end
;
	tthsteptext: begin
		widget_control,tthsteptext,get_value=calc_vals
		widget_control,done,sensitive=0
		widget_control,save,sensitive=0
		widget_control,ngro,set_value=""
	end
;
	qsteptext: begin
		widget_control,Qsteptext,get_value=calc_vals
		widget_control,done,sensitive=0
		widget_control,save,sensitive=0
		widget_control,ngro,set_value=""
	end
;
; NEVER CALLED: PROBABLY WRONG
;	tthvalentry:	begin
;		widget_control,tthvalentry,get_value=newval
;		if (np) then mintth=0.0 else mintth=tthmin
;		if (newval[0] gt mintth and newval[0] lt tthmax) then begin
;;			widget_control,tthvaltext,use_table_select=[0,0,0,100],get_value=oldvals
;			qthvals=float([newval[0],transpose(oldvals)])
;			qthvals=qthvals[sort(qthvals)]
;			qthvals=transpose(string(qthvals))
;;			widget_control,tthvaltext,use_table_select=[0,0,0,100],set_value=qthvals
;			widget_control,tthvalentry,set_value=" "
;			if (size(calc_vals,/n_dimensions) ne 0) then $
;				qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
;		endif else widget_control,tthvalentry,set_value="Illegal"
;	end
;
; NEVER CALLED: PROBABLY WRONG
;	qvalentry: begin
;		widget_control,qvalentry,get_value=newval
;		if (np) then minq=0.0 else minq=qmin
;		if (newval[0] gt minq and newval[0] lt qmax) then begin
;;			widget_control,qvaltext,use_table_select=[0,0,0,100],get_value=oldvals
;			qthvals=float([newval[0],transpose(oldvals)])
;			qthvals=qthvals[sort(qthvals)]
;			qthvals=transpose(string(qthvals))
;;			widget_control,qvaltext,use_table_select=[0,0,0,100],set_value=qthvals
;			widget_control,qvalentry,set_value=" "
;			if (size(calc_vals,/n_dimensions) ne 0) then $
;				qthvals=transpose(calc_vals) else qthvals=calc_vals[0]
;		endif else widget_control,qvalentry,set_value="Illegal"
;	end
;
endcase
;
*state.ptr_np=np
state.uml=uml
state.qthchce=qthchce
state.calc_vals=calc_vals
state.ngro=ngro
state.contents=contents
state.info=info
*state.ptr_gp=grouping
*state.ptr_elq=elasticqvals
;
widget_control,event.top,set_uvalue=state
end

;************************************************************************************************
pro dcs_choose_grouping,dcs_base,nhedet,lambda,skip,grouping,ngroups,$
	angle_props,Q_props,elasticqvals=elasticqvals,doQgrouping,do2thetagrouping
;************************************************************************************************
;
compile_opt strictarr
;
grouping=indgen(nhedet)+1
;
tthmin=-29.99
tthmax=139.99
qmin=4.0*!pi*sin(tthmin*0.5/!radeg)/lambda
qmax=4.0*!pi*sin(tthmax*0.5/!radeg)/lambda
;
;inputfile=file_which("dcs_DetPos2.dat",/include_current_dir)
inputfile=!DAVE_AUXILIARY_DIR+'dcs_DetPos2.dat'
;
content=strarr(nhedet+1)
;
openr,unit,inputfile,/get_lun
readf,unit,content
free_lun,unit
;
bank=[" 1"," 0","-1"]
contents=strarr(6,nhedet+1)
contents[0:4,0]=["Detector","Bank","Angle","''Q''","Group"]
contents[0,1:nhedet]=[string(grouping)]
;
angles=fltarr(nhedet)
Q_values=fltarr(nhedet)
;
np=0
;
for i=1,nhedet do begin
	pieces=strsplit(content[i]," ",/extract)
	contents[1,i]=bank[fix(pieces[6])+1]
	contents[2,i]=pieces[8]
	angles[i-1]=float(pieces[8])
	Q_values[i-1]=4.0*!pi*sin(angles[i-1]*0.5/!radeg)/lambda
	contents[3,i]=string(Q_values[i-1],format="(f7.3)")
	contents[4,i]=contents[0,i]
endfor
;
if (skip) then goto,skip_grouping
;
tlb=widget_base(title='Detector Grouping',/row,group_leader=dcs_base,/modal)
	leftpart=widget_base(tlb,/col)
		mainchoice=widget_base(leftpart,/nonexclusive)
			gng=widget_button(mainchoice,value="DO NOT GROUP DETECTORS")
		bbase=widget_base(leftpart,/col,/frame)
			bb1=widget_base(bbase,/col,/nonexclusive,/frame)
				negpos=widget_button(bb1,value="Combine negative and positive angle detectors")
			bb2=widget_base(bbase,/col,/exclusive,/frame)
				lomiup=widget_button(bb2,value="Combine lower, middle and upper banks")
				lowupp=widget_button(bb2,value="Combine lower and upper banks only")
				donotc=widget_button(bb2,value="Do not combine detector banks")
			bb3=widget_base(bbase,/col,/exclusive,/frame)
				equal2=widget_button(bb3,value="Combine into groups with equal widths in 2theta")
				equalQ=widget_button(bb3,value="Combine into groups with equal widths in ''Q''")
;				speci2=widget_button(bb3,value="Specify 2theta boundaries of detector groups")
;				speciQ=widget_button(bb3,value="Specify ''Q'' boundaries of detector groups")
			info=widget_list(bbase,ysize=5)
			qthbase=widget_base(bbase,/row,/align_center)
				tthstepb=widget_base(qthbase,/col,sensitive=0)
					tthsteplabel=widget_label(tthstepb,value='Step in 2theta')
					tthsteptext=widget_text(tthstepb,/editable,/all_events,xsize=10)
				qstepb=widget_base(qthbase,/col,sensitive=1)
					qsteplabel=widget_label(qstepb,value="Step in ''Q''")
					qsteptext=widget_text(qstepb,/editable,/all_events,xsize=10)
		calc=widget_button(leftpart,value="Assign detectors to groups")
		nxtrow=widget_base(leftpart,/row)
			ngro=widget_list(nxtrow,xsize=12)
			save=widget_button(nxtrow,sensitive=0,value="Save")
			restore=widget_button(nxtrow,sensitive=1,value="Restore")
			done=widget_button(nxtrow,sensitive=0,value="Proceed")
;			qthvalbase=widget_base(bbase,/row,/align_center)
;				tthvalb=widget_base(qthvalbase,/col,sensitive=0,/align_center)
;					tthvallabel=widget_label(tthvalb,value='Values of 2theta')
;					tthvalentry=widget_text(tthvalb,/editable)
;					tthvaltext=widget_table(tthvalb,xsize=1,ysize=20,/scroll,/no_headers,column_width=80,alignment=2)
;				qvalb=widget_base(qthvalbase,/col,sensitive=0,/align_center)
;					qvallabel=widget_label(qvalb,value="Values of ''Q''")
;					qvalentry=widget_text(qvalb,/editable)
;					qvaltext=widget_table(qvalb,xsize=1,ysize=20,/scroll,/no_headers,column_width=80,alignment=2)
	dpt=widget_table(tlb,xsize=6,ysize=nhedet+1,x_scroll_size=6,y_scroll_size=18,$
		column_widths=[50,50,50,50,50,5],/no_headers,/scroll,alignment=1,value=contents)
;
centertlb,tlb
widget_control,tlb,/realize
;
widget_control,info,set_value=[$
	"Incident wavelength  "+string(lambda,format="(f8.3)")+" A",$
	"Minimum 2theta  "+string(tthmin,format="(f8.2)")+" deg",$
	"Maximum 2theta  "+string(tthmax,format="(f8.2)")+" deg",$
	"Minimum ''Q''   "+string(qmin,format="(f8.3)")+" A-1",$
	"Maximum ''Q''   "+string(qmax,format="(f8.3)")+" A-1"]
;
widget_control,negpos,set_button=1
widget_control,lomiup,set_button=1
widget_control,equalq,set_button=1
;
np=1
uml=1
qthchce=2
widget_control,tthsteptext,set_value=string(" 10.0")
calc_vals=string(fix(qmax/15/0.01)*0.01,format="(f6.2)")
widget_control,qsteptext,set_value=calc_vals
;
ptr_gp=ptr_new(grouping)
ptr_np=ptr_new(np)
ptr_elq=ptr_new(np)
;
state={nhedet:nhedet,$
	done:done,$
	gng:gng,$
	ngro:ngro,$
	dpt:dpt,$
	bbase:bbase,$
	negpos:negpos,$
	lomiup:lomiup,$
	lowupp:lowupp,$
	donotc:donotc,$
	equalQ:equalQ,$
	equal2:equal2,$
	speciQ:-1,$;speciQ,$
	speci2:-1,$;speci2,$
	qstepb:qstepb,$
	tthstepb:tthstepb,$
	qvalb:-1,$;qvalb,$
	tthvalb:-1,$;tthvalb,$
	qsteptext:qsteptext,$
	tthsteptext:tthsteptext,$
	qvaltext:-1,$;qvaltext,$
	tthvaltext:-1,$;tthvaltext,$
	qvalentry:-1,$;qvalentry,$
	tthvalentry:-1,$;tthvalentry,$
	save:save,$
	restore:restore,$
	calc:calc,$
	nxtrow:nxtrow,$
	bb1:bb1,$
	bb2:bb2,$
	bb3:bb3,$
	ptr_np:ptr_np,$
	uml:uml,$
	qthchce:qthchce,$
	calc_vals:calc_vals,$
	contents:contents,$
	lambda:lambda,$
	info:info,$
	tthmin:tthmin,$
	tthmax:tthmax,$
	qmin:qmin,$
	qmax:qmax,$
	ptr_gp:ptr_gp,$
	ptr_elq:ptr_elq}
;
widget_control,tlb,set_uvalue=state
;
widget_control,gng,set_button=0
dcs_choose_grouping_handler,{id:gng,top:tlb,handler:0l,select:0}
dcs_choose_grouping_handler,{id:calc,top:tlb,handler:0l}
;
xmanager,'dcs_choose_grouping',tlb,event_handler='dcs_choose_grouping_handler'
;
grouping=*state.ptr_gp
ptr_free,ptr_gp
;
np=*state.ptr_np
ptr_free,ptr_np
;
elasticqvals=*state.ptr_elq
ptr_free,ptr_elq
;
skip_grouping:
;
ngroups=max(grouping)
;
angle_props=fltarr(ngroups,3)
Q_props=fltarr(ngroups,3)
;
if (np) then begin
	angles=abs(angles)
	Q_values=abs(Q_values)
endif
;
for ig=0,ngroups-1 do begin
	list=where(grouping eq ig+1)
	angle_props[ig,0]=mean(angles[list])
	Q_props[ig,0]=mean(Q_values[list])
	angle_props[ig,1]=min(angles[list])
	Q_props[ig,1]=min(Q_values[list])
	angle_props[ig,2]=max(angles[list])
	Q_props[ig,2]=max(Q_values[list])
endfor
;
if (ngroups eq 1 or ngroups eq nhedet or do2thetagrouping) then doQgrouping=0 else begin
	outstring=["You can choose to group in 2theta or in Q.",$
		"If you group in 2theta the grouping is the same for all energy transfers.",$
		"If you group in Q the grouping of detector information depends on the energy transfer.",$
		" ","Click on one of the buttons below.",""]
	maxlen=60
	blabel=['2theta grouping','Q grouping']
	def_button=0
	can_button=1
	dcs_multichoice_modal,outstring,decision,blabel,def_button,$
		group_leader=dcs_base,alignment=-1
	doQgrouping=decision eq 1
endelse
;
end
