; $Id: dcs_timechannels_time.pro,v 1.2 2005/02/14 17:50:34 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_timechannels_time_handler,event
;************************************************************************************************
;
compile_opt strictarr
;
;
widget_control,event.top,get_uvalue=pstate
;
nmax=(*pstate).nmax
nmhz=(*pstate).nmhz
nrow=(*pstate).nrow
;
; These are the widget IDs
base2b=(*pstate).base2b
nchn=(*pstate).nchn
delt=(*pstate).delt
nchn=(*pstate).nchn
ntik=(*pstate).ntik
prod=(*pstate).prod
tmin=(*pstate).tmin
tmax=(*pstate).tmax
emin=(*pstate).emin
emax=(*pstate).emax
togglemode=(*pstate).togglemode
save=(*pstate).save
savehi=(*pstate).savehi
exit=(*pstate).exit
;
; These are the quantities.
nchnv=(*pstate).nchnv
deltv=(*pstate).deltv
ntikv=(*pstate).ntikv
prodv=(*pstate).prodv
tminv=(*pstate).tminv
tmaxv=(*pstate).tmaxv
eminv=(*pstate).eminv
emaxv=(*pstate).emaxv
;
; Respond to "Exit" button.
if (event.id eq exit) then begin
	widget_control,event.top,/destroy
	ptr_free,pstate
	return
endif
;
; Respond to "Toggle mode" button.
if (event.id eq togglemode) then begin
	res=widget_info(delt[nrow-3],/text_editable)
	widget_control,delt[nrow-3],editable=1-res
	if (res) then widget_control,togglemode,set_value="VARY high end channel width  " $
		else widget_control,togglemode,set_value="FORCE low and high end channel widths  "
endif
;
; Loop over rows.
for k=0,nrow-2 do begin
	case event.id of
		nchn[k]: begin; Respond to modified value of number of channels.
			widget_control,nchn[k],get_value=nchn_new
			nchnv[k]=nchn_new
			if (nchnv[k] ne 0) then $
				widget_control,nchn[k],set_value=strcompress(string(nchnv[k],format='(i6)'))
	end
		delt[k]: begin; Respond to modified value of channel width.
			widget_control,delt[k],get_value=delt_new
			deltv[k]=delt_new
			if (deltv[k] ne 0) then $
				widget_control,delt[k],set_value=strcompress(string(deltv[k],format='(f8.3)'))
		end
		else:
	endcase
	ntikv[k]=deltv[k]*nmhz
	prodv[k]=nchnv[k]*deltv[k]
;
	if (ntikv[k] ne 0) then $
		widget_control,ntik[k],set_value=strcompress(string(ntikv[k],format='(i6)'))
	if (prodv[k] ne 0) then $
		widget_control,prod[k],set_value=strcompress(string(prodv[k],format='(f8.2)'))
endfor
;
nchnv[nrow-3]=nmax-1-total(nchnv[0:nrow-4])
res=widget_info(delt[nrow-3],/text_editable)
if (not res) then deltv[nrow-3]=deltv[0]
ntikv[nrow-3]=deltv[nrow-3]*nmhz
prodv[nrow-3]=nchnv[nrow-3]*deltv[nrow-3]
;
nchnv[nrow-2]=1
period=(*pstate).srd*6.0e7/(*pstate).ms
deltv[nrow-2]=period-total(nchnv[0:nrow-3]*deltv[0:nrow-3])
ntikv[nrow-2]=deltv[nrow-2]*nmhz
prodv[nrow-2]=nchnv[nrow-2]*deltv[nrow-2]
;
nchnv[nrow-1]=total(nchnv[0:nrow-2])
prodv[nrow-1]=total(prodv[0:nrow-2])
;
widget_control,nchn[nrow-3],set_value=strcompress(string(nchnv[nrow-3],format='(i6)'))
widget_control,delt[nrow-3],set_value=strcompress(string(deltv[nrow-3],format='(f8.3)'))
widget_control,ntik[nrow-3],set_value=strcompress(string(ntikv[nrow-3],format='(i6)'))
widget_control,prod[nrow-3],set_value=strcompress(string(prodv[nrow-3],format='(f8.2)'))
widget_control,nchn[nrow-2],set_value=strcompress(string(nchnv[nrow-2],format='(i6)'))
widget_control,delt[nrow-2],set_value=strcompress(string(deltv[nrow-2],format='(f8.3)'))
widget_control,ntik[nrow-2],set_value=strcompress(string(ntikv[nrow-2],format='(i6)'))
widget_control,prod[nrow-2],set_value=strcompress(string(prodv[nrow-2],format='(f8.2)'))
widget_control,nchn[nrow-1],set_value=strcompress(string(nchnv[nrow-1],format='(i6)'))
widget_control,prod[nrow-1],set_value=strcompress(string(prodv[nrow-1],format='(f8.2)'))
;
for k=0,nrow-2 do begin
	if (k gt 0) then tminv[k]=tmaxv[k-1]
	tmaxv[k]=tminv[k]+prodv[k]
	e0=!dcs_hsq2mn/(*pstate).wl^2
	eminv[k]=e0-!dcs_hsq2mn/(!dcs_hom*tminv[k]/!dcs_dsd)^2
	emaxv[k]=e0-!dcs_hsq2mn/(!dcs_hom*tmaxv[k]/!dcs_dsd)^2
	if (prodv[k] ne 0) then begin
		widget_control,prod[k],set_value=strcompress(string(prodv[k],format='(f8.2)'))
		widget_control,tmin[k],set_value=strcompress(string(tminv[k],format='(f10.2)'))
		widget_control,tmax[k],set_value=strcompress(string(tmaxv[k],format='(f10.2)'))
		widget_control,emin[k],set_value=strcompress(string(eminv[k],format='(f10.3)'))
		widget_control,emax[k],set_value=strcompress(string(emaxv[k],format='(f10.3)'))
	endif
endfor
;
(*pstate).nchnv=nchnv
(*pstate).deltv=deltv
(*pstate).ntikv=ntikv
(*pstate).prodv=prodv
(*pstate).tminv=tminv
(*pstate).tmaxv=tmaxv
(*pstate).eminv=eminv
(*pstate).emaxv=emaxv
;
nogood=0
for k=0,nrow-2 do begin
	nogood=prodv[k] lt 0
endfor
;
summary="         SUMMARY"
if (nogood) then message="NO GOOD" else message=summary
widget_control,base2b,set_value=message
;
if (nogood) then begin
	res=dialog_message(message,/error)
endif else begin
	dcs_simplifytchannels,nchnv,ntikv,nchnv0,ntikv0
	message=[summary," ",$
		string(nchnv0,format='(i6)')+" chnls of "+string(ntikv0,format='(f8.2)')+" us"]
	widget_control,base2b,set_value=message
endelse
;
; Respond to "Create time channel width file" button.
if (event.id eq save and not nogood) then begin
	times=intarr(nchnv0[0])+ntikv0[0]
	nsec=n_elements(nchnv0)
	if (nsec gt 1) then for k=1,nsec-1 do times=[times,intarr(nchnv0[k])+ntikv0[k]]
	ntimes=n_elements(times)
	times=[times,intarr(1023-ntimes)+20]
	times=[times,2l^20-long(total(times))]
	filename=dialog_pickfile(title="Select output file name",file="tchanlook.dat")
	if (filename[0] eq "") then x=dialog_message("No file selected.") else begin
		openw,unit,filename,/get_lun
		for k=0,1023 do printf,unit,strcompress(times[k])
		free_lun,unit
		res=dialog_message("File "+filename+" has been written.",/information)
	endelse
endif
;
; Respond to "Create equal time channel width file" button.
if (event.id eq savehi) then begin
	Period=(*pstate).srd*6.0e7/(*pstate).ms
	dt_VME=0.05
	tstep=fix(Period*0.001/dt_VME)
	times=intarr(1000)+tstep
	times=[times,intarr(23)+20]
	times=[times,2l^20-long(total(times))]
	filename=dialog_pickfile(title="Select output file name",file="tchanhi.dat")
	if (filename[0] eq "") then x=dialog_message("No file selected.") else begin
		openw,unit,filename,/get_lun
		for k=0,1023 do printf,unit,strcompress(times[k])
		free_lun,unit
		res=dialog_message("File "+filename+" has been written.",/information)
	endelse
endif
;
widget_control,event.top,set_uvalue=pstate
;
end


;************************************************************************************************
pro dcs_timechannels_time_input,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pstate
winput=(*pstate).winput
widget_control,winput,get_value=input
p=strsplit(input[0],",",/extract)
;
nmax=(*pstate).nmax
nmhz=(*pstate).nmhz
nrow=(*pstate).nrow
;
if (n_elements(p) eq 4) then begin
	wl=p[0]
	ms=p[1]
	srd=p[2]
	tsdmin=p[3]
	widget_control,(*pstate).info[0],set_value=string(wl,format='(f10.3)')+" A"
	widget_control,(*pstate).info[1],set_value=string(ms,format='(f10.1)')+" rpm"
	widget_control,(*pstate).info[2],set_value=string(srd,format='(i3)')
	widget_control,(*pstate).info[3],set_value=string(tsdmin,format='(f10.1)')+" us"
	period=srd*6.0e7/ms
	tsdmax=tsdmin+period
	e0=!dcs_hsq2mn/wl^2
	(*pstate).etmin=e0-!dcs_hsq2mn/(!dcs_hom*tsdmin/!dcs_dsd)^2
	(*pstate).etmax=e0-!dcs_hsq2mn/(!dcs_hom*tsdmax/!dcs_dsd)^2
	widget_control,(*pstate).info[4],set_value=string((*pstate).etmin,$
		format='(f10.3)')+" meV"
	widget_control,(*pstate).info[5],set_value=string((*pstate).etmax,$
		format='(f10.3)')+" meV"
	widget_control,(*pstate).info[6],set_value=string(e0,$
		format='(f10.3)')+" meV"
;
	(*pstate).tminv=fltarr((*pstate).nrow)
	(*pstate).tmaxv=fltarr((*pstate).nrow)
	(*pstate).eminv=fltarr((*pstate).nrow)
	(*pstate).emaxv=fltarr((*pstate).nrow)
;
	(*pstate).nchnv[0]=nmax
	(*pstate).deltv[0]=(tsdmax-tsdmin)/nmax
	(*pstate).ntikv[0]=(*pstate).deltv[0]*nmhz
	(*pstate).prodv[0]=(*pstate).nchnv[0]*(*pstate).deltv[0]
	(*pstate).tminv[0]=tsdmin
	(*pstate).tmaxv[0]=tsdmax
	(*pstate).eminv[0]=(*pstate).etmin
	(*pstate).emaxv[0]=(*pstate).etmax
;
	for k=0,(*pstate).nrow-1 do begin
		if ((*pstate).nchnv[k] ne 0) then $
			widget_control,(*pstate).nchn[k],set_value=strcompress(string((*pstate).nchnv[k],format='(i6)'))
		if ((*pstate).deltv[k] ne 0) then $
			widget_control,(*pstate).delt[k],set_value=strcompress(string((*pstate).deltv[k],format='(f8.3)'))
		if ((*pstate).ntikv[k] ne 0) then $
			widget_control,(*pstate).ntik[k],set_value=strcompress(string((*pstate).ntikv[k],format='(i6)'))
		if ((*pstate).prodv[k] ne 0) then $
			widget_control,(*pstate).prod[k],set_value=strcompress(string((*pstate).prodv[k],format='(f8.2)'))
		if ((*pstate).tminv[k] ne 0) then $
			widget_control,(*pstate).tmin[k],set_value=strcompress(string((*pstate).tminv[k],format='(f10.2)'))
		if ((*pstate).tmaxv[k] ne 0) then $
			widget_control,(*pstate).tmax[k],set_value=strcompress(string((*pstate).tmaxv[k],format='(f10.2)'))
		if ((*pstate).eminv[k] ne 0) then $
			widget_control,(*pstate).emin[k],set_value=strcompress(string((*pstate).eminv[k],format='(f10.3)'))
		if ((*pstate).emaxv[k] ne 0) then $
			widget_control,(*pstate).emax[k],set_value=strcompress(string((*pstate).emaxv[k],format='(f10.3)'))
	endfor
;
	(*pstate).wl=wl
	(*pstate).ms=ms
	(*pstate).srd=srd
	(*pstate).tsdmin=tsdmin
endif
;
widget_control,event.top,set_uvalue=pstate
;
dcs_timechannels_time_handler,{id:0,top:event.top,handler:0}
;
end


;************************************************************************************************
pro dcs_timechannels_time
;************************************************************************************************
;
compile_opt strictarr
;
;
davesysvars
defsysv,'!dcs_hom',(!dave_planck/!dave_nmass)*1.e7
defsysv,'!dcs_mevcon',!dave_e*1.e4
defsysv,'!dcs_hsq2mn',(!dave_planck*1.e7)^2/(2.0*!dave_nmass)/!dcs_mevcon*1.e13
;
defsysv,'!dcs_dsd',4010.0
;
nmax=1000
nmhz=20
nrow=9
;
rowb=lonarr(nrow,/nozero)
nchn=lonarr(nrow)
delt=lonarr(nrow)
ntik=lonarr(nrow)
prod=lonarr(nrow)
tmin=lonarr(nrow)
tmax=lonarr(nrow)
emin=lonarr(nrow)
emax=lonarr(nrow)
;
nchnv=intarr(nrow)
deltv=fltarr(nrow)
ntikv=lonarr(nrow)
prodv=fltarr(nrow)
tminv=fltarr(nrow)
tmaxv=fltarr(nrow)
eminv=fltarr(nrow)
emaxv=fltarr(nrow)
;
info=lonarr(8,/nozero)
;
initial_string=" 7.0, 20000, 4, 500"
;
title='Generation of piecewise constant time width time channels.'
tlb=widget_base(title=title,/col)
	void=widget_label(tlb,/align_left,value="Enter wavelength, master speed, "+$
		"slow chopper speed ratio denominator, and tsdmin, separated by commas")
	winput=widget_text(tlb,/editable,event_pro="dcs_timechannels_time_input",$
		value=initial_string)
	infobase=widget_base(tlb,/row)
		info[0]=cw_field(infobase,xsize=12,title="Wavelength",/noedit,/column)
		info[1]=cw_field(infobase,xsize=12,title="Master Speed",/noedit,/column)
		info[2]=cw_field(infobase,xsize=8,title="SR Denom.",/noedit,/column)
		info[3]=cw_field(infobase,xsize=12,title="''tsdmin''",/noedit,/column)
		info[4]=cw_field(infobase,xsize=12,title="Min. Etransfer",/noedit,/column)
		info[5]=cw_field(infobase,xsize=12,title="Max. Etransfer",/noedit,/column)
		info[6]=cw_field(infobase,xsize=12,title="Incident energy",/noedit,/column)
		info[7]=cw_field(infobase,xsize=8,title="# channels",/noedit,/column,value=nmax)
	;

	base2=widget_base(tlb,/row)
	base2a=widget_base(base2,/col)
	for i=0,nrow-1 do begin
		if (i eq nrow-1) then begin
			dummy=widget_base(base2a,/row)
			dummy2=widget_label(dummy,value="",scr_ysize=1)
		endif
		rowb[i]=widget_base(base2a,/row)
		nchn[i]=widget_text(rowb[i],xsize=6,editable=(i lt nrow-3));,/tracking_events)
		delt[i]=widget_text(rowb[i],xsize=8,editable=(i lt nrow-2));,/tracking_events)
		ntik[i]=widget_text(rowb[i],xsize=6)
		prod[i]=widget_text(rowb[i],xsize=8)
		tmin[i]=widget_text(rowb[i],xsize=10)
		tmax[i]=widget_text(rowb[i],xsize=10)
		emin[i]=widget_text(rowb[i],xsize=10)
		emax[i]=widget_text(rowb[i],xsize=10)
	endfor
	base2b=widget_text(base2,xsize=24,ysize=20)
	;
	bottomline0=widget_base(tlb,/row)
		togglemode=widget_button(bottomline0,value="FORCE low and high end channel widths  ")
	bottomline2=widget_base(tlb,/row)
		save=widget_button(bottomline2,value="Create time channel width file for He-3 detectors")
	bottomline3=widget_base(tlb,/row)
		savehi=widget_button(bottomline3,value="Create equal time channel width file (for beam monitors etc)")
	bottomline4=widget_base(tlb,/row)
		exit=widget_button(bottomline4,value="Exit")
;
centertlb,tlb
widget_control,tlb,/realize
;
pstate=ptr_new({base2b:base2b,rowb:rowb,$
	nchn:nchn,delt:delt,ntik:ntik,prod:prod,$
	tmin:tmin,tmax:tmax,emin:emin,emax:emax,$
	nmax:nmax,nmhz:nmhz,nrow:nrow,winput:winput,etmin:0.0,etmax:0.0,$
	nchnv:nchnv,deltv:deltv,ntikv:ntikv,prodv:prodv,$
	tminv:tminv,tmaxv:tmaxv,eminv:eminv,emaxv:emaxv,$
	info:info,wl:0.0,ms:0.0,srd:0,tsdmin:0.0,save:save,$
	savehi:savehi,togglemode:togglemode,exit:exit})
;
widget_control,tlb,set_uvalue=pstate,/no_copy
;
dcs_timechannels_time_input,{id:0,top:tlb,handler:0}
;
xmanager,'dcs_timechannels_time',tlb,event_handler='dcs_timechannels_time_handler'
;
end