; $Id: dcs_plotdetmask.pro,v 1.11 2007/11/08 21:06:31 jrdcopley 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_plotdetmaskQuit,event
;************************************************************************************************
; Trivial quit routine.
;
compile_opt strictarr
;
widget_control,event.top,/destroy
return
end


;************************************************************************************************
pro dcs_plotdetmaskCleanup,tlb
;************************************************************************************************
; Cleanup routine.
;
compile_opt strictarr
;
widget_control,tlb,get_uvalue = pState,/no_copy
tmpmask=*(*pState).ptr
ptr_free,(*pState).ptr
*(*pState).pblist=intarr((*pState).nhedet)
templist=where(tmpmask eq 0,nblist)
if (nblist gt 0) then (*(*pState).pblist)[0:nblist-1]=templist+1
;
; Revert to color table in existence at start of procedure.
tvlct,(*pState).oldct
;
DEVICE,DECOMPOSED=(*PSTATE).OLD_DECOMP
;
ptr_free,pState
;
return
end


;************************************************************************************************
pro dcs_plot_histo,x,y,xlo,xhi,nhedet
;************************************************************************************************
;
compile_opt strictarr
;
np=n_elements(x)
xx=0.5*(x[0:np-2]+x[1:np-1])
xx=reform(transpose([[xx],[xx]]),2*np-2)
xx=[x[0],xx,x[np-1]]
yy=reform(transpose([[y],[y]]),2*np)*1.00
keep=where(xlo le xx and xx le xhi)
nkeep=n_elements(keep)
xx=xx[keep]
yy=yy[keep]
if (keep[0] gt 0) then begin
	xx=[x[keep[0]/2],xx]
	yy=[y[keep[0]/2],yy]
endif
nkeep=n_elements(keep)
if (keep[nkeep-1] lt 2*nhedet-1) then begin
	xx=[xx,x[keep[nkeep-1]/2]]
	yy=[yy,y[keep[nkeep-1]/2]]
endif
np=n_elements(xx)
xmin=!x.crange[0] > 1
xmax=!x.crange[1] < nhedet
xx=[xmin,xmin,xx[1:np-2],xmax,xmax]
yy=[0.0,yy,0.0]
polyfill,xx,yy,/line_fill,orientation=45,color=3
polyfill,xx,yy,/line_fill,orientation=135,color=3
end


;************************************************************************************************
pro dcs_plotdetmask_replot,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pstate
;
if (event.id ne (*pstate).undozoom) then begin
	(*pstate).xloprev=(*pstate).xlo
	(*pstate).xhiprev=(*pstate).xhi
	(*pstate).yloprev=(*pstate).ylo
	(*pstate).yhiprev=(*pstate).yhi
	widget_control,(*pstate).undozoom,/sensitive
endif
;
; Respond to upper slider.
if (event.id eq (*pstate).mindetnum) then begin
	(*pstate).xmin=event.value
	xlo=(*pstate).xmin
	xhi=(*pstate).xmax
endif
;
; Respond to lower slider.
if (event.id eq (*pstate).maxdetnum) then begin
	(*pstate).xmax=event.value
	xlo=(*pstate).xmin
	xhi=(*pstate).xmax
endif
;
; Respond to "plot all detectors" button.
if (event.id eq (*pstate).alldet) then begin
	xlo=min((*pstate).x)
	xhi=max((*pstate).x)
endif
;
; Respond to "plot selected detectors" button.
if (event.id eq (*pstate).somdet) then begin
	xlo=(*pstate).xmin
	xhi=(*pstate).xmax
	widget_control,(*pstate).mindetnum,set_value=xlo
	widget_control,(*pstate).maxdetnum,set_value=xhi
endif
;
if (event.id ne (*pstate).undozoom) then begin
	if (xlo gt xhi) then begin
		xtmp=xhi
		xhi=xlo
		xlo=xtmp
		widget_control,(*pstate).mindetnum,set_value=xlo
		widget_control,(*pstate).maxdetnum,set_value=xhi
		(*pstate).xmin=xlo
		(*pstate).xmax=xhi
	endif
;
	if ((*pstate).xzoom) then begin
		ylo=min((*pstate).y)
		yhi=max((*pstate).y)
	endif else begin
		ylo=(*pstate).ymin
		yhi=(*pstate).ymax
	endelse
endif
;
; Respond to "undo zoom" button.
if (event.id eq (*pstate).undozoom) then begin
	xlo=(*pstate).xloprev
	xhi=(*pstate).xhiprev
	ylo=(*pstate).yloprev
	yhi=(*pstate).yhiprev
	if (xlo gt 1 or xhi lt (*pstate).nhedet) then begin
		widget_control,(*pstate).mindetnum,set_value=xlo
		widget_control,(*pstate).maxdetnum,set_value=xhi
	endif
	widget_control,(*pstate).undozoom,sensitive=0
endif
;
; Replot detector sums.
y=(*pstate).y
y2=y*(*(*pstate).ptr)
plot,(*pstate).x,y,psym=(*pstate).psym,symsize=(*pstate).symsize,$
	xrange=[xlo,xhi],yrange=[ylo,yhi],color=(*pstate).color1,xstyle=1,$
	xtitle=(*pstate).xtitle,ytitle=(*pstate).ytitle,/NODATA,thick=1
oplot,(*pstate).x,y,psym=(*pstate).psym,symsize=(*pstate).symsize,$
	color=(*pstate).color2,thick=1
dcs_plot_histo,(*pstate).x,y2,xlo,xhi,(*pstate).nhedet
oplot,(*pstate).x,y2,psym=(*pstate).psym,symsize=(*pstate).symsize,$
	color=(*pstate).color1,thick=1
(*pstate).xlo=xlo
(*pstate).xhi=xhi
;
;widget_control,event.top,set_uvalue=pstate,/no_copy
end


;************************************************************************************************
pro dcs_plotdetmask_cursor,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pstate
;
xandy=convert_coord(event.x,event.y,/device,/to_data)
xc=fix(xandy[0]+0.5)
yc=fix(xandy[1]+0.5)
;
; Respond to mouse button press: this defines one limit of operation/plot.
if (event.type eq 0) then begin
	case event.press of
		1: begin
			widget_control,(*pstate).mindetnum,set_value=xc
			(*pstate).xmin=xc
			(*pstate).ymin=yc
		end
		4:(*pstate).xminmsk=xc
		else:
	endcase
endif
;
; Respond to mouse button release: this defines other limit of operation/plot.
if (event.type eq 1) then begin
	case event.release of
		1: begin
			widget_control,(*pstate).maxdetnum,set_value=xc
			(*pstate).xmax=xc
			(*pstate).ymax=yc
		end
		4: begin
			if (xc ge (*pstate).xminmsk) then begin
				(*pstate).xmaxmsk=xc
			endif else begin
				(*pstate).xmaxmsk=(*pstate).xminmsk
				(*pstate).xminmsk=xc
			endelse
			minvalu=((*pstate).xminmsk-1) > 0
			maxvalu=((*pstate).xmaxmsk-1) < ((*pstate).nhedet-1)
			(*(*pstate).ptr)[minvalu:maxvalu]=1-(*pstate).maskem
		end
		else: return
	endcase
;
;	Replot detector sums.
	case event.release of
		1: begin
			(*pstate).xloprev=(*pstate).xlo
			(*pstate).xhiprev=(*pstate).xhi
			(*pstate).yloprev=(*pstate).ylo
			(*pstate).yhiprev=(*pstate).yhi
			widget_control,(*pstate).undozoom,/sensitive
			xlo=(*pstate).xmin<(*pstate).xmax
			xhi=(*pstate).xmin>(*pstate).xmax
			if (xlo eq xhi) then begin
				xlo=1
				xhi=(*pstate).nhedet
			endif
			widget_control,(*pstate).mindetnum,set_value=xlo
			widget_control,(*pstate).maxdetnum,set_value=xhi
			(*pstate).xmin=xlo
			(*pstate).xmax=xhi
			if ((*pstate).xzoom) then begin
				ylo=min((*pstate).y)
				yhi=max((*pstate).y)
			endif else begin
				ylo=(*pstate).ymin<(*pstate).ymax > 0
				yhi=(*pstate).ymin>(*pstate).ymax
				(*pstate).ymin=ylo
				(*pstate).ymax=yhi
			endelse
		end
		4: begin
			xlo=(*pstate).xlo
			xhi=(*pstate).xhi
			ylo=(*pstate).ylo
			yhi=(*pstate).yhi
		end
		else: return
	endcase
;
	y=(*pstate).y
	y2=y*(*(*pstate).ptr)
	plot,(*pstate).x,y,psym=(*pstate).psym,symsize=(*pstate).symsize,$
		xrange=[xlo,xhi],yrange=[ylo,yhi],color=(*pstate).color1,xstyle=1,$
		xtitle=(*pstate).xtitle,ytitle=(*pstate).ytitle,/NODATA,thick=1
	oplot,(*pstate).x,y,psym=(*pstate).psym,symsize=(*pstate).symsize,$
		color=(*pstate).color2,thick=1
	dcs_plot_histo,(*pstate).x,y2,xlo,xhi,(*pstate).nhedet
	oplot,(*pstate).x,y2,psym=(*pstate).psym,symsize=(*pstate).symsize,$
		color=(*pstate).color1,thick=1
	(*pstate).xlo=xlo
	(*pstate).xhi=xhi
endif
;
; Respond to mouse button movement: update information displayed.
if (event.type eq 2) then begin
	if (!x.crange[0] le xc and xc le !x.crange[1] and $
			!y.crange[0] le yc and yc le !y.crange[1] and $
			xc ge 1 and xc le (*pstate).nhedet) then begin
		yc=(*pstate).y[xc-1]
		widget_control,(*pstate).infod,set_value="Detector"+string(fix(xc),format='(i4)')
		widget_control,(*pstate).infoi,set_value="Intensity"+string(fix(yc),format='(i8)')
	endif
endif
;
;widget_control,event.top,set_uvalue=pstate,/no_copy
;
end


;************************************************************************************************
pro dcs_plotdetmask_handler,event
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pstate
;
; Respond to " MASK "/"UNMASK" button.
if (event.id eq (*pstate).infom) then begin
	if ((*pstate).maskem eq 1) then value="UNMASK"
	if ((*pstate).maskem eq 0) then value=" MASK "
	(*pstate).maskem=1-(*pstate).maskem
	widget_control,(*pstate).infom,set_value=value
endif
;
; Respond to " X ZOOM"/"XY ZOOM" button.
if (event.id eq (*pstate).infoz) then begin
	if ((*pstate).xzoom eq 1) then value="XY ZOOM"
	if ((*pstate).xzoom eq 0) then value=" X ZOOM"
	(*pstate).xzoom=1-(*pstate).xzoom
	widget_control,(*pstate).infoz,set_value=value
endif
;
; Respond to "PROCEED" button.
if (event.id eq (*pstate).done) then begin
	wdelete,(*pstate).winvis
	dcs_plotdetmaskQuit,event
	return
endif
;
; Respond to "Help" button.
if (event.id eq (*pstate).help) then $
	res=dialog_message(dialog_parent=event.top,(*pstate).helptext2,/information)
;
;widget_control,event.top,set_uvalue=pstate,/no_copy
;
end


;************************************************************************************************
pro dcs_plotdetmask,base,file,detsum,pblist,helptext2
;************************************************************************************************
; This procedure is used to plot detector sums.
;
compile_opt strictarr
;
DEVICE,GET_DECOMPOSED=OLD_DECOMP
DEVICE,DECOMPOSED=0
;
; Number of detectors.
nhedet=n_elements(detsum)
;
; Set up the top level widget.
xoffset=!screensize[0]*0.00
yoffset=!screensize[1]*0.08
xsize=!screensize[0]*0.60
ysize=!screensize[0]*0.40
tlb=widget_base(title="Detector sum, "+file,/col,/floating,$
	xoffset=xoffset,yoffset=yoffset,xsize=xsize,ysize=ysize,/modal,$
	group_leader=base)
;
; Information base.
infobase=widget_base(tlb,/row)
infod=widget_text(infobase,xsize=12,value="Detector")
infoi=widget_text(infobase,xsize=17,value="Intensity")
infoz=widget_button(infobase,value=" X ZOOM")
infom=widget_button(infobase,value=" MASK ")
;
; Plot window.
plotwin=widget_draw(tlb,/motion_events,/button_events,xsize=xsize*1.0,ysize=ysize*0.6,$
	event_pro='dcs_plotdetmask_cursor')
;
; Sliders.
mindetnum=widget_slider(tlb,min=1,max=nhedet,value=1,event_pro='dcs_plotdetmask_replot')
maxdetnum=widget_slider(tlb,min=1,max=nhedet,value=nhedet,event_pro='dcs_plotdetmask_replot')
;
; Buttons.
bbase=widget_base(tlb,/row,/align_right)
help=widget_button(bbase,value='Help')
somdet=widget_button(bbase,value='Show selected range of detectors',$
	event_pro='dcs_plotdetmask_replot')
alldet=widget_button(bbase,value='Show all detectors',event_pro='dcs_plotdetmask_replot')
undozoom=widget_button(bbase,value='Undo zoom',event_pro='dcs_plotdetmask_replot',$
	sensitive=0)
done=widget_button(bbase,value='PROCEED')
;
; Realize the widget.
dave_position_tlb,tlb
widget_control,tlb,/realize
;
widget_control,plotwin,get_value=winvis
wshow,winvis,1
wset,winvis
;
; Create the initial plot.
x=findgen(nhedet)+1
tmpmask=bytarr(nhedet)+1
templist=where(*pblist gt 0,nblist)
if (nblist gt 0) then tmpmask[(*pblist)[templist]-1]=0
y=detsum
xlo=min(x)
xhi=max(x)
ylo=min(y)
yhi=max(y)
psym=10
symsize=0.25
xtitle="Detector number"
ytitle="Intensity"
;
; Save current color table.
oldct=dcs_getctinfo()
; Use Alan's routine to load 256 colors.
tvlct,!dave_colors.red,!dave_colors.green,!dave_colors.blue
color1=1
color2=2
;
plot,x,detsum,psym=psym,symsize=symsize,xrange=[xlo,xhi],yrange=[ylo,yhi],$
	color=color1,thick=2,xstyle=1,xtitle=xtitle,ytitle=ytitle,/NODATA
oplot,x,detsum,psym=psym,symsize=symsize,color=color2,thick=1
dcs_plot_histo,x,detsum*tmpmask,xlo,xhi,nhedet
oplot,x,detsum*tmpmask,psym=psym,symsize=symsize,color=color1,thick=1
;
; Get set to manage the widget.
ptr=ptr_new(tmpmask,/no_copy)
;
state={x:x,$
	y:y,$
	xmin:1,$
	xmax:nhedet,$
	ymin:ylo,$
	ymax:ylo,$
	infod:infod,$
	infoi:infoi,$
	infom:infom,$
	infoz:infoz,$
	done:done,$
	help:help,$
	helptext2:helptext2,$
	winvis:winvis,$
	alldet:alldet,$
	somdet:somdet,$
	mindetnum:mindetnum,$
	maxdetnum:maxdetnum,$
	nhedet:nhedet,$
	psym:psym,$
	symsize:symsize,$
	xtitle:xtitle,$
	ytitle:ytitle,$
	color1:color1,$
	color2:color2,$
	xlo:xlo,$
	xhi:xhi,$
	ylo:ylo,$
	yhi:yhi,$
	maskem:1,$
	xzoom:1,$
	xminmsk:1,$
	xmaxmsk:nhedet,$
	ptr:ptr,$
	undozoom:undozoom,$
	xloprev:xlo,$
	xhiprev:xhi,$
	yloprev:ylo,$
	yhiprev:yhi,$
	oldct:oldct,$
	OLD_DECOMP:OLD_DECOMP,$
	pblist:pblist}
widget_control,tlb,set_uvalue=ptr_new(state,/no_copy)
xmanager,'dcs_plotdetmask',tlb,$
	event_handler='dcs_plotdetmask_handler',$
	cleanup='dcs_plotdetmaskCleanup'
;
end
