; $Id: dcs_multiplot_Plot.pro,v 1.36 2007/08/09 19:20:16 jrdcopley Exp $
;************************************************************************************************
pro dcs_multiplot_plot_save,event,abscis,ordina,oerror
;************************************************************************************************
; Given the abscissa vector "abscis", the ordinate array "ordina" and the
; ordinate error aray "oerror", this code is executed if saving the data to an ascii file.
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pState
;
;
nvals=size(ordina,/dimension)
nels=n_elements(ordina)
;
; Determine the number of points on each curve and the number of curves.
npoints=nvals[0]
ncurves=nels/npoints
;
; Determine whether or not to include ordinate errors in the saved data.
res=dialog_message([$
    "You may either OMIT the errors, writing the output as X, Y1, Y2, ...",$
    "or you may INCLUDE the errors, writing it as X, Y1, DY1, Y2, DY2, ... ",$
    " ",$
    "Do you wish to include the errors in the output file?"],/question)
include_errors=res eq "Yes"
not_include_errors=1-include_errors
;
;   Determine formats for abscissa, ordinate and error (if included).
fa='f8.3'
fo='e13.4'
minx=strcompress(string(min(abscis)))
maxx=strcompress(string(max(abscis)))
miny=strcompress(string(min(ordina)))
maxy=strcompress(string(max(ordina)))
mindy=strcompress(string(min(oerror)))
maxdy=strcompress(string(max(oerror)))
help=['The extreme values of X are'+minx+' and'+maxx+'.',$
    'The extreme values of Y are'+miny+' and'+maxy+'.',$
    'The extreme values of DY are'+mindy+' and'+maxdy+'.']
if (not_include_errors) then begin
    text=['format(X)','format(Y)']
    fe=''
    value=[fa,fo]
    if (ncurves eq 1) then begin
       form='('+text[0]+', '+text[1]+').'
    endif else begin
       form='('+text[0]+', '+strcompress(ncurves,/remove_all)+' '+text[1]+').'
    endelse
    help=['The output file will be written in the format '+form,'',$
       help,'','If appropriate, edit format(X) and/or format(Y).']
endif else begin
    text=['format(X)','format(Y)','format(DY)']
    fe='e13.4'
    value=[fa,fo,fe]
    if (ncurves eq 1) then begin
       form='('+text[0]+', '+text[1]+','+text[2]+').'
    endif else begin
       form='('+text[0]+','+strcompress(ncurves,/remove_all)+' ('+text[1]+','+text[2]+')).'
    endelse
    help=['The output file will be written in the format '+form,'',$
       help,'','If appropriate, edit format(X), format(Y) and/or format(DY).']
endelse
;
dave_get_values,'Define formats',text,value,help=help,group_leader=event.top
fa='('+value[0]+')'
fo='('+value[1]+')'
;
; Start to construct output strings. First comes the abscissa value.
str=string(abscis,format=fa)
;
;   Then come the ordinate(s) with or without the ordinate error(s).
if (not_include_errors) then begin
	ordina=reform(ordina,npoints,ncurves)
	for m=0,ncurves-1 do str=str+string(ordina[*,m],format=fo)
	ordina=reform(ordina,nvals)
endif else begin
	fe='('+value[2]+')'
	ordina=reform(ordina,npoints,ncurves)
	oerror=reform(oerror,npoints,ncurves)
	for m=0,ncurves-1 do str=str+string(ordina[*,m],format=fo)+string(oerror[*,m],format=fe)
	ordina=reform(ordina,nvals)
	oerror=reform(oerror,nvals)
endelse
;
; Determine whether there are any asterisks in the output strings.
; If so issue a warning and ask whether to continue.
ast_flag=max(strpos(str,"*")) eq 0
if (!debug and ast_flag) then begin
    response=dialog_message(["There are asterisks in the output file,",$
       "indicating that one or more of the formats is inadequate.","",$
       "Do you still wish to write the output file?"],/question,/default_no)
endif else response="Yes"
;
; Request saved data file name and write the data to the file.
if (response eq "Yes") then begin
    filename=dialog_pickfile(title="Enter saved data file name.",filter="*.dat",$
       path=(*!dave_defaults).workdir)
    if (filename eq "") then begin
       widget_control,event.top,set_uvalue=pState
       return
    endif
    if (strpos(filename,".dat") eq -1) then filename=filename+".dat"
    openw,unit,filename,/get_lun
    for k=0,npoints-1 do printf,unit,str[k]
    free_lun,unit
endif
;
end



;************************************************************************************************
pro dcs_multiplot_plot_screen,event,abscis,ordina,oerror,samelabel,othrlabel,ylabel,title
;************************************************************************************************
; Given the abscissa vector "abscis", the ordinate array "ordina" and the
; ordinate error array "oerror", this code is executed if plotting the data to the screen.
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pState
;
; If plotting vs. x (y), index = 0 (1).
index=1-(*pState).plot_vs_x
;;
;   If required, perform autoscaling.
if ((*pState).winState.autoscale[index] eq 1) then begin
   minabs=min(abscis)
   maxabs=max(abscis)
   absrange=maxabs-minabs
   (*pState).winState.xrange[*,index] = [minabs-absrange*0.05,maxabs+absrange*0.05]
   minord=min(ordina)
   maxord=max(ordina)
   ordrange=maxord-minord
   (*pState).winState.yrange[*,index] = [minord-ordrange*0.05,maxord+ordrange*0.05]
   widget_control,(*pState).butt_xmin,set_value=strcompress((*pState).winstate.xrange[0,index])
   widget_control,(*pState).butt_xmax,set_value=strcompress((*pState).winstate.xrange[1,index])
   widget_control,(*pState).butt_ymin,set_value=strcompress((*pState).winstate.yrange[0,index])
   widget_control,(*pState).butt_ymax,set_value=strcompress((*pState).winstate.yrange[1,index])
endif else begin
   if (*pState).objectgraphics then begin
      (*pState).plotWin->getproperty,xrange=xrange,yrange=yrange
      if total(finite(xrange)) eq 2 then begin
         (*pState).winState.xrange[*,index]=xrange
         widget_control,(*pState).butt_xmin,set_value=strcompress(xrange[0])
         widget_control,(*pState).butt_xmax,set_value=strcompress(xrange[1])
      endif
      if total(finite(yrange)) eq 2 then begin
         (*pState).winState.yrange[*,index]=yrange
         widget_control,(*pState).butt_ymin,set_value=strcompress(yrange[0])
         widget_control,(*pState).butt_ymax,set_value=strcompress(yrange[1])
      endif
   endif
   widget_control,(*pState).butt_xmin,get_value=tmpval
   (*pState).winState.xrange[0,index]=tmpval
   widget_control,(*pState).butt_xmax,get_value=tmpval
   (*pState).winState.xrange[1,index]=tmpval
   widget_control,(*pState).butt_ymin,get_value=tmpval
   (*pState).winState.yrange[0,index]=tmpval
   widget_control,(*pState).butt_ymax,get_value=tmpval
   (*pState).winState.yrange[1,index]=tmpval
endelse
;
abscisrange=(*pState).winstate.xrange[*,index]
ordinarange=(*pState).winstate.yrange[*,index]
;
; Define plot parameters.
thick=(*pState).thick
symsize=(*pState).symsize
initsym=(*pState).initsym
if (*pState).objectgraphics then begin
   ; Define the normal set of colors and a set of faded colors.
   defcols=bindgen(256,3)
   ndavecol=n_elements(!dave_colors.red)
   defcols[0:ndavecol-1,*]=[!dave_colors.red,!dave_colors.green,!dave_colors.blue]
   reds=255-(255-defcols[*,0])/(*pState).fadefactor
   grns=255-(255-defcols[*,1])/(*pState).fadefactor
   blus=255-(255-defcols[*,2])/(*pState).fadefactor
   fadecols=[[reds],[grns],[blus]]
   ; Generate symbol numbers.
   case initsym of
        "C": symbols=['filled circle','circle','filled triangle','triangle','filled square','square',$
                  'filled diamond','diamond','filled inverted triangle','inverted triangle']
        "O": symbols=['circle','filled circle','triangle','filled triangle','square','filled square',$
                  'diamond','filled diamond','inverted triangle','filled inverted triangle']
   endcase
endif else begin
   if ((*pState).show_grid eq 1) then ticklen=1.0 else ticklen=0.02
   ;
   if (!d.name eq 'WIN' or !d.name eq 'X') then wset,(*pState).winstate.winPix
   widget_control,event.top,set_uvalue = pState
   ;
   !x=(*pState).bangx
   !y=(*pState).bangy
   !p=(*pState).bangp
   ;
   if (!d.name eq 'WIN' or !d.name eq 'X') then begin
  	  device, get_decomposed=old_decomp
	  (*pState).old_decomp=old_decomp
	  default_colors=bindgen(256,3)
	  tvlct,default_colors,/get
	  (*pState).default_colors=default_colors
	  device, decomposed=0
   endif
   ;colorset
   tvlct,!dave_colors.red,!dave_colors.green,!dave_colors.blue
   ; Define the normal set of colors and a set of faded colors.
   defcols=bindgen(256,3)
   tvlct,defcols,/get
   reds=255-(255-defcols[*,0])/(*pState).fadefactor
   grns=255-(255-defcols[*,1])/(*pState).fadefactor
   blus=255-(255-defcols[*,2])/(*pState).fadefactor
   fadecols=[[reds],[grns],[blus]]
   ; Define numbers needed for plotting legend lines.
   barpos0=0.95
   dbar=0.02
   nbar=4
   ; Generate symbol numbers.
   d=indgen((*pState).ndatasets)
   case initsym of
        "C": dsymbol=(d-d mod 16)/16+((d-d mod 8) eq fix((d-d mod 8)/16)*16)*5
        "O": dsymbol=(d-d mod 16)/16+(1-((d-d mod 8) eq fix((d-d mod 8)/16)*16))*5
   endcase
endelse
;
dims=size(ordina,/dimensions)
ndims=size(ordina,/n_dimensions)
if (dims[0] eq 1) then begin
	ordina=reform(ordina,dims[1:ndims-1])
	oerror=reform(oerror,dims[1:ndims-1])
endif
ndims=size(ordina,/n_dimensions)
;
; A useful logical variable.
onecurveperdataset=((*pState).ndatasets eq 1 and ndims eq 1) or ((*pState).ndatasets gt 1 and ndims eq 2)
;
widget_control,(*pState).textgroup,set_value=""
widget_control,(*pState).butt_numgroups,get_value=ngroups
widget_control,(*pState).butt_groupnumber,get_value=groupnum
;
; Start the actual plotting.
if (*pState).objectgraphics then $
   (*pState).plotWin->erase,/nodraw $
else begin
   ; First plot the frame, ticks, labels etc, but no data.
   plot,abscis,ordina,Xstyle=1,Ystyle=1,Xtitle=samelabel,Ytitle=ylabel,$
        Xrange=abscisrange,Yrange=ordinarange,title=title,color=1,thick=2,$
        ticklen=ticklen,xgridstyle=2,ygridstyle=2,xminor=5,yminor=5,/nodata
   ;
   (*pState).bangx=!x
   (*pState).bangy=!y
   (*pState).bangp=!p
endelse
;
; If plotting vs 2theta or abs(2theta), optionally plot Bragg reflection angles.
if (*pState).objectgraphics eq 0 then begin
	if ((*pState).plot_vs_y and ((*pState).plota2th or (*pState).plotv2th)) then begin
		if ((*pState).plothkls) then begin
			if (n_elements(*(*pState).abctthetaPtr) gt 0) then begin
				abcttheta=(*(*pState).abctthetaPtr)
				crange=(*pState).bangy.crange
				nrefl=n_elements(abcttheta)/4
				if (nrefl gt 0) then begin
					for k=0,nrefl-1 do begin
						oplot,[+1,+1]*abcttheta[3,k],[crange[0],crange[0]+(crange[1]-crange[0])*0.85],color=8
						hvalu=fix(abcttheta[0,k])
						kvalu=fix(abcttheta[1,k])
						lvalu=fix(abcttheta[2,k])
						if (hvalu lt 0) then begin
							hvalu=-hvalu
							kvalu=-kvalu
							lvalu=-lvalu
						endif
						if (hvalu eq 0) then begin
							if (kvalu lt 0) then begin
								kvalu=-kvalu
								lvalu=-lvalu
							endif
							if (kvalu eq 0) then begin
								if (lvalu lt 0) then lvalu=-lvalu
							endif
						endif
						label=strcompress(string(hvalu)+string(kvalu)+string(lvalu))
						ypos=crange[0]+(crange[1]-crange[0])*0.855
						xyouts,abcttheta[3,k],ypos,label,color=2,orientation=90,charthick=2
					endfor
					for k=0,nrefl-1 do oplot,[-1,-1]*abcttheta[3,k],[crange[0],crange[0]+(crange[1]-crange[0])*0.85],color=8
				endif
			endif else begin
				res=dialog_message("Please provide lattice parameter information")
			endelse
		endif
	endif
endif else begin
	if ((*pState).plot_vs_y and ((*pState).plota2th or (*pState).plotv2th)) then begin
		if ((*pState).plothkls) then begin
			if (n_elements(*(*pState).abctthetaPtr) gt 0) then begin
				abcttheta=(*(*pState).abctthetaPtr)
				nrefl=n_elements(abcttheta)/4
				if (nrefl gt 0) then begin
					for k=0,nrefl-1 do (*pState).plotWin->add_plot,[+1,+1]*abcttheta[3,k],(*pState).winstate.yrange[*,index],color='grey'
					for k=0,nrefl-1 do (*pState).plotWin->add_plot,[-1,-1]*abcttheta[3,k],(*pState).winstate.yrange[*,index],color='grey'
				endif
			endif else begin
				res=dialog_message("Please provide lattice parameter information")
			endelse
		endif
	endif
endelse
;
; Plot data for each active, non-highlighted dataset.
if (*pState).objectgraphics eq 0 then tvlct,fadecols
for dataset=(*pState).ndatasets-1,0,-1 do begin
; Check that the dataset is active. If not, skip to end of loop.
    if (1-(*(*pState).activePtr)[dataset]) then continue
; Check whether the dataset is highlighted. If so, skip to end of loop.
    if ((*(*pState).hilitePtr)[dataset]) then continue
    ;
    color=2 + dataset mod 8
    if (*pState).objectgraphics then $
       psym=symbols[(dataset/8) mod 10] $
    else begin
       symbol=dsymbol[dataset]
       psym=-dave_selsym(symbol)*(*pState).join_pts
    endelse
    legend=strcompress(string(dataset+1),/remove_all)
;
; If there is one curve to be plotted per dataset, construct the
; ordinate and its error as vectors "ordina1" and "oerror1", and then
; plot the ordinate and its error (if requested).
    if (onecurveperdataset) then begin
       ordina1=ordina[*,dataset]
       if ((*pState).plot_eb) then $
          oerror1=oerror[*,dataset] $
       else begin   ;make oerror1 undefined
          oerror1=0 & tmp=temporary(oerror1)
       endelse
       if (*pState).objectgraphics then $
          (*pState).plotWin->add_plot,abscis,ordina1,yerr=oerror1,psym=psym,symsize=symsize,$
             color=reform(fadecols[color,*]),thick=thick,legend=legend,linestyle=3*(1-(*pState).join_pts) $
       else begin
          oplot,abscis,ordina1,psym=psym,symsize=symsize,color=color,thick=thick
          if ((*pState).plot_eb) then dave_cerrplot,abscis,ordina1-oerror1,$
             ordina1+oerror1,color=color
       endelse
    endif
;
; If there is more than one curve to be plotted per dataset, construct
; the ordinate and its error as 2-d arrays "ordina1" and "oerror1", and
; then execute a loop to plot the ordinate and its error (if requested).
    if (1-onecurveperdataset) then begin
       ordina1=ordina[*,*,dataset]
       for k=0,ngroups-1 do begin
           if ((*pState).plot_eb) then $
              oerror1=oerror[*,k,dataset] $
           else begin   ;make oerror1 undefined
              oerror1=0 & tmp=temporary(oerror1)
           endelse
           if (*pState).objectgraphics then $
              (*pState).plotWin->add_plot,abscis,ordina1[*,k],yerr=oerror1,psym=psym,symsize=symsize,$
              color=reform(fadecols[color,*]),thick=thick,legend=(k eq 0?legend:''),linestyle=3*(1-(*pState).join_pts) $
           else begin
              oplot,abscis,ordina1[*,k],psym=psym,symsize=symsize,color=color,thick=thick
              if ((*pState).plot_eb) then dave_cerrplot,abscis,$
                 ordina1[*,k]-oerror1,ordina1[*,k]+oerror1,color=color
           endelse
       endfor
    endif
;
    if (*pState).objectgraphics eq 0 then begin
    ;Draw a short line plus two symbols at top left of plot.
       barpos=barpos0-dbar*(dataset+fix(dataset/nbar))
       plots,[0.01,0.03],[1,1]*barpos,psym=-dave_selsym(symbol),$
          symsize=symsize,color=color,thick=thick,/normal
       xyouts,0.04,barpos-dbar*0.4,legend,/normal,color=1
    endif
endfor
;
; Plot non-highlighted data for each active, highlighted dataset.
tvlct,fadecols
for dataset=(*pState).ndatasets-1,0,-1 do begin
; Check that the dataset is active. If not, skip to end of loop.
    if (1-(*(*pState).activePtr)[dataset]) then continue
; Check whether the dataset is highlighted. If not, skip to end of loop.
    if (1-(*(*pState).hilitePtr)[dataset]) then continue
    color=2 + dataset mod 8
    if (*pState).objectgraphics then $
       psym=symbols[(dataset/8) mod 10] $
    else begin
       symbol=dsymbol[dataset]
       psym=-dave_selsym(symbol)*(*pState).join_pts
    endelse
;
; If there is more than one curve to be plotted per dataset, construct
; the ordinate and its error as 2-d arrays "ordina1" and "oerror1", and
; then execute a loop to plot the ordinate and its error (if requested).
    if (1-onecurveperdataset) then begin
       ordina1=ordina[*,*,dataset]
       if (groupnum ne 0) then begin
         for k=0,ngroups-1 do begin
          if (groupnum ne k+1) then begin
              if ((*pState).plot_eb) then $
                 oerror1=oerror[*,k,dataset] $
              else begin ;make oerror1 undefined
                 oerror1=0 & tmp=temporary(oerror1)
              endelse
              if (*pState).objectgraphics then $
                 (*pState).plotWin->add_plot,abscis,ordina1[*,k],yerr=oerror1,psym=psym,$
                    symsize=symsize,color=reform(fadecols[color,*]),thick=thick,legend='',$
                    linestyle=3*(1-(*pState).join_pts) $
              else begin
                 oplot,abscis,ordina1[*,k],psym=psym,symsize=symsize,color=color,thick=thick
                 if ((*pState).plot_eb) then dave_cerrplot,abscis,$
                    ordina1[*,k]-oerror1,ordina1[*,k]+oerror1,color=color
              endelse
          endif
         endfor
       endif
    endif
;
endfor
;
layer=0
; Plot highlighted data for each active, highlighted dataset.
tvlct,defcols
for dataset=(*pState).ndatasets-1,0,-1 do begin
; Check that the dataset is active. If not, skip to end of loop.
    if (1-(*(*pState).activePtr)[dataset]) then continue
; Check whether the dataset is highlighted. If not, skip to end of loop.
    if (1-(*(*pState).hilitePtr)[dataset]) then continue
    color=2 + dataset mod 8
    if (*pState).objectgraphics then $
       psym=symbols[(dataset/8) mod 10] $
    else begin
       symbol=dsymbol[dataset]
       psym=-dave_selsym(symbol)*(*pState).join_pts
    endelse
    legend=strcompress(string(dataset+1),/remove_all)
;
; If there is one curve to be plotted per dataset, construct the
; ordinate and its error as vectors "ordina1" and "oerror1", and then
; plot the ordinate and its error (if requested).
    if (onecurveperdataset) then begin
       ordina1=ordina[*,dataset]
       if ((*pState).plot_eb) then $
          oerror1=oerror[*,dataset] $
       else begin   ;make oerror1 undefined
          oerror1=0 & tmp=temporary(oerror1)
       endelse
       if (*pState).objectgraphics then $
          (*pState).plotWin->add_plot,abscis,ordina1,yerr=oerror1,psym=psym,symsize=symsize,$
             color=reform(defcols[color,*]),thick=thick,legend=legend,layer=layer++,$
             linestyle=3*(1-(*pState).join_pts) $
       else begin
          oplot,abscis,ordina1,psym=psym,symsize=symsize,color=color,thick=thick
          if ((*pState).plot_eb) then dave_cerrplot,abscis,ordina1-oerror1,$
             ordina1+oerror1,color=color
       endelse
    endif
;
; If there is more than one curve to be plotted per dataset, construct
; the ordinate and its error as 2-d arrays "ordina1" and "oerror1", and
; then execute a loop to plot the ordinate and its error (if requested).
    if (1-onecurveperdataset) then begin
       ordina1=ordina[*,*,dataset]
       if (groupnum eq 0) then begin
         for k=0,ngroups-1 do begin
             if ((*pState).plot_eb) then $
                oerror1=oerror[*,k,dataset] $
             else begin   ;make oerror1 undefined
                oerror1=0 & tmp=temporary(oerror1)
             endelse
             if (*pState).objectgraphics then $
                (*pState).plotWin->add_plot,abscis,ordina1[*,k],yerr=oerror1,psym=psym,$
                   symsize=symsize,color=reform(defcols[color,*]),thick=thick,layer=layer++,$
                   linestyle=3*(1-(*pState).join_pts),legend=(k eq 0?legend:'') $
             else begin
                oplot,abscis,ordina1[*,k],psym=psym,symsize=symsize,color=color,thick=thick
                if ((*pState).plot_eb) then dave_cerrplot,abscis,$
                   ordina1[*,k]-oerror1,ordina1[*,k]+oerror1,color=color
             endelse
         endfor
       endif
       if (groupnum ne 0) then begin
         k=groupnum-1
         if ((*pState).plot_eb) then $
            oerror1=oerror[*,k,dataset] $
         else begin   ;make oerror1 undefined
            oerror1=0 & tmp=temporary(oerror1)
         endelse
         if (*pState).objectgraphics then $
            (*pState).plotWin->add_plot,abscis,ordina1[*,k],yerr=oerror1,psym=psym,$
               symsize=symsize,color=reform(defcols[color,*]),thick=thick,legend=legend,$
               layer=layer++,linestyle=3*(1-(*pState).join_pts) $
         else begin
            oplot,abscis,ordina1[*,k],psym=psym,symsize=symsize,color=color,thick=thick
            if ((*pState).plot_eb) then dave_cerrplot,abscis,$
               ordina1[*,k]-oerror1,ordina1[*,k]+oerror1,color=color
         endelse
         widget_control,(*pState).textgroup,set_value=["HIGHLIGHTED",$
            strupcase(othrlabel)+"S",$
            strcompress((*(*pState).ksPtr)[k])+" -"+strcompress((*(*pState).kePtr)[k])+"  ("+$
            strcompress((*(*pState).ksPtr)[k]+1,/remove_all)+" -"+strcompress((*(*pState).kePtr)[k]+1)+")"]
       endif
    endif
;
    if (*pState).objectgraphics eq 0 then begin
    ;   Draw a short line plus two symbols at top left of plot.
       barpos=barpos0-dbar*(dataset+fix(dataset/nbar))
       plots,[0.01,0.03],[1,1]*barpos,psym=-dave_selsym(symbol),$
          symsize=symsize,color=color,thick=thick,/normal
       xyouts,0.04,barpos-dbar*0.4,legend,/normal,color=1
    endif
endfor
;
if (*pState).objectgraphics then begin
   (*pState).plotWin->setproperty,xrange=abscisrange,yrange=ordinarange,showxgrid=(*pState).show_grid,$
       showygrid=(*pState).show_grid,title=title,xtitle=samelabel,ytitle=ylabel
   ;
   (*pState).winstate.autoscale[index] = 0
endif else begin
   if (!d.name eq 'WIN' or !d.name eq 'X') then device,decomposed=(*pState).old_decomp
   ;revert to default colors
   tvlct, (*pState).default_colors
   ;
   if (!d.name eq 'WIN' or !d.name eq 'X') then begin
	  widget_control,event.top,get_uvalue = pState
	  wset,(*pState).winstate.winVis
	  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winstate.winPix]
	  wshow,(*pState).winstate.winVis
      widget_control,event.top,set_uvalue = pState
   endif
endelse
;
;
; Update the information window.
widget_control,(*pState).infowindow,get_value=information
for dataset=(*pState).ndatasets-1,0,-1 do begin
    code="   "
    if ((*(*pState).activePtr)[dataset]) then begin
       if ((*(*pState).hilitePtr)[dataset]) then code="AH " else code="A  "
    endif
    information[dataset]=code+strmid(information[dataset],3)
endfor
widget_control,(*pState).infowindow,set_value=information
tags=tag_names(*pState)
index=where(tags eq strupcase('informationPtr'))
if (index ge 0) then *(*pState).informationPtr=information
;
widget_control,event.top,set_uvalue=pState
;
end


;************************************************************************************************
pro dcs_multiplot_Plot,event
;************************************************************************************************
; This procedure defines the abscissa vector "abscis", the ordinate array "ordina" and the
; ordinate error array "oerror" for subsequent saving or plotting.
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=pState
;
dcs_multiplot_sensitivity,event,enable=0
;
; Define some variables, depending whether the abscissa is x or y.
plot_vs_x=(*pState).plot_vs_x
plot_vs_y=(*pState).plot_vs_y
;
samedim =   (plot_vs_x) ? (*pState).xdim   : (*pState).ydim
samerebin = (plot_vs_x) ? (*pState).xrebin : (*pState).yrebin
samelabel = (plot_vs_x) ? (*pState).xlabel : (*pState).ylabel
;
othrvalue = (plot_vs_x) ? (*pState).yvalue : (*pState).xvalue
othrwidth = (plot_vs_x) ? (*pState).ywidth : (*pState).xwidth
othrdim =   (plot_vs_x) ? (*pState).ydim   : (*pState).xdim
othrlabel = (plot_vs_x) ? (*pState).ylabel : (*pState).xlabel
;
abscis =    (plot_vs_x) ? *(*pState).px    : *(*pState).py
tot_index = (plot_vs_x) ? 2                : 1
;
; If plotting raw data files, redefine certain variables.
if ((*pState).readingDCS or (*pState).readingDCShigh) then begin
	if (plot_vs_x) then samedim=1000
	if (plot_vs_y) then othrdim=1000
	if (plot_vs_x) then abscis=(*(*pState).px)[0:999]
endif
;
ndp=size(*(*pState).pqty,/n_dimensions)
;
; If plotting raw data files, define local pointers.
if ((*pState).readingDCS or (*pState).readingDCShigh) then begin
    tchansPtr=ptr_new((*(*pState).tchansPtr)[0:999])
    timesPtr=ptr_new((*(*pState).timesPtr)[0:999])
    energiesPtr=ptr_new((*(*pState).energiesPtr)[0:999])
endif
;
; Define pqtyPtr and perrPtr.
if ((*pState).readingDCS or (*pState).readingDCShigh) then begin
	case ndp of
    2: begin
       pqtyPtr=ptr_new((*(*pState).pqty)[0:999,*])
       perrPtr=ptr_new((*(*pState).perr)[0:999,*])
    end
    3: begin
       pqtyPtr=ptr_new((*(*pState).pqty)[0:999,*,*])
       perrPtr=ptr_new((*(*pState).perr)[0:999,*,*])
    end
    else:
	endcase
endif else begin
  pqtyPtr=ptr_new((*(*pState).pqty))
  perrPtr=ptr_new((*(*pState).perr))
endelse
;
; If plotting raw data files, rotate spectra as necessary.
rotating=(*pState).delta_tsdmin ne 0.0
if (rotating) then begin
    tcwid=(*tchansPtr)[0]
    dummy=where(*tchansPtr ne tcwid,count)
    if (count ne 0) then begin
       ptr_free,tchansPtr
       ptr_free,timesPtr
       ptr_free,energiesPtr
       ptr_free,pqtyPtr
       ptr_free,perrPtr
       res=dialog_message('Failure in dcs_multiplot_Plot (time channels unequal)')
       return
    endif
;
    *timesPtr=*timesPtr+(*pState).delta_tsdmin
    *energiesPtr=(*pState).e0-!dcs_hsq2mn/(!dcs_hom*(*timesPtr)/!dcs_dsd)^2
    nshift=fix((*pState).delta_tsdmin/tcwid)
    case ndp of
       2: begin
         *pqtyPtr=shift((*pqtyPtr),-nshift,0)
         *perrPtr=shift((*perrPtr),-nshift,0)
       end
       3: begin
         *pqtyPtr=shift((*pqtyPtr),-nshift,0,0)
         *perrPtr=shift((*perrPtr),-nshift,0,0)
       end
       else:
    endcase
endif
;
; If plotting vs time (T_SD) or against energy transfer, redefine the abscissa
; and its label.
if (plot_vs_x and (*pState).plotvst) then begin
    abscis=*timesPtr
    samelabel="Time sample-detector (us)"
endif
;
if (plot_vs_x and ((*pState).plotvsE or $
       (*pState).plott4E or (*pState).plott4EDB or $
       (*pState).plotdos or (*pState).plotdosDB)) then begin
    abscis=*energiesPtr
    samelabel="Energy transfer (meV)"
endif
;
; If plotting vs 2theta or against abs(2theta), redefine the abscissa and
; its label.
if (plot_vs_y and (*pState).plotv2th) then begin
    dcs_getangles,nhedet=913,angles
    abscis=angles
    samelabel="Scattering angle"
endif
;
if (plot_vs_y and (*pState).plota2th) then begin
    dcs_getangles,nhedet=913,angles
    abscis=abs(angles)
    samelabel="ABS(Scattering angle)"
endif
;
; Define the ordinate and its error when plotting the sum over the
; other dimension ("All in one group").
if ((*pState).all) then begin
    ordina=total((*pqtyPtr),tot_index)/othrdim
    oerror=sqrt(total((*perrPtr)^2,tot_index))/othrdim
    title=(*pState).histlabel+": average over all "+othrlabel
    ngroups=1
endif
;
; Define the ordinate and its error when plotting "Several groups".
; This is only allowed if there is only one dataset.
if ((*pState).some) then begin
    widget_control,(*pState).butt_numgroups,get_value=ngroups
    ndim=othrdim/ngroups
; Initialize the ordinate and its error as a 2-d array.
    ordina=fltarr(samedim,ngroups,(*pState).ndatasets)
    oerror=fltarr(samedim,ngroups,(*pState).ndatasets)
; Loop over the groups, generating lower and upper values
;   of the index of the third dimension.
    kc=othrdim-ndim*ngroups
    ke=-1
    ksvals=intarr(ngroups)
    kevals=intarr(ngroups)
    for k=0,ngroups-1 do begin
       if (k lt kc) then begin
         ks=ke+1
         ke=ks+ndim
       endif else begin
         ks=ke+1
         ke=ks+ndim-1
       endelse
       ksvals[k]=ks
       kevals[k]=ke
; Generate the ordinate and its error.
;   Treat separately the case where there is only one contribution to the group.
       for dataset=0,(*pState).ndatasets-1 do begin
         if (ks eq ke) then begin
          if ((*pState).plot_vs_x) then begin
              ordina[*,k,dataset]=(*pqtyPtr)[*,ks,dataset]
              oerror[*,k,dataset]=sqrt((*perrPtr)[*,ks,dataset]^2)
          endif else begin
              ordina[*,k,dataset]=(*pqtyPtr)[ks,*,dataset]
              oerror[*,k,dataset]=sqrt((*perrPtr)[ks,*,dataset]^2)
          endelse
; Treat the case where there is more than one contribution to the group.
         endif else begin
          if ((*pState).plot_vs_x) then begin
              ordina[*,k,dataset]=total((*pqtyPtr)[*,ks:ke,dataset],2)/(ke-ks+1);;
              oerror[*,k,dataset]=sqrt(total((*perrPtr)[*,ks:ke,dataset]^2,2))/(ke-ks+1);;
          endif else begin
              ordina[*,k,dataset]=total((*pqtyPtr)[ks:ke,*,dataset],1)/(ke-ks+1)
              oerror[*,k,dataset]=sqrt(total((*perrPtr)[ks:ke,*,dataset]^2,1))/(ke-ks+1)
          endelse
         endelse
       endfor
    endfor
    ptr_free,(*pState).ksPtr
    ptr_free,(*pState).kePtr
    (*pState).ksPtr=ptr_new(ksvals)
    (*pState).kePtr=ptr_new(kevals)

; Define the plot title.
    title=(*pState).histlabel+": "+othrlabel+"-"+$
       strcompress(ngroups)+" groups"
endif
;
; Define the ordinate and its error when plotting a "single group".
if ((*pState).one) then begin
; Generating lower and upper values of the index of the third dimension.
    othrval1=othrvalue-othrwidth > 1
    othrval2=othrvalue+othrwidth < othrdim
;   Generate the ordinate and its error.
; Treat separately the case where there is only one contribution to the group.
    if (othrval1 eq othrval2) then begin
       if ((*pState).plot_vs_x) then begin
         ordina=(*pqtyPtr)[*,othrvalue-1,*]
         oerror=(*perrPtr)[*,othrvalue-1,*]
       endif else begin
         ordina=(*pqtyPtr)[othrvalue-1,*,*]
         oerror=(*perrPtr)[othrvalue-1,*,*]
       endelse
       title=(*pState).histlabel+": "+othrlabel+" ="+strcompress(othrvalue)
; Treat the case where there is more than one contribution to the group.
    endif else begin
       if ((*pState).plot_vs_x) then begin
         ordina=total((*pqtyPtr)[*,othrval1-1:othrval2-1,*],2)$
          /(othrval2-othrval1+1)
         oerror=sqrt(total((*perrPtr)[*,othrval1-1:othrval2-1,*]^2,2))$
          /(othrval2-othrval1+1)
       endif else begin
         ordina=total((*pqtyPtr)[othrval1-1:othrval2-1,*,*],1)$
          /(othrval2-othrval1+1)
         oerror=sqrt(total((*perrPtr)[othrval1-1:othrval2-1,*,*]^2,1))$
          /(othrval2-othrval1+1)
       endelse
       title=(*pState).histlabel+": "+othrlabel+$
         " ="+strcompress(othrval1)+" to"+strcompress(othrval2)
    endelse
    ngroups=1
endif
;
; Modify plot title.
if ((*pState).delta_tsdmin ne 0.0) then $
    title=title+" (tsdmin ="+strcompress((*pState).tsdmin+(*pState).delta_tsdmin)+")"
;
; Multiply each dataset ordinate and ordinate error by a multiplier.
if ((*pstate).ndatasets eq 1) then begin
    ordina=ordina*(*(*pstate).multiplierPtr)[0]
    oerror=oerror*(*(*pstate).multiplierPtr)[0]
endif else begin
    dims=size(ordina,/dimensions)
    ndims=size(ordina,/n_dimensions)
    unityPtr=ptr_new(bytarr(n_elements(ordina)/dims[ndims-1])+1)
    ordina=ordina*(*unityPtr#(*(*pstate).multiplierPtr))
    oerror=oerror*(*unityPtr#(*(*pstate).multiplierPtr))
    ptr_free,unityPtr
endelse
;
; Subtract a constant from each dataset ordinate; (ordinate error unchanged).
if ((*pstate).ndatasets eq 1) then begin
    ordina=ordina-(*(*pstate).constantsPtr)[0]
endif else begin
    dims=size(ordina,/dimensions)
    ndims=size(ordina,/n_dimensions)
    unityPtr=ptr_new(bytarr(n_elements(ordina)/dims[ndims-1])+1)
    ordina=ordina-(*unityPtr#(*(*pstate).constantsPtr))
    ptr_free,unityPtr
endelse
;
npoints=samedim
nsets=(*pState).ndatasets
;
; If plotting vs 2theta or abs(2theta), sort the abscissa and ordinate(s).
if (plot_vs_y and ((*pState).plota2th or (*pState).plotv2th)) then begin
	sortorder=sort(abscis)
	abscis=abscis[sortorder]
	ndims=size(ordina,/n_dimensions)
	case ndims of
	  1: begin
	    ordina=ordina[sortorder]
	    oerror=oerror[sortorder]
	   end
	  2: begin
	    ordina=ordina[sortorder,*]
	    oerror=oerror[sortorder,*]
	  end
	  3: begin
	    ordina=ordina[sortorder,*,*]
	    oerror=oerror[sortorder,*,*]
	  end
	  else:
	endcase
endif
;
ylabel="Detector counts"
;
; If plotting raw DCS data in certain ways, involving transformation
; of the ordinate, construct a variable (*factorPtr) with the same
; length as the (modified) ordinate.
; The dimension of *unityPtr is the product of all but the first dimension
; of ordina.
;
; If plotting intensity versus t_SD or versus E_transfer, divide each ordinate
; value by the time width of the channel.
if (plot_vs_x and ((*pState).plotvst or (*pState).plotvsE)) then begin
    dims=size(ordina,/dimensions)
    unityPtr=ptr_new(bytarr(n_elements(ordina)/dims[0])+1)
    factorPtr=ptr_new((*tchansPtr)#(*unityPtr))
    ordina=ordina/(*factorPtr)
    oerror=oerror/(*factorPtr)
    ptr_free,unityPtr
    ptr_free,factorPtr
    ylabel='" dsdt "'
endif
;
; If plotting "t^4*dsdt" vs E_transfer, multiply each ordinate value by
; (t_SD/t_elastic)^4 and divide by the time width of the channel.
if (plot_vs_x and ((*pState).plott4E or (*pState).plott4EDB)) then begin
    dims=size(ordina,/dimensions)
    unityPtr=ptr_new(bytarr(n_elements(ordina)/dims[0])+1)
    factorPtr=ptr_new( (((*timesPtr)/(*pState).elastic_time)^4/(*tchansPtr))#(*unityPtr))
    ordina=ordina*(*factorPtr)
    oerror=oerror*(*factorPtr)
    ptr_free,unityPtr
    ptr_free,factorPtr
    ylabel='" t^4*dsdt "'
endif
;
; If plotting "DOS" vs E_transfer, multiply each ordinate value by
; E_transfer^2*(t_SD/t_elastic)^4, and divide by the time width of the channel.
if (plot_vs_x and ((*pState).plotdos or (*pState).plotdosDB)) then begin
    dims=size(ordina,/dimensions)
    unityPtr=ptr_new(bytarr(n_elements(ordina)/dims[0])+1)
    factorPtr=ptr_new( (*energiesPtr)^2*$
       (((*timesPtr)/(*pState).elastic_time)^4/(*tchansPtr))#(*unityPtr))
    ordina=ordina*(*factorPtr)
    oerror=oerror*(*factorPtr)
    ptr_free,unityPtr
    ptr_free,factorPtr
    ylabel='" DOS "'
endif
;
; If including detailed balance in a plot of either "t^4*dsdt" or "DOS" vs E_transfer,
; multiply each ordinate value by exp(-0.5*E_transfer/kT).
if (plot_vs_x and ((*pState).plott4EDB or (*pState).plotdosDB)) then begin
    dims=size(ordina,/dimensions)
    kTinv=(!dcs_mevcon/!dcs_boltzmann)/(*(*pState).temperaturesPtr)
    arg1Ptr=ptr_new((*energiesPtr)#(1+bytarr(ngroups*(*pState).ndatasets)))
    arg2Ptr=ptr_new((1+bytarr(1000*ngroups))#kTinv)
    factorPtr=ptr_new(exp(-0.5*((*arg1Ptr)*(*arg2Ptr))))
    ordina=ordina*(*factorPtr)
    oerror=oerror*(*factorPtr)
    ptr_free,arg1Ptr
    ptr_free,arg2Ptr
    ptr_free,factorPtr
    ylabel="Symmetrized "+ylabel
endif
;
; If desired, divide each dataset ordinate and ordinate error by its effective
; duration, i.e. duration*srdenom/60.0.
if ((*pState).norm_d) then begin
    duration=(*(*pstate).durationsPtr)*(*(*pstate).srdenomsPtr)/60.0
    if ((*pstate).ndatasets eq 1) then begin
       ordina=ordina/duration[0]
       oerror=oerror/duration[0]
    endif else begin
       dims=size(ordina,/dimensions)
       ndims=size(ordina,/n_dimensions)
       unityPtr=ptr_new(bytarr(n_elements(ordina)/dims[ndims-1])+1)
       ordina=ordina/(*unityPtr#duration)
       oerror=oerror/(*unityPtr#duration)
       ptr_free,unityPtr
    endelse
endif
;
;   If required, rebin the data.
if (samerebin gt 1) then begin
    newdim=samedim/samerebin
    abscis=total(reform(abscis[0:samerebin*newdim-1],samerebin,newdim),1)/samerebin
    ndims=size(ordina,/n_dimensions)
    dims=size(ordina,/dimensions)
    case ndims of
       1: begin
         ordina=total(reform(ordina[0:samerebin*newdim-1],samerebin,newdim),1)/samerebin
         oerror=sqrt(total(reform(oerror[0:samerebin*newdim-1]^2,samerebin,newdim),1))/samerebin
       end
       2: begin
         ordina=total(reform(ordina[0:samerebin*newdim-1,*],samerebin,newdim,dims[1]),1)/samerebin
         oerror=sqrt(total(reform(oerror[0:samerebin*newdim-1,*]^2,samerebin,newdim,dims[1]),1))/samerebin
       end
       3: begin
         ordina=total(reform(ordina[0:samerebin*newdim-1,*,*],samerebin,newdim,dims[1],dims[2]),1)/samerebin
         oerror=sqrt(total(reform(oerror[0:samerebin*newdim-1,*,*]^2,samerebin,newdim,dims[1],dims[2]),1))/samerebin
       end
       else: begin
         res=dialog_message('Failure in dcs_multiplot_Plot (rebinning code)')
         ptr_free,tchansPtr
         ptr_free,timesPtr
         ptr_free,energiesPtr
         ptr_free,pqtyPtr
         ptr_free,perrPtr
         return
       end
    endcase
endif
;
; The data to be plotted should now be fully defined.
; It is either saved or plotted to the screen.
;
if ((*pState).savedata) then begin
    dcs_multiplot_plot_save,event,abscis,ordina,oerror
endif else begin
    dcs_multiplot_plot_screen,event,abscis,ordina,oerror,samelabel,othrlabel,ylabel,title
endelse
;
dcs_multiplot_sensitivity,event,/enable
;
;Free local pointers.
if ((*pState).readingDCS or (*pState).readingDCShigh) then begin
    ptr_free,tchansPtr
    ptr_free,timesPtr
    ptr_free,energiesPtr
endif
ptr_free,pqtyPtr
ptr_free,perrPtr
;
end




