; $Id: hfbs_db.pro,v 1.13 2005/02/09 16:58:00 dimeo Exp $
;###############################################################################
;
; NAME:
;  HFBS_DB
;
; PURPOSE:
;  GUI application for visualization of HFBS data
;
; CATEGORY:
;  DAVE, HFBS, Data visualization
;
; AUTHOR:
;   Robert M. Dimeo, Ph.D.
;   NIST Center for Neutron Research
;   100 Bureau Drive
;   Gaithersburg, MD 20899
;   Phone: (301) 975-8135
;   E-mail: robert.dimeo@nist.gov
;   http://www.ncnr.nist.gov/staff/dimeo
;
; 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 of if the code in this file is
;  included in another product.
;
;###############################################################################
; HFBS_DB.PRO
; Graphical user interface to read in and display data from HFBS
;
; Version 2.0
;
; Original program written by R.M.Dimeo (4/14/99)
;
; Routines written by several other IDL programmers have been included
; in this program and are listed below:
;
; Uses PLOTSYM (renamed hfbs_plotsym) and INFORMATIONPANEL by Ronn Kling
;
; Modification history:
; ---------------------
; -  Enabled mouse-driven zooming in plotting (5/18/99)
; -  Simple curve fitting functionality added (5/18/99)
; -  Corrected error in calculating error bars when normalizing
;     data to either beam monitor or P(v) (5/24/99)
; -  Add reduced chi-squared value to fit output and added display in fit box (5/25/99)
; -  Add fit parameters and chi-squared in postscript output (5/25/99)
; -  Single menu selection for postscript output (5/28/99)
; -  Made the "add function" bases modal to block other widgets (5/31/99)
; -  User selection of plotting symbols (5/31/99)
; -  Added primitive legend capabilities to both screen and postscript output (6/1/99)
; -  Added the Kohlrausch fitting function (stretched exponential) (6/1/99).
; -  Added gaussian-broadened Kohlrausch fitting function (6/1/99).
; -  Displays currently-selected fit function (6/2/99).
; -  Reads in *.hscn files: temperature/time scan data files (6/8/99)
; -  Normalization to vanadium files.  Enable normalization of *.hscn files. (6/9/99)
; -  Changed title of plot to reflect what's been done to the data
;    (e.g. normalization) (6/9/99)
; -  Added ability to load in 3 cols of data into the current workspace (6/13/99)
; -  Added rebinning capability (6/16/99)
; -  Fixed titles when normalizing to P(v) (6/16/99)
; -  Wrote a separate widget program to add *.HFBS files together and write the
;    result out to a new file (6/16/99).  (AddHFBS.PRO)
; -  Enlarged plot symbol choices to include various line styles (6/17/99).
; -  Improved data zooming option (6/18/99).
; -  Added ability to plot spectra from multiple detectors in 3 dimensions
;    where each detector is offset from the other (6/22/99) and print to a
;    postscript file (6/24/99).
; -  Modified the vanadium normalization so that the DataBrowser now must
;    read in a file ending in .VAN which contains the values which, when
;    multiplied by the detector data, yield normalized scattering.  The
;    values are created in a separate IDL widget program called CreateVanNorm.PRO.(6/23/99)
; -  Added color imaging of data from different detectors (6/25/99)
; -  Reads in new TOF format files.  Data file format has changed and new components to
;    the header have been added as well as a log of the white beam monitor
;    and doppler frequency.  READ_HFBS has been renamed ReadOldHFBS and the
;    new routine ReadNewHFBS has been added (7/1/99)
; -  Added ability to type in detectors to add together (7/27/99)
; -  Added ability to type in workspaces to plot on one graph (7/28/99)
; -  Properly sorting arrays after converting from time to energy (7/30/99)
; -  Reads in files converted from time to energy using ConvertTime2Energy.PRO
;    with the new routine called ReadConFile.PRO (8/20/99).
; -  Corrected an error in the time to energy conversion for velocity binning mode
;    and with time-of-flight mode (8/20/99).
; -  All CW_FIELDS accept string input so they are white rather than gray (8/25/99).
; -  Added SIN_CAM_FUN.PRO which is the analytical profile for the sin cam option
;    for the doppler drive (8/25/99).
; -  User can write macros to reduce the data in a buffer (8/26/99).  This is not
;    completely functioning yet but user can save macros.
; -  Automatic computation of the number of channels in a time frame based on fitting
;    a function with a roll-off to the fission chamber data (9/1/99).
; -  User can write current buffer out to a file with energy as x-value (9/14/99)
; -  Writes the scattering angle out after detector identification (9/17/99)
; -  Reads in an HFBS data file with the sample temperature recorded (9/23/99)
; -  Add file utility added (9/24/99)
; -  Low angle detector data have been shifted artificially so that their peak maximum
;    lines up with the zero energy channel (9/27/99)
; -  Moved the Zoom In and Zoom Out buttons from a menu to the main GUI (9/27/99)
; -  Rearranged "fitting information" box so that it displays events as they
;    occur (9/30/99)
; -  Corrected problem associated with labeling the x-axis when there are different
;    data types in different buffers and workspaces (10/1/99)
; -  Some macro functionality for HSCN files works now (10/4/99)
; -  Fixed problem with axis labeling with workspace operations and
;    rebinning (10/12/99)
; -  Changed sigma for gaussian and width for lorentzian to
;    full-width-half-maximum (10/20/99)
; -  Checks for the file /tmp/hfbs.lock.  If present then the data continues to be
;    read in (11/10/99)
; -  Added the statement setenv,'LD_LIBRARY_PATH=""' if running under LINUX which
;    allows processes to be spawned and OS environmental commands to be used (11/10/99)
; -  Changed time-to-energy conversion for triangle cam...old conversion based on Ross
;    Christman's equations was incorrect...new one from Paul Brand (6/29/2000)
; -  Uses the mpcurvefit.pro routing contained in the fitting path (7/19/2000)
; -  A pointer to the state variable is now passed between procedures rather than
;    the whole state to improve speed (10/1/2000)
; -  Zooming is possible using the mouse and button clicks rather than with the
;    press of the button on the main widget (10/1/2000).
; -  Enabled normalization to the incident beam monitor (3/21/2001).
;
;    Began imcorporating into DAVE (11/18/2001)-RMD
;
;   Added workspace operation capability using John Copley's DAVE_EVALUATE procedure (01/10/02)-RMD
;    Incorporated John Copley's rebinning routine called DAVE_REBIN.PRO (01/12/02)-RMD
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_dbCleanup,tlb
widget_control,tlb,get_uvalue = pState,/no_copy
tvlct,(*pState).rorig,(*pState).gorig,(*pState).borig
wdelete,(*pState).winPix

thisPtr = !dave_defaults

; Remove all pointers not necessary for apps external to this one
;if ptr_valid((*pState).inPtr) then begin
;  dave_beast_ops,"get_ptrs",(*pState).inPtr,show_analysis = 0,show_commands = 0,bpointers = bptrs
;  bptrs = reverse(bptrs)
;  nb = n_elements(bptrs)        ; number of pointers we want to keep
;  zptrs = ptr_valid(count = nz)      ; total number of all pointers
;  ;print,'Total number of pointers before cleanup in DATABROWSER: ',nz
;  if nz gt 0 then begin
;    for i = 0,nz-1 do begin
;      thisOne = where((bptrs eq zptrs[i]) or (zptrs[i] eq pState),count)
;      if count eq 0 then begin
;        if zptrs[i] ne thisPtr then ptr_free,zptrs[i]
;      endif
;    endfor
;  endif
;endif

s = size((*pState).notifyIDs)
if s[0] eq 1 then count = 0 else count = s[2]-1
for j = 0,count do begin
  pseudoEvent = {dbEvent,$
                        ID:(*pState).notifyIDs[0,j],$
                        Top:(*pState).notifyIDs[1,j],$
                        Handler:0l};,$
;                        inPtr:ptr_new(*(*pState).inPtr)}
  if widget_info((*pState).notifyIDs[0,j],/valid_id) then begin $
    widget_control,(*pState).notifyIDs[0,j],send_event = pseudoEvent
  endif
endfor



return
end
;==========================================
PRO hfbs_doneDB,event
widget_control,event.top,/destroy
RETURN
END
;==========================================
Function hfbs_ChooseDets,strdets
;
; Input:    string containing detector numbers separated either by
;           commas or - (hyphens).  A hyphen indicates to include the
;           two detectors and all detectors in between.  A comma simply
;           means to append that detector to the current list.
;
; Output:   a pointer to an array containing all of the detectors to be
;      summed together.
;
; Catch errors in input string
nerror = strmid(strdets,0)
if (nerror[0] eq '-') or (nerror[0] eq ',') or (nerror[0] eq ' ') then begin
  void = dialog_message('Not a valid input field',$
           dialog_parent=event.top)
  return,0
endif
strdets = strcompress(strdets)
test1 = strpos(strdets,'-,')
test2 = strpos(strdets,',-')
if test1[0] ne -1 or test2[0] ne -1 then begin
  void = dialog_message('Not a valid input field',$
           dialog_parent=event.top)
  return,0
endif

; count the number of commas occurring in the string
i = 0
inum = 0
cnt = 0
commacnt = intarr(50)
while (inum ne -1) do begin
  i = strpos(strdets,',',i)
  inum = i[0]
  if (inum ne -1) then begin
    commacnt[cnt] = inum
    cnt = cnt+1
    inum = inum + 1
    i = inum
  endif
endwhile
ncommas = cnt
if ncommas gt 0 then begin
  commaPos = intarr(ncommas)
  commaPos = commacnt[0:ncommas-1]
endif
;commaPos = [-1,commaPos[0:ncommas-1]]

; if there are no commas then there are two possibilities
; either there is a single detector present.....
ndash = strpos(strdets,'-')
if (ncommas eq 0) and (ndash[0] eq -1) then begin
  detnum = fix(strdets)
  ndets = 1
  dets = detnum
endif

; or there are a sum of detectors present
if (ncommas eq 0) and (ndash[0] ne -1) then begin
  pos = strpos(strdets,'-')
  len = strlen(strdets)
  numstr1 = strmid(strdets,0,pos[0])
  numstr2 = strmid(strdets,pos[0]+1,len[0]-1)
  num1 = fix(numstr1)
  num2 = fix(numstr2)
  ndets = num2[0] - num1[0] + 1
  dets = intarr(ndets)
  dets = num1[0] + INDGEN(ndets)
endif

; are there one or more commas?
if (ncommas gt 0) then begin
  dets = intarr(100)
  totlen=strlen(strdets)     ; total length of the input string
  smallLen = intarr(ncommas+1)   ; array defining the length of all substrings in string
                 ; variable strdets
  smallLen[0] = commaPos[0]
  for i=1,ncommas-1 do begin
      smallLen[i] = commaPos[i]-commaPos[i-1]-1
  endfor
  smallLen[ncommas] = totlen-commaPos[ncommas-1]-1

  substrings = strarr(ncommas+1) ; string array representing string form of detectors to sum
  substrings[0]=strmid(strdets,0,smallLen[0])
  for i = 1,ncommas do begin
    substrings[i]=strmid(strdets,commaPos[i-1]+1,smallLen[i])
  endfor

  ; convert substrings to an array of numbers
  count = 0
  for i = 0,ncommas do begin

    dashpresent = strpos(substrings[i],'-')
    dash = dashpresent[0]

    if dash eq -1 then begin
      detnum = fix(substrings[i])
      ndets = 1
      dets[count] = detnum[0]
      count = count+1
    endif

    if dash ne -1 then begin

      pos = strpos(substrings[i],'-')
      len = strlen(substrings[i])
      numstr1 = strmid(substrings[i],0,pos[0])
      numstr2 = strmid(substrings[i],pos[0]+1,len[0]-1)
      num1 = fix(numstr1)
      num2 = fix(numstr2)
      ndets = num2[0] - num1[0] + 1
      singledets = intarr(ndets)
      singledets = num1[0] + INDGEN(ndets)
      dets[count:count+ndets-1] = singledets[0:ndets-1]
      count = count+ndets
    endif
  endfor

ndets = count
tempdets = intarr(ndets)
tempdets[0:ndets-1] = dets[0:ndets-1]
dets = intarr(ndets)
dets[0:ndets-1] = tempdets[0:ndets-1]
endif
newdetPtr = ptr_new(dets)
RETURN,newdetPtr
END
;==========================================
function hfbs_symname,index
case index of
 0: begin
    name = 'circles'
    end
 1: begin
    name = 'triangles'
    end
 2: begin
    name = 'diamonds'
    end
 3: begin
    name = 'Boxes'
    end
 4: begin
    name = 'Horizontal Lines'
    end
 5: begin
    name = 'Continuous line'   ; continuous line
    end

 6: begin
    name = 'Dotted line'
    end

 7: begin
    name = 'Dashed line'
    end

 8: begin
    name = 'Dash-dot line'
    end

 9: begin
    name = 'Dash-dot-dot-dot line'
    end

 10: begin
     name = 'Long Dashes line'
     end
endcase
return,name
end
;==========================================
PRO Print2PsFile,event
; Print workspace
widget_control,event.top,get_uvalue = pState
cd,(*pState).printPath
thisDevice = !d.name
;;;;;;;;;;;;;;;;;
if (*pState).plotType eq 0 then begin

IF (*pState).imagePlot EQ 1 THEN BEGIN
;widget_control,(*pState).PlotWsList,get_value = choice
  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
;widget_control,(*pState).xrangelo,get_value = xlo
;widget_control,(*pState).xrangehi,get_value = xhi
ylo = (*pState).yrangelo
yhi = (*pState).yrangehi
;widget_control,(*pState).yrangelo,get_value = ylo
;widget_control,(*pState).yrangehi,get_value = yhi
xlo = float(xlo[0]) & xhi = float(xhi[0])
ylo = float(ylo[0]) & yhi = float(yhi[0])
buffer = (*pState).curbuff
(*pState).imagePlot = 1
nchan = (*pState).buffchan[buffer]
ndet = (*pState).ndet[buffer]
;IF (*pState).mode EQ 'standard' THEN BEGIN
  IF PTR_VALID((*pState).BuffPtr[buffer]) THEN BEGIN
    dataPtr = ptr_new(/allocate_heap)
    dataPtr = (*pState).BuffPtr[buffer]
    data = FLTARR(ndet,nchan)
    data = *dataPtr
    energy = FLTARR(nchan)
    energy = *(*pState).BuffEnergyPtr[buffer]
    ;index = where()
    ;surfr,ax=45
    ;device,decomposed = 0
    ;loadct,1


;widget_control,(*pState).addlist,get_value = choice
ws = (*pState).curws
; index is an array of indices which include the detectors
; to be added together...nchoices is the number of detectors
; to be summed together
widget_control,(*pState).selPlotField,get_value = strdets
chindexPtr = hfbs_choosedets(strdets)
chindex = *chindexPtr
nchoices = n_elements(chindex)
;chindex = where(choice eq 1,nchoices)

IF chindex[0] EQ -1 THEN RETURN
nxpts = nchoices
index = where(energy LE xhi and energy GE xlo,nypts)
zz = FLTARR(nxpts,nypts)
xx = FLTARR(nxpts,nypts)
yy = FLTARR(nxpts,nypts)
newdetectors= fltarr(nchoices)
newdetectors = chindex

newenergy = fltarr(nypts)
newenergy[0:nypts-1] = energy[index]
;newdata = fltarr(nchoices,nypts)

FOR i=0,nchoices-1 DO BEGIN
  FOR j=0,nypts-1 DO BEGIN
    xx[i,j] = newdetectors[i]
    yy[i,j] = newenergy[j]
    zz[i,j] = data[chindex[i],index[j]]
  ENDFOR
ENDFOR
    surfr

    IF nchoices GT 1 THEN BEGIN
      xxlo = min(xx)
      xxhi = max(xx)
    ENDIF ELSE BEGIN
      xxlo = -1+chindex[0]
      xxhi = 1+chindex[0]
    ENDELSE
    yylo = min(yy)
    yyhi = max(yy)
    zlo = min(zz)
    zhi = max(zz)

ws = chindex[0]-1
IF (*pState).nlabels[ws] EQ 'Energy' THEN BEGIN
  xlabel = '!6E (!4l!6eV)'
ENDIF

IF (*pState).nlabels[ws] EQ 'PST Channel' THEN BEGIN
  xlabel = 'PST Channel'
ENDIF

IF (*pState).nlabels[ws] EQ 'time' THEN BEGIN
   xlabel = 'time (s)'
ENDIF

IF (*pState).nlabels[ws] EQ 'temp' THEN BEGIN
   xlabel = 'T (K)'
ENDIF

IF (*pState).nlabels[ws] EQ 'Channel' THEN BEGIN
   xlabel = 'Channel'
ENDIF

winxsize = 600
winysize = 450
position = [0.1,0.1,0.9,0.9]
newxsize = (position[2]-position[0])*winxsize
newysize = (position[3]-position[1])*winysize
xstart = position[0]*winxsize
ystart = position[1]*winysize
xend = position[2]*winxsize
yend = position[3]*winysize
device,decomposed=0
new = congrid(zz,newxsize,newysize,/interp)

dxx = (xxhi-xxlo)/(newxsize)
dyy = (yyhi-yylo)/(newysize)
xx = xxlo+dxx*findgen(newxsize)
yy = yylo+dyy*findgen(newysize)
plotPosition = [xstart-2,ystart-2,xend,yend]
loadct,0
labels = strarr(nchoices)
for i = 0,nchoices-1 do begin
  labels[i] = string(xx[i])
endfor
    printPath = (*pState).printPath
    cd,printPath
    filename = DIALOG_PICKFILE(FILTER = '*.ps',dialog_parent = event.top,/write)
    ;filename = 'idl'+'.ps'
    SET_PLOT, 'PS'
    DEVICE, FILENAME=filename,/inches,xsize=5.5,ysize=4.5,bits_per_pixel=8,color=1

plot,xx,yy,/nodata,ytitle=xlabel,$
     xtitle='Detector Number',$
     position=[0.15,0.1,0.95,0.9],xtickformat='(I2)',$
     xtickname = labels,xticks = nchoices-1
loadct,6
ypicsize = 3.6
xpicsize = (5.5/4.5)*ypicsize
tvscl,new,0.83,0.45,xsize=xpicsize,ysize=ypicsize,/inches


;loadct,2
;tvscl,new,xstart,ystart
DEVICE, /CLOSE_FILE
;set_plot,'X'
set_plot,thisDevice
;spawn,'lpr idl.ps'
loadct,0


  ENDIF ELSE BEGIN
    void = dialog_message('No data in buffer',$
         dialog_parent=event.top)
  ENDELSE

  RETURN
ENDIF
;;;;;;;;;;;;;;;;;

IF (*pState).threeDplot EQ 1 THEN BEGIN
  printPath = (*pState).printPath
  cd,printPath


  ;widget_control,(*pState).PlotWsList,get_value = choice
    xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
  ;widget_control,(*pState).xrangelo,get_value = xlo
  ;widget_control,(*pState).xrangehi,get_value = xhi
  ylo = (*pState).yrangelo
  yhi = (*pState).yrangehi
;  widget_control,(*pState).yrangelo,get_value = ylo
;  widget_control,(*pState).yrangehi,get_value = yhi
  xlo = float(xlo[0]) & xhi = float(xhi[0])
  ylo = float(ylo[0]) & yhi = float(yhi[0])
  buffer = (*pState).curbuff
  (*pState).threeDplot = 1
  nchan = (*pState).buffchan[buffer]
  ndet = (*pState).ndet[buffer]

   IF PTR_VALID((*pState).BuffPtr[buffer]) THEN BEGIN
     dataPtr = ptr_new(/allocate_heap)
     dataPtr = (*pState).BuffPtr[buffer]
     data = FLTARR(ndet,nchan)
     data = *dataPtr
     energy = FLTARR(nchan)
     energy = *(*pState).BuffEnergyPtr[buffer]


  ;widget_control,(*pState).addlist,get_value = choice
  ws = (*pState).curws
; index is an array of indices which include the detectors
; to be added together...nchoices is the number of detectors
; to be summed together
;  chindex = where(choice eq 1,nchoices)
  widget_control,(*pState).selDetField,get_value = strdets
  chindexPtr = hfbs_choosedets(strdets)
  chindex = *chindexPtr
  nchoices = n_elements(chindex)
 ;chindex = where(choice eq 1,nchoices)

  IF chindex[0] EQ -1 THEN RETURN
  nxpts = nchoices
  index = where(energy LE xhi and energy GE xlo,nypts)
  zz = FLTARR(nxpts,nypts)
  xx = FLTARR(nxpts,nypts)
  yy = FLTARR(nxpts,nypts)
  newdetectors= fltarr(nchoices)
  newdetectors = chindex

  newenergy = fltarr(nypts)
  newenergy[0:nypts-1] = energy[index]


  FOR i=0,nchoices-1 DO BEGIN
    FOR j=0,nypts-1 DO BEGIN
      xx[i,j] = newdetectors[i]
      yy[i,j] = newenergy[j]
      zz[i,j] = data[chindex[i],index[j]]
    ENDFOR
  ENDFOR
    surfr

    IF nchoices GT 1 THEN BEGIN
      xxlo = min(xx)
      xxhi = max(xx)
    ENDIF ELSE BEGIN
      xxlo = -1+chindex[0]
      xxhi = 1+chindex[0]
    ENDELSE
    yylo = min(yy)
    yyhi = max(yy)
    zlo = min(zz)
    zhi = max(zz)
    filename = DIALOG_PICKFILE(FILTER = '*.ps',dialog_parent = event.top,/write)
    filename = filename+'.ps'
    SET_PLOT, 'PS'
    DEVICE, FILENAME=filename,/inches,xsize=5.5,ysize=4.5
    surface,dist(5,5),/nodata,/save,xrange=[-1+xxlo,xxhi+1],xstyle=1,yrange=[xlo,xhi],ystyle=1,$
            charsize=1.5,zrange=[zlo,zhi],zstyle=1,xtitle='Detector',ytitle='Energy', AZ = 50,AX = 45

    plots,xx,yy,zz,psym=hfbs_plotsym(/circle),/T3d
    DEVICE, /CLOSE_FILE
    ;set_plot,'x'
    set_plot,thisDevice
    ;spawn,'lpr idl.ps'
    ;plotS,detectors[1:16],energy[950:1200],data[1:16,950:1200],psym=4,symsize=2.5,/T3D
   ; shade_surf,data[1:16,950:1200],xtitle='Detector',ytitle='Channel'
  ENDIF ELSE BEGIN
    void = dialog_message('No data in buffer',$
         dialog_parent=event.top)
  ENDELSE
  RETURN
ENDIF

IF (*pState).curplot EQ 0 THEN BEGIN
;widget_control,(*pState).PlotWsList,get_value = choice

  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
;widget_control,(*pState).xrangelo,get_value = xlo
;widget_control,(*pState).xrangehi,get_value = xhi
ylo = (*pState).yrangelo
yhi = (*pState).yrangehi
;widget_control,(*pState).yrangelo,get_value = ylo
;widget_control,(*pState).yrangehi,get_value = yhi
xlo = float(xlo[0]) & xhi = float(xhi[0])
ylo = float(ylo[0]) & yhi = float(yhi[0])
;widget_control,(*pState).plotTitle,get_value = plottitle1

;plottitle = plottitle1[0]
buffer = (*pState).curbuff
;plottitle = (*pState).treatment[buffer]

;loadct,0
IF (*pState).lines NE 1 THEN BEGIN
  psymselect=[4,1,2,5,6]
  lineselect=[0,0,0,0,0]
ENDIF ELSE BEGIN
  psymselect=[0,0,0,0,0]
  lineselect=[0,1,2,3,4]
ENDELSE

;index = where(choice eq 1,nchoices)
widget_control,(*pState).selPlotField,get_value = strdets
indexPtr = hfbs_choosedets(strdets)
index = *indexPtr
nchoices = n_elements(index)
;chindex = where(choice eq 1,nchoices)

IF index[0] EQ -1 THEN BEGIN
  void = dialog_message('No workspaces selected',$
         dialog_parent=event.top)
  RETURN
ENDIF

ws = index[0]-1
IF (*pState).nlabels[ws] EQ 'Energy' THEN BEGIN
  xlabel = '!6E (!4l!6eV)'
ENDIF

IF (*pState).nlabels[ws] EQ 'PST Channel' THEN BEGIN
  xlabel = 'PST Channel'
ENDIF

IF (*pState).nlabels[ws] EQ 'time' THEN BEGIN
   xlabel = 'time (s)'
ENDIF

IF (*pState).nlabels[ws] EQ 'temp' THEN BEGIN
   xlabel = 'T (K)'
ENDIF

IF (*pState).nlabels[ws] EQ 'Channel' THEN BEGIN
   xlabel = 'Channel'
ENDIF

;;;;;;;;;;;;;;;;
; Generate legend text
;index = where(choice eq 1,nchoices)
text = ''
legendTxt = strarr(nchoices)

FOR i=0,nchoices-1 DO BEGIN
    ws = index[i]-1
    text = 'ws number'+string(1+ws)
    legendTxt[i] = hfbs_symname((*pState).symselect[ws])+':  '+strcompress(text)
ENDFOR
dypos = 0.05;(1.0-0.75)/(nchoices-1)
xpos = 0.2
ypos = FLTARR(nchoices)
ypos = 0.9-dypos*FINDGEN(nchoices)
;;;;;;;;;;;;;;;;

printPath = (*pState).printPath
cd,printPath
filename = DIALOG_PICKFILE(FILTER = '*.ps',dialog_parent = event.top,/write)
filename = filename+'.ps'
SET_PLOT, 'PS'
DEVICE, FILENAME=filename,/inches,xsize=5.5,ysize=4.5


  FOR i=0,nchoices-1 DO BEGIN
    ws = index[i]-1
    nws = (*pState).nws
    nchan = (*pState).nchan[ws]

  IF PTR_VALID((*pState).wsPtr[ws]) THEN BEGIN
    dataPtr = ptr_new(/allocate_heap)
    dataPtr = (*pState).wsPtr[ws]
    energyPtr = ptr_new(/allocate_heap)
    energyPtr = (*pState).energyPtr[ws]
    errorPtr = ptr_new(/allocate_heap)
    errorPtr = (*pState).wsErrPtr[ws]
    data = FLTARR(nchan)
    data = *dataPtr
    error = FLTARR(nchan)
    error = *errorPtr
    energy = FLTARR(nchan)
    energy = *energyPtr
    IF i EQ 0 THEN BEGIN

     IF (*pState).scale EQ 1 THEN BEGIN
      symbolid = (*pState).symselect[ws]

           IF symbolid LT 5 THEN BEGIN
             plot,energy,data,psym=hfbs_selsym(symbolid),xrange=[xlo,xhi],yrange=[ylo,yhi],$
               xstyle=1,ystyle=1,xtitle=xlabel,title = (*pState).wstreatment[ws]
             errplot,energy,data-error,data+error
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal
             ENDFOR
           ENDIF ELSE BEGIN
             plot,energy,data,psym=0,linestyle = symbolid-5,xrange=[xlo,xhi],yrange=[ylo,yhi],$
               xstyle=1,ystyle=1,xtitle=xlabel,title = (*pState).wstreatment[ws]
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal
             ENDFOR
           ENDELSE


      ENDIF ELSE BEGIN

           symbolid = (*pState).symselect[ws]
           IF symbolid LT 5 THEN BEGIN
             plot,energy,data,psym=hfbs_selsym(symbolid),$
               xtitle=xlabel,title = (*pState).wstreatment[ws]
             errplot,energy,data-error,data+error
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal
             ENDFOR
           ENDIF ELSE BEGIN
             plot,energy,data,psym=0,linestyle = symbolid-5,$
               xtitle=xlabel,title = (*pState).wstreatment[ws]
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal
             ENDFOR
           ENDELSE
           (*pState).xrangelo = min(energy)
           (*pState).xrangehi = max(energy)
;        widget_control,(*pState).xrangelo,set_value = MIN(energy)
;        widget_control,(*pState).xrangehi,set_value = MAX(energy)
        (*pState).yrangelo = min(data)
        (*pState).yrangehi = max(data)+max(error)
;        widget_control,(*pState).yrangelo,set_value = MIN(data)
;        widget_control,(*pState).yrangehi,set_value = MAX(data)+MAX(error)
      ENDELSE

    ENDIF ELSE BEGIN
        symbolid = (*pState).symselect[ws]
        IF symbolid LT 5 THEN BEGIN    ; Plot symbols and user defined limits
           oplot,energy,data,psym=hfbs_selsym((*pState).symselect[ws])
           errplot,energy,data-error,data+error
        ENDIF ELSE BEGIN   ; plot lines and user defined limits
          oplot,energy,data,psym=0,linestyle=symbolid - 5
        ENDELSE
    ENDELSE
  ENDIF ELSE BEGIN
    void = dialog_message('No data in workspace',$
         dialog_parent=event.top)
  ENDELSE
  ENDFOR

DEVICE, /CLOSE_FILE
;set_plot,'x'
set_plot,thisDevice
;spawn,'lpr idl.ps'
ENDIF ELSE BEGIN

;widget_control,(*pState).PlotWsList,get_value = choice
widget_control,(*pState).selPlotField,get_value = strdets
indexPtr = hfbs_choosedets(strdets)
index = *indexPtr
nchoices = n_elements(chindex)
;chindex = where(choice eq 1,nchoices)

;index = WHERE(choice eq 1,nchoices)
ws = index[0]-1
npts = (*pState).nchan[ws]
energyPtr = ptr_new(/allocate_heap)
energyPtr = (*pState).energyPtr[ws]
yPtr = ptr_new(/allocate_heap)
yPtr = (*pState).wsPtr[ws]
yerrPtr = ptr_new(/allocate_heap)
yerrPtr = (*pState).WsErrPtr[ws]
;widget_control,(*pState).plotTitle,get_value = plottitle1
;plottitle = plottitle1[0]

; Set up spacing for fit parameters
nparms = N_ELEMENTS(*(*pState).fitstate.parmPtr)
npos = nparms+1
num = nparms+1
dypos = 0.25/(npos-1)
ypos = FLTARR(npos)
ypos = dypos*FINDGEN(npos)
xo = 0.1 & yo = 0.5

printPath = (*pState).printPath
cd,printPath
filename = DIALOG_PICKFILE(FILTER = '*.ps',dialog_parent = event.top,/write)
filename = filename+'.ps'
SET_PLOT, 'PS'
DEVICE, FILENAME=filename,/inches,xsize=5,ysize=6

widget_control,(*pState).xfitrangelo,get_value = xxlo
widget_control,(*pState).xfitrangehi,get_value = xxhi
xxlo = float(xxlo[0])
xxhi = float(xxhi[0])

IF (*pState).xlabel EQ 'Energy' THEN BEGIN
  xlabel = '!6E (!4l!6eV)'
ENDIF

IF (*pState).xlabel EQ 'PST Channel' THEN BEGIN
  xlabel = 'PST Channel'
ENDIF


IF npts EQ 0 THEN BEGIN
  void = DIALOG_MESSAGE('No Data Present',dialog_parent=event.top)
  RETURN
ENDIF
x = DBLARR(npts)
y = DBLARR(npts)
yerr = DBLARR(npts)
x = *energyPtr & y = *yPtr & yerr = *yerrPtr
xrangeindex = WHERE((x GE xxlo) AND (x LE xxhi), newpts)
xnew = DBLARR(newpts)
ynew = DBLARR(newpts)
errnew = DBLARR(newpts)
xnew[0:newpts-1]=x[xrangeindex]
ynew[0:newpts-1]=y[xrangeindex]
errnew[0:newpts-1]=yerr[xrangeindex]

nfuncs = (*pState).fitstate.nfuncs
IF nfuncs EQ 0 THEN BEGIN
  void = DIALOG_MESSAGE('No Fits Present',dialog_parent=event.top)
  RETURN
ENDIF

pstart = DBLARR(N_ELEMENTS(*(*pState).fitstate.parmPtr))
pstart = *(*pState).fitstate.parmPtr
yfit = DBLARR(newpts)

fname = EQNAME(*(*pState).fitstate.funcSelPtr)
;print,fname
yfit = CALL_FUNCTION(fname,xnew,pstart)

IF (*pState).scale EQ 0 THEN BEGIN
  ; Auto scale
  xlo = MIN(x)
  xhi = MAX(x)
  ylo = MIN(y)
  yhi = MAX(y)+MAX(yerr)
ENDIF ELSE BEGIN
  ; User defined limits


  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
;  widget_control,(*pState).xrangelo, get_value = xlo
;  widget_control,(*pState).xrangehi, get_value = xhi
  ylo = (*pState).yrangelo
  yhi = (*pState).yrangehi
;  widget_control,(*pState).yrangelo, get_value = ylo
;  widget_control,(*pState).yrangehi, get_value = yhi
  xlo = float(xlo[0]) & xhi = float(xhi[0])
  ylo = float(ylo[0]) & yhi = float(yhi[0])
ENDELSE
xdisplo = (*pState).xrangelo
xdisphi = (*pState).xrangehi
;widget_control,(*pState).xrangelo,get_value = xdisplo
;widget_control,(*pState).xrangehi,get_value = xdisphi
xdisplo = float(xdisplo[0]) & xdisphi = float(xdisphi[0])

widget_control,(*pState).fitstate.textWid,get_value = textvalue

!P.MULTI=[0,1,2]
symbolid = (*pState).symselect[ws]

IF (*pState).nlabels[ws] EQ 'Energy' THEN BEGIN
  xlabel = '!6E (!4l!6eV)'
ENDIF

IF (*pState).nlabels[ws] EQ 'PST Channel' THEN BEGIN
  xlabel = 'PST Channel'
ENDIF

IF (*pState).nlabels[ws] EQ 'time' THEN BEGIN
   xlabel = 'time (s)'
ENDIF

IF (*pState).nlabels[ws] EQ 'temp' THEN BEGIN
   xlabel = 'T (K)'
ENDIF

IF (*pState).nlabels[ws] EQ 'Channel' THEN BEGIN
   xlabel = 'Channel'
ENDIF

IF symbolid LT 5 THEN BEGIN
  plot,x,y,xrange=[xdisplo,xdisphi],xstyle=1,yrange=[ylo,yhi],ystyle=1,$
       title = (*pState).wstreatment[ws],xtitle = xlabel,psym=hfbs_selsym(symbolid)
  errplot,x,y-yerr,y+yerr
ENDIF ELSE BEGIN
  plot,x,y,xrange=[xdisplo,xdisphi],xstyle=1,yrange=[ylo,yhi],ystyle=1,$
       title = (*pState).wstreatment[ws],xtitle = xlabel,psym=0,$
       linestyle = symbolid-5
ENDELSE
oplot,xnew,yfit,psym=0
for i=0,num-1 do begin
  xyouts,xo,yo-ypos[i],textvalue[i],/normal,charsize = 0.75
endfor

DEVICE, /CLOSE_FILE
;set_plot,'x'
set_plot,thisDevice
!P.MULTI = 0
;spawn,'lpr idl.ps'
endelse
endif


if (*pState).plotType eq 1 then begin
widget_control,(*pState).detSlider,get_value = detector
detector = fix(detector[0])
(*pState).plotType = 1
nbuff = 5
filledBuffers = intarr(nbuff)
for i = 0,nbuff-1 do begin
  filledBuffers[i] = ptr_valid((*pState).BuffPtr[i])
endfor
whereok = where(filledBuffers eq 1,numBuffers)
;  numBuffers = number of buffers currently loaded
if numBuffers eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

legendTxt = strarr(numBuffers)
FOR i=0,numBuffers-1 DO BEGIN
    text = 'Buffer: '+string(whereok[i]+1)
    legendTxt[i] = hfbs_symname((*pState).symselect[whereok[i]])+':  '+strcompress(text)
ENDFOR
dypos = 0.05
xpos = 0.15
ypos = FLTARR(numBuffers)
ypos = 0.9-dypos*FINDGEN(numBuffers)

xTemp = 0.0 & yTemp = 0.0

if (*pState).scale eq 0 then begin  ; autoscale

endif else begin  ; user scaled limits
  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
  ylo = (*pState).yrangelo
  yhi = (*pState).yrangehi
endelse

theseColors = (*pState).theseColors
colors = (*pState).colors

;wset, (*pState).winPix
errcolors = {thiscolor:theseColors[0]}
symcolor = theseColors[0]

printPath = (*pState).printPath
cd,printPath
filename = DIALOG_PICKFILE(FILTER = '*.ps',dialog_parent = event.top,/write)
filename = filename+'.ps'
SET_PLOT, 'PS'
DEVICE, FILENAME=filename,/inches,xsize=5,ysize=6

if (*pState).scale eq 0 then begin
  plot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*],$
       psym = hfbs_selsym((*pState).symselect[whereok[0]]),/nodata,xtitle = '!6E (!4l!6eV)';,color = (*pState).colors.white
endif else begin
  plot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*],xtitle = '!6E (!4l!6eV)',$
       psym = hfbs_selsym((*pState).symselect[whereok[0]]),/nodata,$;,color = (*pState).colors.white,$
       xrange = [xlo,xhi],yrange = [ylo,yhi],xstyle = 1,ystyle = 1
endelse
oplot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*],$
     psym = hfbs_selsym((*pState).symselect[whereok[0]]);,color = symcolor
errplot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*]-$
         (*(*pState).errorBuffPtr[whereok[0]])[detector,*],(*(*pState).BuffPtr[whereok[0]])[detector,*]+$
         (*(*pState).errorBuffPtr[whereok[0]])[detector,*],width = 0.0;,errcolors = errcolors

if numBuffers gt 1 then begin
  for i = 1,numBuffers-1 do begin
    errcolors = {thiscolor:theseColors[i]}
    symcolor = theseColors[i]
    oplot,(*(*pState).BuffEnergyPtr[whereok[i]]),(*(*pState).BuffPtr[whereok[i]])[detector,*],$
          psym = hfbs_selsym((*pState).symselect[whereok[i]]);,color = symcolor
    errplot,(*(*pState).BuffEnergyPtr[whereok[i]]),(*(*pState).BuffPtr[whereok[i]])[detector,*]-$
          (*(*pState).errorBuffPtr[whereok[i]])[detector,*],(*(*pState).BuffPtr[whereok[i]])[detector,*]+$
          (*(*pState).errorBuffPtr[whereok[i]])[detector,*],width = 0.0;,errcolors = errcolors
  endfor
endif
FOR k = 0,numBuffers - 1 DO BEGIN
    xyouts,xpos,ypos[k],legendTxt[k],/normal
ENDFOR

DEVICE, /CLOSE_FILE
;set_plot,'x'
set_plot,thisDevice

endif
;ENDELSE
RETURN
END
;==========================================
function is_file_there,filename
; returns a 0 if file not found and a 1 if the file is found
result = string(findfile(filename))
if result[0] ne '' then begin
  y=1
endif else begin
  y=0
endelse
return,y
end
;==========================================
PRO hfbs_dbSumDetsNew,event
widget_control,event.top, get_uvalue = pState
widget_control,(*pState).selDetField,get_value = strdets
;widget_control,(*pState).addlist,get_value = choice
ws = (*pState).curws
; index is an array of indices which include the detectors
; to be added together...nchoices is the number of detectors
; to be summed together
indexPtr = hfbs_ChooseDets(strdets)
index = *indexPtr
nchoices = n_elements(index)

buffer = (*pState).curbuff
(*pState).xlabel = (*pState).BuffLabel[buffer]

IF (index[0] NE -1) AND (PTR_VALID((*pState).BuffPtr[buffer])) THEN BEGIN

  nchan = (*pState).buffchan[buffer]
  ndet = (*pState).ndet[buffer]
  ws = (*pState).curws
  dataPtr = ptr_new(/allocate_heap)
  dataPtr = (*pState).BuffPtr[buffer]

  energyPtr = ptr_new(/allocate_heap)
  energyPtr = (*pState).BuffEnergyPtr[buffer]
  errorPtr = ptr_new(/allocate_heap)
  errorPtr = (*pState).errorBuffPtr[buffer]
  newDataPtr = ptr_new(/allocate_heap)
  newErrPtr = ptr_new(/allocate_heap)

  ;data = FLTARR(ndet,nchan)
  ;data = *dataPtr
  data = *(*pState).BuffPtr[buffer]
  error = *(*pState).errorBuffPtr[buffer]

  ;error = FLTARR(ndet,nchan)
  ;error = *errorPtr
  ;energy = FLTARR(nchan)
  ;energy = *energyPtr
  energy = *(*pState).BuffEnergyPtr[buffer]

  newdata = FLTARR(nchan)
  newerror = FLTARR(nchan)

  FOR i=0,nchoices-1 DO BEGIN
    newdata[0:nchan-1] = newdata[0:nchan-1] + data[index[i],0:nchan-1]
    newerror[0:nchan-1] = (newerror[0:nchan-1]) + (error[index[i],0:nchan-1])^2
  ENDFOR


  ;print,'max newdata: ',max(newdata[0:nchan-1])

  newerror = sqrt(newerror)

  *newDataPtr = newdata
  *newErrPtr = newerror

  *(*pState).energyPtr[ws] = *energyPtr
  (*pState).nchan[ws] = nchan
  *(*pState).wsPtr[ws] = (newdata)
  *(*pState).wsErrPtr[ws] = (newerror)

  (*pState).wstreatment[ws] = (*pState).treatment[buffer]
  (*pState).info = 'Sum completed'
  (*pState).nlabels[ws] = (*pState).BuffLabel[buffer]

; now fill out the qtys and errs pointers
  nws = n_elements((*pState).wsPtr)
  dataIndex = intarr(nws)
  for i = 0,nws-1 do begin
    if n_elements(*(*pState).wsPtr[i]) gt 0 then dataIndex[i] = 1
  endfor

  totValid = total(dataIndex)
  valid = where(dataIndex eq 1,countValid)

  wsString = strarr(countValid)
  wseString = strarr(countValid)
  wsxString = strarr(countValid)
  for i = 0,countValid-1 do begin
    x = *(*pState).energyPtr[valid[i]]
    y = *(*pState).wsPtr[valid[i]]
    yerr = *(*pState).wsErrPtr[valid[i]]
    wsxString[i] = 'wx'+strtrim(string(valid[i]+1),2)
    wsString[i] = 'w'+strtrim(string(valid[i]+1),2)
    wseString[i] = 'we'+strtrim(string(valid[i]+1),2)
    wstrExpr = 'w'+strtrim(string(valid[i]+1),2)+'=y'
    westrExpr = 'we'+strtrim(string(valid[i]+1),2)+'=yerr'
    wxstrExpr = 'wx'+strtrim(string(valid[i]+1),2)+'=x'
    r = execute(wstrExpr,1)
    r = execute(westrExpr,1)
    r = execute(wxstrExpr,1)
  endfor
  stateString = '{'
  errString = '{'
  xString = '{'
  for i = 0,countValid-1 do begin
      if i gt 0 then begin
       xString = xString+','+wsxString[i]+':'+wsxString[i]
       stateString = stateString+','+wsString[i]+':'+wsString[i]
       errString = errString+','+wsString[i]+':'+wseString[i]
     endif else begin
       xString = xString+wsxString[i]+':'+wsxString[i]
       stateString = stateString+wsString[i]+':'+wsString[i]
       errString = errString+wsString[i]+':'+wseString[i]
      endelse
  endfor
  xvarString = '*(*pState).xs='+xString+'}'
  errString = '*(*pState).errs='+errString+'}'
  stateString = '*(*pState).qtys='+stateString+'}'
  r = execute(stateString,1)
  r = execute(errString,1)
  r = execute(xvarString,1)

  widget_control,event.top,set_uvalue = pState
ENDIF ELSE BEGIN
        (*pState).info = 'No detectors selected'
  ;void = dialog_message(['No Detectors Selected'],dialog_parent=event.top)
ENDELSE

RETURN
END
;==========================================
PRO SelCircles,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 0
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelTriangles,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 1
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelDiamonds,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 2
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelBoxes,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 3
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelLines,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 4
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelContLine,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 5
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelDotLine,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 6
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelDashLine,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 7
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelDashDotLine,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 8
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelDashDotDotDotLine,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 9
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelLongDashLine,event
widget_control,event.top,get_uvalue = pState
(*pState).symselect[(*pState).curws] = 10
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
Pro hfbs_dbPlotZoom,pState,xlo,xhi,ylo,yhi
;widget_control,(*pState).PlotWsList,get_value = choice

buffer = (*pState).curbuff

IF (*pState).lines NE 1 THEN BEGIN
  lineselect=[0,0,0,0,0]
ENDIF ELSE BEGIN
  lineselect=[0,1,2,3,4]
ENDELSE

;;;;;;;;;;;;;;;;
; Generate legend text
;index = where(choice eq 1,nchoices)
widget_control,(*pState).selPlotField,get_value = strdets
indexPtr = hfbs_ChooseDets(strdets)
index = *indexPtr
nchoices = n_elements(index)

wugga = intarr(nchoices)
for i = 0,nchoices-1 do begin
  if n_elements(*((*pState).wsPtr[index[i]-1])) lt 1 then wugga[i] = 1
endfor
if total(wugga) gt 0 then return

;print,'Index: ',index
;print,'Number of elements in index: ',nchoices
text = ''

if nchoices eq 0 then begin
  void = dialog_message('No workspaces selected',dialog_parent = event.top)
  return
end

legendTxt = strarr(nchoices)

ws = index[0]-1
IF (*pState).nlabels[ws] EQ 'Energy' THEN BEGIN
  xlabel = '!6E (!4l!6eV)'
ENDIF

IF (*pState).nlabels[ws] EQ 'PST Channel' THEN BEGIN
  xlabel = 'PST Channel'
ENDIF

IF (*pState).nlabels[ws] EQ 'time channel' THEN BEGIN
   xlabel = 'time channel'
ENDIF

IF (*pState).nlabels[ws] EQ 'temp' THEN BEGIN
   xlabel = 'T (K)'
ENDIF

IF (*pState).nlabels[ws] EQ 'Channel' THEN BEGIN
   xlabel = 'Channel'
ENDIF
xlabel = (*pState).xlabel

; determine the data maximum
nchan = (*pState).nchan[0]
if nchan eq -1 or nchoices eq 0 then begin
  return
endif
ydat = dblarr(nchoices,(*pState).nchan[0])
ymaxVector = dblarr(nchoices)
emaxVector = dblarr(nchoices)
eminVector = dblarr(nchoices)

for i = 0,nchoices-1 do begin
  ymaxVector[i] = max(*((*pState).wsPtr[index[i]-1]))
  emaxVector[i] = max(*((*pState).energyPtr[index[i]-1]))
  eminVector[i] = min(*((*pState).energyPtr[index[i]-1]))
endfor
ymax = max(ymaxVector)
ymax = double(ymax[0])

emax = max(emaxVector)
emax = double(emax[0])
emin = min(eminVector)
emin = double(emin[0])

colors = (*pState).theseColors

FOR i=0,nchoices-1 DO BEGIN
    ws = index[i]-1
    text = 'ws number'+string(1+ws)
    legendTxt[i] = hfbs_symname((*pState).symselect[ws])+':  '+strcompress(text)
ENDFOR

dypos = 0.05
xpos = 0.15
ypos = FLTARR(nchoices)
ypos = 0.9-dypos*FINDGEN(nchoices)
;;;;;;;;;;;;;;;;

IF index[0] NE -1 THEN BEGIN
  FOR i=0,nchoices-1 DO BEGIN
    ws = index[i]-1
    nws = (*pState).nws
    nchan = (*pState).nchan[ws]
    symcolor = colors[i]
    errcolors = {thiscolor:symcolor}
  IF PTR_VALID((*pState).wsPtr[ws]) THEN BEGIN
    dataPtr = ptr_new(/allocate_heap)
    dataPtr = (*pState).wsPtr[ws]
    energyPtr = ptr_new(/allocate_heap)
    energyPtr = (*pState).energyPtr[ws]
    errorPtr = ptr_new(/allocate_heap)
    errorPtr = (*pState).wsErrPtr[ws]
    data = FLTARR(nchan)
    data = *dataPtr
    error = FLTARR(nchan)
    error = *errorPtr
    energy = FLTARR(nchan)
    energy = *energyPtr

    IF i EQ 0 THEN BEGIN
      IF (*pState).scale EQ 1 THEN BEGIN
      symbolid = (*pState).symselect[ws]

           IF symbolid LT 5 THEN BEGIN
             plot,energy,data,psym=hfbs_selsym(symbolid),xrange=[xlo,xhi],yrange=[ylo,yhi],$
               xstyle=1,ystyle=1,xtitle=xlabel,title = (*pState).wstreatment[ws],$
               color = (*pState).colors.white
             if (*pState).errBars then begin
               errcolors = {thiscolor:(*pState).colors.white}
               hfbs_cerrplot,energy,data-error,data+error,width = 0.0,errcolors = errcolors
             endif
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = colors[k]
             ENDFOR
           ENDIF ELSE BEGIN
             plot,energy,data,psym=0,linestyle = symbolid-5,xrange=[xlo,xhi],yrange=[ylo,yhi],$
               xstyle=1,ystyle=1,xtitle=xlabel,title = (*pState).wstreatment[ws],$
               color = (*pState).colors.white
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = colors[k]
             ENDFOR
           ENDELSE


      ENDIF ELSE BEGIN  ; autoscaling

           symbolid = (*pState).symselect[ws]
           IF symbolid LT 5 THEN BEGIN
             plot,energy,data,psym=hfbs_selsym(symbolid),$
               xtitle=xlabel,title = (*pState).wstreatment[ws],$
               ;yrange = [0.0,1.1*ymax],ystyle = 1,$
               color = symcolor;,$
               ;xrange = [emin,emax],xstyle = 1
             if (*pState).errBars then begin
               hfbs_cerrplot,energy,data-error,data+error,width = 0.0,errcolors = errcolors
             endif
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = colors[k]
             ENDFOR
           ENDIF ELSE BEGIN
             plot,energy,data,psym=0,linestyle = symbolid-5,$
               xtitle=xlabel,title = (*pState).wstreatment[ws],$
               ;yrange = [0.0,1.1*ymax],ystyle = 1,$
               color = symcolor;,$
               ;xrange = [emin,emax],xstyle = 1
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = colors[k]
             ENDFOR
           ENDELSE
           (*pState).xrangelo = emin;min(energy)
           (*pState).xrangehi = emax;max(energy)
        ;widget_control,(*pState).xrangelo,set_value = MIN(energy)
        ;widget_control,(*pState).xrangehi,set_value = MAX(energy)
        (*pState).yrangelo = 0.0
        (*pState).yrangehi = 1.1*ymax
;        widget_control,(*pState).yrangelo,set_value = 0.0;MIN(data)
;        widget_control,(*pState).yrangehi,set_value = 1.1*ymax;MAX(data)+MAX(error)
      ENDELSE

    ENDIF ELSE BEGIN
        symbolid = (*pState).symselect[ws]
        IF symbolid LT 5 THEN BEGIN    ; Plot symbols and user defined limits
           oplot,energy,data,psym=hfbs_selsym((*pState).symselect[ws]),color = symcolor
           if (*pState).errBars then begin
             hfbs_cerrplot,energy,data-error,data+error,width = 0.0,errcolors = errcolors
           endif
        ENDIF ELSE BEGIN   ; plot lines and user defined limits
          oplot,energy,data,psym=0,linestyle=symbolid - 5,color = symcolor
        ENDELSE
    ENDELSE
  ENDIF ELSE BEGIN
    void = dialog_message('No data in workspace',dialog_parent = event.top)
  ENDELSE
  ENDFOR

ENDIF ELSE BEGIN
    void = dialog_message('No workspaces selected',dialog_parent = event.top)
ENDELSE
(*pState).curplot = 0
RETURN
END
;==========================================
PRO ABOUT,event
void = dialog_message(['Written by R.M.Dimeo',$
       'April 14, 1999'],dialog_parent=event.top,/information)
RETURN
END
;==========================================
PRO SelWork,event
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).curws = event.index
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
;PRO ViewHeader,event
;widget_control,event.top,get_uvalue = pState
;widget_control,/hourglass
;buffer = (*pState).curbuff
;filename = (*pState).filename[buffer]
;IF filename NE 'Empty' THEN BEGIN
;  cd,'c:\dimeo\hfbs\data'

;  XDisplayFile, filename, $
;                TITLE = "ASCII Data File", $
;                GROUP = event.top, $
;                WIDTH = 55, $
;                HEIGHT = 16

;ENDIF
;RETURN
;END
;==========================================
PRO DisplayHelp,event
widget_control,event.top,get_uvalue = pState
helpPath = (*pState).helpPath
cd,helpPath
XDisplayFile, 'browser.txt', $
                TITLE = "Data Browser Help", $
                GROUP = event.top, $
                WIDTH = 80, $
                HEIGHT = 20

RETURN
END
;==========================================
PRO SelDet,event
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).curdet = event.index
ENDIF
;print,(*pState).curdet
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO AnnotatePlot,event
widget_control,event.top,get_uvalue = pState
thisDevice = !d.name
Annotate
set_plot,thisDevice
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelBuffer,event
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).curbuff = FIX(event.index)
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelW1,event
; Used for workspace operations
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).ws1 = event.index
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelW2,event
; Used for workspace operations
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).ws2 = event.index
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelW3,event
; Used for workspace operations
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).ws3 = event.index
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelOp,event
; Used for workspace operations
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).op = FIX(event.index)
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO AutoScale,event
widget_control,event.top,get_uvalue = pState
(*pState).scale = 1;0
;;;;;
widget_control,(*pState).selPlotField,get_value = strdets
indexPtr = hfbs_ChooseDets(strdets)
index = *indexPtr
nchoices = n_elements(index)
emin = fltarr(nchoices)
emax = fltarr(nchoices)
ymin = fltarr(nchoices)
ymax = fltarr(nchoices)
for i=0,nchoices - 1 do begin
  ws = index[i]-1
  emin[i] = min(*((*pState).energyPtr[ws]))
  emax[i] = max(*((*pState).energyPtr[ws]))
  ymin[i] = min(*((*pState).wsPtr[ws]))
  ymax[i] = max(*((*pState).wsPtr[ws]))
endfor
xlo = min(emin) & xhi = max(emax)
ylo = min(ymin) & yhi = max(ymax)

(*pState).xrangelo = xlo
(*pState).xrangehi = xhi
;widget_control,(*pState).xrangelo,set_value = xlo
ylo = (*pState).yrangelo
yhi = (*pState).yrangehi
;widget_control,(*pState).yrangelo,set_value = ylo
;widget_control,(*pState).xrangehi,set_value = xhi
;widget_control,(*pState).yrangehi,set_value = yhi

;;;;;
;xlo = -1.0 & xhi = 1.0
;ylo = 0.0 & yhi = 1.0
hfbs_dbPlotZoom,pState,xlo,xhi,ylo,yhi
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO UserScale,event
widget_control,event.top,get_uvalue = pState
(*pState).scale = 1
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO PlotLines,event
widget_control,event.top,get_uvalue = pState
(*pState).sym = 0
(*pState).lines = 1
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO PlotSymbols,event
widget_control,event.top,get_uvalue = pState
(*pState).sym = 1
(*pState).lines = 0
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SelTargWs,event
; Target workspace for rebinning
widget_control,event.top,get_uvalue = pState

IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_DROPLIST') THEN BEGIN
  (*pState).TargetWs = FIX(event.index)
ENDIF
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO SaveWsCols,event
widget_control,event.top,get_uvalue = pState
ws = (*pState).curws
nchan = (*pState).nchan[ws]
IF nchan EQ 0 THEN BEGIN
  void = dialog_message(['No Files Loaded'],dialog_parent=event.top)
  RETURN
ENDIF
IF nchan EQ -1 THEN BEGIN
  void = dialog_message(['No Files Loaded'],dialog_parent=event.top)
  RETURN
ENDIF

result = FLTARR(nchan)
error = FLTARR(nchan)
energy = FLTARR(nchan)

ws1Ptr = ptr_new(/allocate_heap)
wserr1Ptr = ptr_new(/allocate_heap)
wserr1Ptr = (*pState).wserrPtr[ws]

IF NOT (PTR_VALID(wserr1Ptr)) THEN BEGIN
  void = dialog_message(['Workspace empty'],dialog_parent=event.top)
RETURN
ENDIF
energyPtr = ptr_new(/allocate_heap)
energyPtr = (*pState).energyPtr[ws]
energy = *energyPtr

ws1Ptr = (*pState).wsPtr[ws]
error = *wserr1Ptr
result = *ws1Ptr
file = DIALOG_PICKFILE(filter='*.ws')
file = file+'.ws'
writefile = STRPOS(file, 'ws')
IF writefile EQ -1 THEN RETURN

; print the data out as energy first, then data, then errors
openw,lun,file,/get_lun
FOR i=0,nchan-2 DO BEGIN
  printf,lun,energy[i],result[i],error[i],format='(3(E15.6,x))'
ENDFOR
free_lun,lun

RETURN
END
;==========================================
PRO SaveWorkSpace,event
widget_control,event.top,get_uvalue = pState

ws = (*pState).curws
nchan = (*pState).nchan[ws]
;print,nchan
IF nchan EQ 0 THEN BEGIN
  void = dialog_message(['No Files Loaded'],dialog_parent=event.top)
RETURN
ENDIF
result = FLTARR(nchan)
error = FLTARR(nchan)
energy = FLTARR(nchan)

ws1Ptr = ptr_new(/allocate_heap)
wserr1Ptr = ptr_new(/allocate_heap)
wserr1Ptr = (*pState).wserrPtr[ws]

IF NOT (PTR_VALID(wserr1Ptr)) THEN BEGIN
  void = dialog_message(['Workspace empty'],dialog_parent=event.top)
RETURN
ENDIF
energyPtr = ptr_new(/allocate_heap)
energyPtr = (*pState).energyPtr[ws]
energy = *energyPtr

ws1Ptr = (*pState).wsPtr[ws]
error = *wserr1Ptr
result = *ws1Ptr
file = DIALOG_PICKFILE(filter='*.ws')
file = file+'.ws'
writefile = STRPOS(file, 'ws')
IF writefile EQ -1 THEN RETURN

; print the data out as energy first, then data, then errors
openw,lun,file,/get_lun
printf,lun,nchan
printf,lun,energy
printf,lun,result
printf,lun,error
free_lun,lun

RETURN
END
;==========================================
PRO LoadWorkSpace,event
widget_control,event.top,get_uvalue = pState
ws = (*pState).curws

file = DIALOG_PICKFILE(filter='*.ws')
readfile = STRPOS(file, 'ws')
IF readfile EQ -1 THEN RETURN
; read the data and errors
openr,lun,file,/get_lun
readf,lun,nchan
energy = FLTARR(nchan)
result = FLTARR(nchan)
error = FLTARR(nchan)
readf,lun,energy
readf,lun,result
readf,lun,error
free_lun,lun

energyPtr = PTR_NEW(/allocate_heap)
wsPtr = PTR_NEW(/allocate_heap)
wserrPtr = PTR_NEW(/allocate_heap)

*energyPtr = energy
*wsPtr = result
*wserrPtr = error

(*pState).energyPtr[ws] = energyPtr
(*pState).wsPtr[ws] = wsPtr
(*pState).wserrPtr[ws] = wserrPtr
(*pState).nchan[ws] = nchan
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO ExecOp,event
widget_control,event.top,get_uvalue = pState
nws = (*pState).nws   ; number of workspaces
ws1 = (*pState).ws1
ws2 = (*pState).ws2
;print,nws,ws1,ws2
; Test if either workspace selected was a constant
; OK
IF (ws1 EQ nws-1) AND (ws2 EQ nws-1) THEN BEGIN
  void = dialog_message('Both workspaces cannot be constants',$
         dialog_parent=event.top)
  RETURN
ENDIF
; Not OK
IF ((ws1 EQ nws-1) AND (N_ELEMENTS((*pState).nchan[ws2]) EQ -1)) THEN BEGIN
  void = dialog_message('Incompatible workspace dimensions',dialog_parent=event.top)
  RETURN
ENDIF
; Not OK
IF ((ws2 EQ nws-1) AND (N_ELEMENTS((*pState).nchan[ws2]) EQ -1)) THEN BEGIN
  void = dialog_message('Incompatible workspace dimensions',dialog_parent=event.top)
  RETURN
ENDIF

; This next statement is causing problems

IF (ws1 NE nws-1) AND (ws2 NE nws-1) AND (((*pState).nchan[ws1] EQ -1) $
    OR ((*pState).nchan[ws2] EQ -1))THEN BEGIN
     void = dialog_message('Incompatible workspace dimensions',dialog_parent=event.top)
   RETURN
ENDIF

IF (ws1 NE nws-1) AND (ws2 NE nws-1) AND ((*pState).nchan[ws1] EQ -1) AND $
    ((*pState).nchan[ws2] EQ -1) THEN BEGIN
  void = dialog_message(['No Files Loaded'],dialog_parent=event.top)
  RETURN
ENDIF

IF (ws1 NE nws-1) AND ((*pState).nchan[ws1] EQ -1) THEN BEGIN
  void = dialog_message(['Workspace Not Loaded'],dialog_parent=event.top)
  RETURN
ENDIF

IF (ws2 NE nws-1) AND ((*pState).nchan[ws2] EQ -1) THEN BEGIN
  void = dialog_message(['Workspace Not Loaded'],dialog_parent=event.top)
  RETURN
ENDIF

ws1Ptr = ptr_new(/allocate_heap)
ws2Ptr = ptr_new(/allocate_heap)
ws3Ptr = ptr_new(/allocate_heap)

wserr1Ptr = ptr_new(/allocate_heap)
wserr2Ptr = ptr_new(/allocate_heap)
wserr3Ptr = ptr_new(/allocate_heap)
energyPtr = ptr_new(/allocate_heap)

    if ws1 eq nws-1 then begin
      nchan = (*pState).nchan[ws2]
      energyPtr = (*pState).energyPtr[ws2]
    endif
    if ws2 eq nws-1 then begin
      nchan = (*pState).nchan[ws1]
      energyPtr = (*pState).energyPtr[ws1]
    endif
    if ws2 ne nws-1 and ws1 ne nws-1 then begin
      nchan = (*pState).nchan[ws1]
      energyPtr = (*pState).energyPtr[ws1]
    endif

    ws1Ptr = (*pState).wsPtr[ws1]
    ws2Ptr = (*pState).wsPtr[ws2]
    ws1data = fltarr(nchan)
    ws2data = fltarr(nchan)
    ws1dataerr = fltarr(nchan)
    ws2dataerr = fltarr(nchan)

    if not ptr_valid(ws1Ptr) then begin
      ws1data[0:nchan-1]=1.0+0.0*fltarr(nchan)
      ws1dataerr[0:nchan-1]=1.0e-7+0.0*fltarr(nchan)
    endif else begin
      ws1data = *ws1Ptr
      wserr1Ptr = (*pState).wserrPtr[ws1]
      ws1dataerr = *wserr1Ptr
    endelse

    if not ptr_valid(ws2Ptr) then begin
      ws2data[0:nchan-1]=1.0+0.0*fltarr(nchan)
      ws2dataerr[0:nchan-1]=1.0e-7+0.0*fltarr(nchan)
    endif else begin
      ws2data = *ws2Ptr
      wserr2Ptr = (*pState).wserrPtr[ws2]
      ws2dataerr = *wserr2Ptr
    endelse
;    ws2data = *ws2Ptr
;    wserr1Ptr = (*pState).wserrPtr[ws1]
;    wserr2Ptr = (*pState).wserrPtr[ws2]
;    ws1dataerr = *wserr1Ptr
;    ws2dataerr = *wserr2Ptr

result = FLTARR(nchan)
error = FLTARR(nchan)

widget_control,(*pState).const1,get_value = c1
widget_control,(*pState).const2,get_value = c2
c1 = float(c1[0]) & c2 = float(c2[0])

IF NOT (PTR_VALID(wserr1Ptr)) THEN BEGIN
  void = dialog_message(['At least one workspace not valid'],dialog_parent=event.top)
RETURN
ENDIF

IF NOT (PTR_VALID(wserr2Ptr)) THEN BEGIN
  void = dialog_message(['At least one workspace not valid'],dialog_parent=event.top)
RETURN
ENDIF

result = FLTARR(nchan)
error = FLTARR(nchan)

CASE (*pState).op OF
  0:  BEGIN
        result = c1*(ws1data)+c2*(ws2data)
        error = SQRT((c1*(ws1dataerr))^2+(c2*(ws2dataerr))^2)
      END
  1:  BEGIN
        result = c1*(ws1data)-c2*(ws2data)
        error = SQRT((c1*(ws1dataerr))^2+(c2*(ws2dataerr))^2)
      END
  2:  BEGIN
        result = c1*(ws1data)*c2*(ws2data)
        if ptr_valid(ws2Ptr) then begin
          error = SQRT((c1*(ws1data)*(ws1dataerr))^2+$
                      (c2*(ws2data)*(ws2dataerr))^2)
        endif else begin
          error = ws1dataerr*c2
        endelse
      END
  3:  BEGIN
        result = c1*(ws1data)/(c2*(ws2data))
        u = c1*ws1data & v = c2*ws2data
        sigu = c1*ws1dataerr & sigv = c2*ws2dataerr
        if ptr_valid(ws2Ptr) then begin
;          error = (1.0/v^2)*sqrt(u*v^2+v*u^2)
          error = (1.0/v^2)*sqrt((sigu*v)^2+(sigv*u)^2)
        endif else begin
          error = ws1dataerr/c2
        endelse
        ;error = result*SQRT((c1*(ws1dataerr)/(ws1data))^2+$
        ;            (c2*(ws2dataerr)/(ws2data))^2)

        index = where(FINITE(result) NE 1)
        if index ne -1 then begin
          result[index] = 0.0
          result[index] = 0.0
        endif
      END
ENDCASE
*ws3Ptr = result
*wserr3Ptr = error
(*pState).nlabels[(*pState).ws3] = (*pState).nlabels[ws1]
(*pState).nchan[(*pState).ws3] = nchan
(*pState).energyPtr[(*pState).ws3]=energyPtr
(*pState).wsPtr[(*pState).ws3] = ws3Ptr
(*pState).wserrPtr[(*pState).ws3] = wserr3Ptr

; Set the plotting workspace to the result of the calculation
thisWs = string(1+(*pState).ws3)
widget_control,(*pState).selPlotField,set_value = thisWs
widget_control,event.top,set_uvalue = pState,/no_copy
plotWs,event
widget_control,event.top,get_uvalue = pState,/no_copy
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO WriteAdd,event

widget_control,event.top,get_uvalue = pState
widget_control,(*pState).addlist,get_value = choice
ws = (*pState).curws
; index is an array of indices which include the detectors
; to be added together...nchoices is the number of detectors
; to be summed together
index = where(choice eq 1,nchoices)
buffer = (*pState).curbuff
IF (index[0] NE -1) AND (PTR_VALID((*pState).BuffPtr[buffer])) THEN BEGIN

  nchan = (*pState).buffchan[buffer]
  ndet = (*pState).ndet[buffer]
  ws = (*pState).curws
  dataPtr = ptr_new(/allocate_heap)
  dataPtr = (*pState).BuffPtr[buffer]
  energyPtr = ptr_new(/allocate_heap)
  energyPtr = (*pState).BuffEnergyPtr[buffer]
  errorPtr = ptr_new(/allocate_heap)
  errorPtr = (*pState).errorBuffPtr[buffer]
  newDataPtr = ptr_new(/allocate_heap)
  newErrPtr = ptr_new(/allocate_heap)

  data = FLTARR(ndet,nchan)
  data = *dataPtr
  error = FLTARR(ndet,nchan)
  error = *errorPtr
  energy = FLTARR(nchan)
  energy = *energyPtr
  newdata = FLTARR(nchan)
  newerror = FLTARR(nchan)

  FOR i=0,nchoices-1 DO BEGIN
    newdata[0:nchan-1] = newdata[0:nchan-1] + data[index[i],0:nchan-1]
    newerror[0:nchan-1] = newerror[0:nchan-1] + error[index[i],0:nchan-1]
  ENDFOR
  *newDataPtr = newdata
  *newErrPtr = newerror
  (*pState).energyPtr[ws] = energyPtr
  (*pState).nchan[ws] = nchan
  (*pState).wsPtr[ws] = newDataPtr
  (*pState).wsErrPtr[ws] = newErrPtr

  (*pState).wstreatment[ws] = (*pState).treatment[buffer]
  widget_control,event.top,set_uvalue = pState
ENDIF ELSE BEGIN
  void = dialog_message(['No Detectors Selected'],dialog_parent=event.top)
ENDELSE

RETURN
END
;==========================================
PRO Read3Cols,event
widget_control,event.top,get_uvalue = pState
ws = (*pState).curws
(*pState).xlabel = ''

cd,(*pState).dataPath
file = DIALOG_PICKFILE(filter='*.dat')
IF file EQ '' THEN RETURN ELSE BEGIN
   OPENR, lun, file, /GET_LUN
   nbig  = 50000
   x     = dblarr(nbig)
   y     = dblarr(nbig)
   yerr  = dblarr(nbig)
   x1    = 0.0
   y1    = 0.0
   y1err = 0.0
   count = 0
   WHILE (NOT EOF(lun)) DO BEGIN
      READF, lun, x1,y1,y1err
      x[count] = x1
      y[count] = y1
      yerr[count] = y1err
      count = count + 1
   ENDWHILE
   FREE_LUN, lun

xPtr = ptr_new(/allocate_heap)
yPtr = ptr_new(/allocate_heap)
errPtr = ptr_new(/allocate_heap)

*xPtr = x[0:count-1]
*yPtr = y[0:count-1]
*errPtr = yerr[0:count-1]

(*pState).energyPtr[ws] = xPtr
(*pState).wsPtr[ws] = yPtr
(*pState).wsErrPtr[ws] = errPtr

(*pState).xrangelo = min(x)
(*pState).xrangehi = max(x)
;widget_control,(*pState).xrangelo,set_value = MIN(x)
;widget_control,(*pState).xrangehi,set_value = MAX(x)
(*pState).yrangelo = min(y)
(*pState).yrangehi = max(y)
;widget_control,(*pState).yrangelo,set_value = MIN(y)
;widget_control,(*pState).yrangehi,set_value = MAX(y)
(*pState).nchan[ws] = count
(*pState).wstreatment[ws] = 'Arbitrary'
(*pState).xlabel = 'Channel'
widget_control,event.top,set_uvalue = pState
ENDELSE
RETURN
END
;==========================================
PRO ReadOldHFBS,event
widget_control,event.top,get_uvalue = pState
widget_control,/hourglass
nws = (*pState).nws
nbuff = (*pState).nbuff
ws = (*pState).curws
buffer = (*pState).curbuff
(*pState).treatment[buffer] = 'counts'
cd,(*pState).datapath
file = DIALOG_PICKFILE(filter='*.hfbs')
Result = STRPOS(file, 'hfbs')
IF Result EQ -1 THEN RETURN
(*pState).filename[buffer] = file
widget_control,(*pState).buffer1,set_value = (*pState).filename[0]
widget_control,(*pState).buffer2,set_value = (*pState).filename[1]
widget_control,(*pState).buffer3,set_value = (*pState).filename[2]
widget_control,(*pState).buffer4,set_value = (*pState).filename[3]
widget_control,(*pState).buffer5,set_value = (*pState).filename[4]

OPENR, lun, file, /GET_LUN
header=strarr(5)
comments = ''
dumstr = ''
dumstr1 = ''
dumstrmode = ''
ch = 0
intensity = 0.0

;Begin reading in information

READF, lun, dumstr     ; read comments

(*pState).comments[buffer]=strmid(dumstr,21)
READF, lun, dumstrmode  ; read mode

(*pState).mode[buffer]=strmid(dumstrmode,21)
READF, lun, dumstr     ; up to and including line 7

(*pState).start_time[buffer]=strmid(dumstr,21)
READF, lun, dumstr

(*pState).stop_time[buffer]=strmid(dumstr,21)
READF, lun, dumstr

(*pState).cycles[buffer]=strmid(dumstr,21)
READF, lun, dumstr

(*pState).cycle_time[buffer]=strmid(dumstr,21)
READF, lun, dumstr

(*pState).live_time[buffer]=strmid(dumstr,21)

; Test if in teach mode ('t'), standard mode ('s'), or
; hybrid mode ('h')

CASE strmid(dumstrmode,21,2) OF
'st':  BEGIN
      ndet = 23
      nchan = 2048
      data = FLTARR(ndet,nchan)
      error = FLTARR(ndet,nchan)

      FOR i = 0,ndet-1 DO BEGIN
         READF, lun, dumstr1
         FOR j = 0,nchan-1 DO BEGIN
           READF, lun, ch, intensity
           data[i,j] = intensity
           error[i,j] = SQRT(intensity)
         ENDFOR
      ENDFOR
      FREE_LUN, lun

        energy = FLTARR(nchan)
        lamo = 6.27
        eo = 81.81/lamo^2
        vo = 3956.0/lamo
        chan2ueV = (2.0*eo*1.0e3/vo)/(2048.0/20.0)
        energy = chan2uev*(-1024.0+FINDGEN(nchan))

        totdetcounts = INTARR(ndet)
        FOR i=0,ndet-1 DO BEGIN
          totdetcounts[i] = TOTAL(data[i,0:nchan-1])
        ENDFOR
        moncount = 0l
        moncount = TOTAL(data[0,0:nchan-1])

        detcntPtr = PTR_NEW(INTARR(ndet))
        *detcntPtr = totdetcounts

        energyPtr = ptr_new(FLTARR(nchan))
        *energyPtr = energy[0:nchan-1]

        dataPtr = ptr_new(FLTARR(ndet,nchan))
        *dataPtr = data[0:ndet-1,0:nchan-1]

        errorPtr = ptr_new(FLTARR(ndet,nchan))
        *errorPtr = error[0:ndet-1,0:nchan-1]

        MonPtr = ptr_new(/allocate_heap)
        *MonPtr = data[0,0:nchan-1]

        PvLowPtr = ptr_new(/allocate_heap)
        *PvLowPtr = data[21,0:nchan-1]

        PvHighPtr = ptr_new(/allocate_heap)
        *PvHighPtr = data[22,0:nchan-1]

        PvMonPtr = ptr_new(/allocate_heap)
        *PvMonPtr = data[20,0:nchan-1]


        (*pState).PvLowPtr = PvLowPtr
        (*pState).PvHighPtr = PvHighPtr
        (*pState).PvMonPtr[buffer] = PvMonPtr
        (*pState).BuffPvPtr[buffer] = PvHighPtr
        (*pState).xlabel = 'Energy'
        void = dialog_message('Data file successfully read!',/information)
      END
'te':  BEGIN
      ndet = 20
      nchan = 4096
      data = FLTARR(ndet,nchan)
      error = FLTARR(ndet,nchan)

      FOR i = 0,ndet-1 DO BEGIN
         READF, lun, dumstr1
         FOR j = 0,nchan-1 DO BEGIN
           READF, lun, ch, intensity
           data[i,j] = intensity
           error[i,j] = SQRT(intensity)
         ENDFOR
      ENDFOR

        FREE_LUN, lun
        totdetcounts = INTARR(ndet)

        FOR i=0,ndet-1 DO BEGIN
          totdetcounts[i] = TOTAL(data[i,0:nchan-1])
        ENDFOR

        energy = FLTARR(nchan)
        lamo = 6.27
        eo = 81.81/lamo^2
        vo = 3956.0/lamo
        chan2ueV = (2.0*eo*1.0e3/vo)/(2048.0/20.0)
        energy = 1.0+FINDGEN(nchan)


        moncount = 0l
        moncount = TOTAL(data[0,0:nchan-1])

        detcntPtr = PTR_NEW(INTARR(ndet))
        *detcntPtr = totdetcounts

        energyPtr = ptr_new(FLTARR(nchan))
        *energyPtr = energy[0:nchan-1]

        dataPtr = ptr_new(FLTARR(ndet,nchan))
        *dataPtr = data[0:ndet-1,0:nchan-1]

        errorPtr = ptr_new(FLTARR(ndet,nchan))
        *errorPtr = error[0:ndet-1,0:nchan-1]

        MonPtr = ptr_new(/allocate_heap)
        *MonPtr = data[0,0:nchan-1]
        (*pState).xlabel = 'PST channel'
        void = dialog_message('Data file successfully read!',/information)
      END

'ti': BEGIN
      ndet = 20
      nchan = 4096
      data = FLTARR(ndet,nchan)
      error = FLTARR(ndet,nchan)

      FOR i = 0,ndet-1 DO BEGIN
         READF, lun, dumstr1
         FOR j = 0,nchan-1 DO BEGIN
           READF, lun, ch, intensity
           data[i,j] = intensity
           error[i,j] = SQRT(intensity)
         ENDFOR
      ENDFOR

        FREE_LUN, lun
        totdetcounts = INTARR(ndet)

        FOR i=0,ndet-1 DO BEGIN
          totdetcounts[i] = TOTAL(data[i,0:nchan-1])
        ENDFOR

        energy = FLTARR(nchan)
        lamo = 6.27
        eo = 81.81/lamo^2
        vo = 3956.0/lamo
        chan2ueV = (2.0*eo*1.0e3/vo)/(2048.0/20.0)
        energy = 1.0+FINDGEN(nchan)


        moncount = 0l
        moncount = TOTAL(data[0,0:nchan-1])

        detcntPtr = PTR_NEW(INTARR(ndet))
        *detcntPtr = totdetcounts

        energyPtr = ptr_new(FLTARR(nchan))
        *energyPtr = energy[0:nchan-1]

        dataPtr = ptr_new(FLTARR(ndet,nchan))
        *dataPtr = data[0:ndet-1,0:nchan-1]

        errorPtr = ptr_new(FLTARR(ndet,nchan))
        *errorPtr = error[0:ndet-1,0:nchan-1]

        MonPtr = ptr_new(/allocate_heap)
        *MonPtr = data[0,0:nchan-1]
        (*pState).xlabel = 'time channel'
        void = dialog_message('Data file successfully read!',/information)
       END
'hy':  BEGIN
        void = dialog_message(['Hybrid mode not supported yet.'])
        RETURN
      END
ELSE:  void = dialog_message(['Not a valid HFBS file.'])
ENDCASE

(*pState).BuffEnergyPtr[buffer] = energyPtr
(*pState).BuffMonPtr[buffer] = MonPtr

(*pState).BuffPtr[buffer] = dataPtr
(*pState).errorBuffPtr[buffer] = errorPtr
(*pState).errorPtr = errorPtr

nws = (*pState).nws
(*pState).buffchan[buffer] = nchan
(*pState).ndet[buffer] = ndet
(*pState).detcountPtr[buffer] = detcntPtr
(*pState).moncount[buffer] = moncount
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO hfbsdbloadDAVE,event
widget_control,event.top,get_uvalue = pState,/no_copy

nws = (*pState).nws
nbuff = (*pState).nbuff
ws = (*pState).curws
buffer = (*pState).curbuff


cd,(*!dave_defaults).workdir;(*(*pState).inPtr).workDir
file = DIALOG_PICKFILE(dialog_parent = event.top,$
                                              title = 'Select data file to restore',$
                                              /read,filter = '*.dave')
if file eq '' then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
restore,file
state = *davePtr
;dave_beast_ops,"remove",davePtr
ptr_free,davePtr

workDir = (*!dave_defaults).workDir
datDir = (*!dave_defaults).datDir

;;;;
; Pull out the relevant portions of the DAVE workspace here and
; make them fit in with the PAN program
instrument = (*state.dataStrPtr).commonStr.instrument
energy = (*(*state.dataStrPtr).commonStr.histPtr).x
q = (*(*state.dataStrPtr).commonStr.histPtr).y
data = (*(*state.dataStrPtr).commonStr.histPtr).qty
error = (*(*state.dataStrPtr).commonStr.histPtr).err
mon = *(*(*state.dataStrPtr).specificPtr).monPtr
monErr = *(*(*state.dataStrPtr).specificPtr).monErrPtr
livetime = (*(*state.dataStrPtr).specificPtr).livetime


cRates = (*(*state.dataStrPtr).specificPtr).cRates

; Now reform the arrays    (added 11/29/01)
data = transpose(data)
error = transpose(error)
ndet = n_elements(q) + 1
nchan = n_elements(energy)
newData = fltarr(ndet,nchan)
newError = fltarr(ndet,nchan)
newData[0,0:nchan-1] = mon[0:nchan-1]
newError[0,0:nchan-1] = monErr[0:nchan-1]
newData[1:ndet-1,0:nchan-1] = data[0:ndet-2,0:nchan-1]
newError[1:ndet-1,0:nchan-1] = error[0:ndet-2,0:nchan-1]
data = newData
error = newError

datSize = size(data)

if datSize[0] eq 1 then begin
  void = dialog_message('Incorrect file type',/error)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
ndet = datSize[1] & nchan = datSize[2]
widget_control,(*pState).detSlider,set_slider_max = ndet - 1

addString = '1-'+strtrim(string(ndet-1),2)
widget_control,(*pState).selDetField,set_value = addString

treatment = *(*state.dataStrPtr).commonStr.treatmentPtr
xlabel = (*state.dataStrPtr).commonStr.xlabel
ylabel = (*state.dataStrPtr).commonStr.ylabel

xunits = (*state.dataStrPtr).commonStr.xunits
yunits = (*state.dataStrPtr).commonStr.yunits
xlabel = (*state.dataStrPtr).commonStr.xlabel
ylabel = (*state.dataStrPtr).commonStr.ylabel

xxunits = strtrim(strmid(xunits,strpos(xunits,':')+1))
yyunits = strtrim(strmid(yunits,strpos(yunits,':')+1))
xunits = hfbs_replaceSymbol(xxunits)
yunits = hfbs_replaceSymbol(yyunits)

xlabelDisp = xlabel+'('+xunits+')'
ylabelDisp = ylabel+'('+yunits+')'

(*pState).xlabel = xlabelDisp
;(*pState).ylabel = ylabelDisp
;(*pState).curTitle = ylabel
yvalues = q;(*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).y

(*pState).treatment[buffer] = 'counts'
;(*pState).BuffLabel[buffer] = xlabelDisp
;(*pState).xlabel = 'Energy'
(*pState).BuffLabel[buffer] = xlabelDisp
cd,(*pState).datapath

sumTBM = 0.0
(*pState).wholefile[buffer] = file
(*pState).filename[buffer] = file
widget_control,(*pState).buffer1,set_value = (*pState).filename[0]
widget_control,(*pState).buffer2,set_value = (*pState).filename[1]
widget_control,(*pState).buffer3,set_value = (*pState).filename[2]
widget_control,(*pState).buffer4,set_value = (*pState).filename[3]
widget_control,(*pState).buffer5,set_value = (*pState).filename[4]

; display the hourglass symbol to denote we're doing some work here
widget_control,/hourglass

(*pState).comments[buffer]='';comments
(*pState).mode[buffer]=''
(*pState).start_time[buffer]=''
(*pState).stop_time[buffer]=''
(*pState).cycles[buffer]=''
(*pState).cycle_time[buffer]=''
(*pState).live_time[buffer]=0.0
(*pState).TimeBin[buffer] = 0.0
(*pState).DopFreq[buffer] = 0.0
(*pState).sumWBM[buffer] = 0.0
(*pState).sumTBM[buffer] = 0.0
(*pState).tempPtr[buffer] = ptr_new(0.0)
;;;;;;


(*pState).sumFC[buffer] = total(data[0,*])
moncount = TOTAL(data[0,0:nchan-1])


wuggaData = fltarr(ndet,nchan)
wuggaData = data
energyPtr = ptr_new(energy)

dataPtr = ptr_new(data[0:ndet-1,0:nchan-1])
errorPtr = ptr_new(error[0:ndet-1,0:nchan-1])

MonPtr = ptr_new(data[0,0:nchan-1])
(*pState).info = 'Data successfully read'

(*pState).BuffEnergyPtr[buffer] = ptr_new(energy)
(*pState).BuffMonPtr[buffer] = MonPtr

(*pState).BuffPtr[buffer] = ptr_new(data[0:ndet-1,0:nchan-1])
(*pState).errorBuffPtr[buffer] = ptr_new(error[0:ndet-1,0:nchan-1])
(*pState).errorPtr = ptr_new(error[0:ndet-1,0:nchan-1])

nws = (*pState).nws
(*pState).buffchan[buffer] = nchan
(*pState).ndet[buffer] = ndet
(*pState).moncount[buffer] = moncount
(*pState).Crate[buffer] = 60.0*(total(data[0:ndet-1,0:nchan-1]))/float((*pState).live_time[buffer])
(*pState).TBMrate[buffer] = 1.0;60.0*sumTBM/float((*pState).live_time[buffer])
countRate = fltarr(ndet)
;for i = 0,ndet-1 do begin
;  countRate[i] = 60.0*(total(data[i,*]))/float((*pState).live_time[buffer])
;endfor
crates = (*(*state.dataStrPtr).specificPtr).cRates
(*pState).countRatePtr[buffer] = ptr_new(cRates)

widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;==========================================
PRO hfbs_dbWriteBuffer,event
widget_control,event.top,get_uvalue = pState
buffer = (*pState).curbuff
detangles = (*pState).detangles
sumTBM = (*pState).sumTBM[buffer]
sumFC = (*pState).sumFC[buffer]
sumWBM = (*pState).sumWBM[buffer]
comments = (*pState).comments[buffer]
file = (*pState).wholefile[buffer]
dataPtr = (*pState).BuffPtr[buffer]
energyPtr = (*pState).BuffEnergyPtr[buffer]
if ptr_valid((*pState).tempPtr[buffer]) then begin
  temperature = *(*pState).tempPtr[buffer]
endif
nchan = (*pState).buffchan[buffer]
data = *dataPtr
errorPtr = (*pState).errorBuffPtr[buffer]
error = *errorPtr
sumFC = total(data[0,0:nchan-1])

;print,'number of channels: ',nchan

energy = *energyPtr
; get header information to write into new file
OPENR, lun, file, /GET_LUN
nheader = 9
dumstr = ''
header=strarr(nheader)
for i=0,nheader-1 do begin
  readf,lun,dumstr
  header[i] = dumstr
endfor
FREE_LUN, lun

  newfile = DIALOG_PICKFILE(filter='*.con')
  newfile = newfile+'.con'
  OPENW, lun, newfile, /GET_LUN
  ; write header
  for i=0,nheader-1 do begin
    printf,lun,header[i]
  endfor

  ; write wbm
  ;printf,lun,'White beam monitor: ',sumWBM,format='(A30,E24.8)';+string(sumWBM)
  ; write tbm
  ;printf,lun,'Transmitted beam monitor: ',sumTBM,format = '(A30,E24.8)';+string(sumTBM)
  ; write fission chamber sum
  ;printf,lun,'Fission chamber sum: ',sumFC,format = '(A30,E24.8)';+string(sumFC)

;  The above lines were commented out and replaced with the lines below 5/26/2000
  printf,lun,'White beam monitor: '+string(sumWBM)
  ; write tbm
  printf,lun,'Transmitted beam monitor: '+string(sumTBM)
  ; write fission chamber sum
  printf,lun,'Fission chamber sum: '+string(sumFC)


 ; if temperature data present, write out to file
  if ptr_valid((*pState).tempPtr[buffer]) then begin
    ntemps = n_elements(temperature)
    printf,lun,'Temperature log: '
    for i = 0,ntemps-1 do begin
      printf,lun,temperature[i]
    endfor
  endif
  ; write data
  for i=0,16 do begin
    printf,lun,'#Detector '+string(i)+':  '+detangles[i]
    for j=0,nchan-1 do begin

;  The format statement was removed for Taub's group 5/26/2000
      printf,lun,energy[j],data[i,j],error[i,j],format='(3(E15.6,x))'
    endfor
  endfor
  ;
  FREE_LUN, lun

RETURN
END
;==========================================
PRO READ_HSCAN,event
; Read in time or temperature scan files
widget_control,event.top,get_uvalue = pState
widget_control,/hourglass
nws = (*pState).nws
nbuff = (*pState).nbuff
ws = (*pState).curws
buffer = (*pState).curbuff
(*pState).treatment[buffer] = 'counts'
cd,(*pState).dataPath
file = DIALOG_PICKFILE(filter='*.hscn')
Result = STRPOS(file, 'hscn')
IF Result EQ -1 THEN RETURN
(*pState).filename[buffer] = file
widget_control,(*pState).buffer1,set_value = (*pState).filename[0]
widget_control,(*pState).buffer2,set_value = (*pState).filename[1]
widget_control,(*pState).buffer3,set_value = (*pState).filename[2]
widget_control,(*pState).buffer4,set_value = (*pState).filename[3]
widget_control,(*pState).buffer5,set_value = (*pState).filename[4]

OPENR, lun, file, /GET_LUN
header=strarr(5)
comments = ''
dumstr = ''
dumstr1 = ''
dumstrmode = ''
ch = 0
intensity = 0.0

;Begin reading in information

READF, lun, dumstr     ; read comments

(*pState).comments[buffer]=strmid(dumstr,21)
READF, lun, dumstrmode  ; read mode

(*pState).mode[buffer]=strmid(dumstrmode,14)


READF, lun, dumstr     ; up to and including line 7

(*pState).start_time[buffer]=strmid(dumstr,21)
READF, lun, dumstr

(*pState).stop_time[buffer]=strmid(dumstr,21)
READF, lun, dumstr


(*pState).cycles[buffer]=1.0

(*pState).cycle_time[buffer]=1.0

(*pState).live_time[buffer]=1.0


ndet1 = 23

   nbig  = 50000
   x     = dblarr(ndet1,nbig)
   x1    = dblarr(ndet1)
   count = 0
   data = fltarr(ndet1)
   WHILE (NOT EOF(lun)) DO BEGIN
        READF, lun, data,format='(23F0)'
      x[0:ndet1-1,count]=data[0:ndet1-1]
      count = count + 1
   ENDWHILE
FREE_LUN, lun
nchan = count

ndet = 20

data = dblarr(ndet,nchan)
data[0:ndet-1,0:nchan-1]=x[1:ndet1-3,0:nchan-1]
error = dblarr(ndet,nchan)
error[0:ndet-1,0:nchan-1] = sqrt(data[0:ndet-1,0:nchan-1])

        energy = FLTARR(nchan)
        energy[0:nchan-1] = x[0,0:nchan-1]

        totdetcounts = INTARR(ndet)
        FOR i=0,ndet-1 DO BEGIN
          totdetcounts[i] = TOTAL(data[i,0:nchan-1])
        ENDFOR
        moncount = 0l
        moncount = TOTAL(data[0,0:nchan-1])

        detcntPtr = PTR_NEW(INTARR(ndet))
        *detcntPtr = totdetcounts

        energyPtr = ptr_new(FLTARR(nchan))
        *energyPtr = energy[0:nchan-1]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Must append enough zero detector columns to match
; the format for standard files.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        dataPtr = ptr_new(FLTARR(ndet1,nchan))
        newdatarr = fltarr(ndet1,nchan)
        ;newdatarr[0:ndet-1,0:nchan-1] = data[0:ndet-1,0:nchan-1]
        newdatarr[0:ndet1-2,0:nchan-1] = x[1:ndet1-1,0:nchan-1]
        ;newdatarr[ndet:ndet1-1,0:nchan-1] = x[ndet:ndet1-1,0:nchan-1]
        newdatarr[ndet1-1,0:nchan-1] = 0.0*findgen(nchan)
        *dataPtr = newdatarr[0:ndet1-1,0:nchan-1]

        errorPtr = ptr_new(FLTARR(ndet1,nchan))
        newerrarr = fltarr(ndet1,nchan)
        ;newerrarr[0:ndet-1,0:nchan-1] = error[0:ndet-1,0:nchan-1]
        ;newerrarr[ndet:ndet1-1,0:nchan-1] = x[ndet:ndet1-1,0:nchan-1]
        newerrarr[0:ndet1-2,0:nchan-1] = sqrt(newdatarr[0:ndet1-2,0:nchan-1])
        newerrarr[ndet1-1,0:nchan-1] = 0.0*findgen(nchan)
        *errorPtr = newerrarr[0:ndet1-1,0:nchan-1]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        MonPtr = ptr_new(/allocate_heap)
        *MonPtr = data[0,0:nchan-1]

        PvLowPtr = ptr_new(/allocate_heap)
        *PvLowPtr = x[21,0:nchan-1]

        PvHighPtr = ptr_new(/allocate_heap)
        *PvHighPtr = x[22,0:nchan-1]

        PvMonPtr = ptr_new(/allocate_heap)
        *PvMonPtr = x[20,0:nchan-1]


        (*pState).PvLowPtr = PvLowPtr
        (*pState).PvHighPtr = PvHighPtr
        (*pState).PvMonPtr[buffer] = PvMonPtr
        (*pState).BuffPvPtr[buffer] = PvHighPtr
        ;(*pState).xlabel = 'Energy'
        void = dialog_message('Data file successfully read!',/information)

(*pState).BuffEnergyPtr[buffer] = energyPtr
(*pState).BuffMonPtr[buffer] = MonPtr

(*pState).BuffPtr[buffer] = dataPtr
(*pState).errorBuffPtr[buffer] = errorPtr
(*pState).errorPtr = errorPtr

nws = (*pState).nws
(*pState).buffchan[buffer] = nchan
(*pState).ndet[buffer] = ndet1
(*pState).detcountPtr[buffer] = detcntPtr
(*pState).moncount[buffer] = moncount
(*pState).xlabel = (*pState).mode[buffer]
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO hfbs_dbPlotWs,event
; Plot workspace
widget_control,event.top,get_uvalue = pState
(*pState).plotType = 0
;widget_control,(*pState).PlotWsList,get_value = choice
  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
;widget_control,(*pState).xrangelo,get_value = xlo
;widget_control,(*pState).xrangehi,get_value = xhi
ylo = (*pState).yrangelo
yhi = (*pState).yrangehi
;widget_control,(*pState).yrangelo,get_value = ylo
;widget_control,(*pState).yrangehi,get_value = yhi
xlo = float(xlo[0]) & xhi = float(xhi[0])
ylo = float(ylo[0]) & yhi = float(yhi[0])
(*pState).threeDplot = 0
(*pState).imagePlot = 0
buffer = (*pState).curbuff
theseColors = (*pState).theseColors
colors = (*pState).colors
;;;;;;;;;;;;;;;;
; Generate legend text
;index = where(choice eq 1,nchoices)
widget_control,(*pState).selPlotField,get_value = strdets
indexPtr = hfbs_ChooseDets(strdets)
index = *indexPtr

;case (*pState).nlabels[index[0]-1] of
;  'Energy':    xlabel = '!6E (!4l!6eV)'
;  'PST Channel':    xlabel = 'PST Channel'
;  'time channel':   xlabel = 'time channel'
;  'temp':      xlabel = 'T (K)'
;  'time':      xlabel = 'time (s)'
;  'Channel':   xlabel = 'Channel'
;else:   xlabel = '!6E (!4l!6eV)'
;endcase
xlabel = (*pState).xlabel

nchoices = n_elements(index)

text = ''

if nchoices eq 0 then begin
  void = dialog_message('No workspaces selected',$
         dialog_parent=event.top)
  return
end

wset,(*pState).winPix

legendTxt = strarr(nchoices)

FOR i=0,nchoices-1 DO BEGIN
    ws = index[i]-1
    text = 'ws number'+string(1+ws)
    legendTxt[i] = hfbs_symname((*pState).symselect[ws])+':  '+strcompress(text)
ENDFOR
dypos = 0.05
xpos = 0.15
ypos = FLTARR(nchoices)
ypos = 0.9-dypos*FINDGEN(nchoices)
;;;;;;;;;;;;;;;;
emin = fltarr(nchoices)
emax = fltarr(nchoices)
ymin = fltarr(nchoices)
ymax = fltarr(nchoices)
;;;;;;;;;;;;;;;;
;index = where(choice eq 1,nchoices)
IF index[0] NE -1 THEN BEGIN
  FOR i=0,nchoices-1 DO BEGIN
    ws = index[i]-1
    nws = (*pState).nws
    nchan = (*pState).nchan[ws]
    errcolors = {thiscolor:theseColors[i]}
    symcolor = theseColors[i]

  IF n_elements(*(*pState).wsPtr[ws]) gt 0 THEN BEGIN
    dataPtr = ptr_new(/allocate_heap)
    dataPtr = (*pState).wsPtr[ws]
    energyPtr = ptr_new(/allocate_heap)
    energyPtr = (*pState).energyPtr[ws]
    errorPtr = ptr_new(/allocate_heap)
    errorPtr = (*pState).wsErrPtr[ws]
    data = FLTARR(nchan)
    data = *dataPtr
    error = FLTARR(nchan)
    error = *errorPtr
    energy = FLTARR(nchan)
    energy = *energyPtr
    emin[i] = min(energy) & emax[i] = max(energy)
    ymin[i] = min(data) & ymax[i] = max(data)
    IF i EQ 0 THEN BEGIN
      IF (*pState).scale EQ 1 THEN BEGIN
      symbolid = (*pState).symselect[ws]
      ;symcolor = theseColors[i]

           IF symbolid LT 5 THEN BEGIN
               plot,energy,data,psym=hfbs_selsym(symbolid),xrange=[xlo,xhi],yrange=[ylo,yhi],$
                 xstyle=1,ystyle=1,xtitle=xlabel,title = (*pState).wstreatment[ws],$
                 color = colors.white
               hfbs_cerrplot,energy,data-error,data+error,errcolors = errcolors
               FOR k = 0,nchoices - 1 DO BEGIN
                 xyouts,xpos,ypos[k],legendTxt[k],/normal,color = theseColors[k]
               ENDFOR
           ENDIF ELSE BEGIN
             plot,energy,data,psym=0,linestyle = symbolid-5,xrange=[xlo,xhi],yrange=[ylo,yhi],$
               xstyle=1,ystyle=1,xtitle=xlabel,title = (*pState).wstreatment[ws]
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = theseColors[k]
             ENDFOR
           ENDELSE


      ENDIF ELSE BEGIN

           symbolid = (*pState).symselect[ws]
           IF symbolid LT 5 THEN BEGIN
             plot,energy,data,psym=hfbs_selsym(symbolid),$
               xtitle=xlabel,title = (*pState).wstreatment[ws],color = (*pState).colors.white
               errcolors = {thiscolor:(*pState).colors.white}
             hfbs_cerrplot,energy,data-error,data+error,width = 0.0,errcolors = errcolors
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = theseColors[k]
             ENDFOR
           ENDIF ELSE BEGIN
             plot,energy,data,psym=0,linestyle = symbolid-5,$
               xtitle=xlabel,title = (*pState).wstreatment[ws]
             FOR k = 0,nchoices - 1 DO BEGIN
               xyouts,xpos,ypos[k],legendTxt[k],/normal,color = theseColors[k]
             ENDFOR
           ENDELSE
           (*pState).xrangelo = min(energy)
           (*pState).xrangehi = max(energy)
        (*pState).yrangelo = min(data)
        (*pState).yrangehi = max(data)+max(error)
      ENDELSE

    ENDIF ELSE BEGIN
        symbolid = (*pState).symselect[ws]
        IF symbolid LT 5 THEN BEGIN    ; Plot symbols and user defined limits
           oplot,energy,data,psym=hfbs_selsym((*pState).symselect[ws]),color = symcolor
           hfbs_cerrplot,energy,data-error,data+error,errcolors = errcolors
        ENDIF ELSE BEGIN   ; plot lines and user defined limits
          oplot,energy,data,psym=0,linestyle=symbolid - 5,color = thisColor
        ENDELSE
    ENDELSE
  ENDIF ELSE BEGIN
    void = dialog_message('No data in workspace',$
         dialog_parent=event.top)
  ENDELSE
  ENDFOR
wset,(*pState).winVis
device,copy = [0,0,(*pState).winxsize,(*pState).winysize,0,0,(*pState).winPix]


ENDIF ELSE BEGIN
    void = dialog_message('No workspaces selected',$
         dialog_parent=event.top)
ENDELSE

;print,(*pState).legendTxt
(*pState).curplot = 0
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO DoneTable,event
widget_control,event.top,/destroy
RETURN
END
;==========================================
PRO TableInfo,event
; Widget table which displays the count rates and other information.
widget_control,event.top,get_uvalue = pState
geom = widget_info(event.top,/geometry)
xoff = geom.xoffset
yoff = geom.yoffset
xsize = geom.xsize
ysize = geom.ysize

sumWBM = lonarr(5)
sumTBM = lonarr(5)
DopFreq = fltarr(5)
Crate = fltarr(5)
TBMrate = fltarr(5)

buffer = (*pState).curbuff
for i=0,4 do begin
  sumWBM[i] = (*pState).sumWBM[i]
  sumTBM[i] = (*pState).sumTBM[i]
  DopFreq[i] = (*pState).DopFreq[i]
  Crate[i] = (*pState).Crate[i]
  TBMrate[i] = (*pState).TBMrate[i]
endfor

tbl_base = widget_base(group_leader=event.top,/column)
labels = [['WBM'],['TBM'],['Doppler Frequency'],['FC (cpm)'],['TBM (cpm)']]

printvalues = [[string(sumWBM[0]),string(sumTBM[0]),string(DopFreq[0]),string(Crate[0]),string(TBMrate[0])],$
                [string(sumWBM[1]),string(sumTBM[1]),string(DopFreq[1]),string(Crate[1]),string(TBMrate[1])],$
                [string(sumWBM[2]),string(sumTBM[2]),string(DopFreq[2]),string(Crate[2]),string(TBMrate[2])],$
                [string(sumWBM[3]),string(sumTBM[3]),string(DopFreq[3]),string(Crate[3]),string(TBMrate[3])],$
                [string(sumWBM[4]),string(sumTBM[4]),string(DopFreq[4]),string(Crate[4]),string(TBMrate[4])]]

void = widget_table(tbl_base,column_labels=labels,value=printvalues,$
       xsize=5,/resizeable_columns)
void = widget_button(tbl_base,value='Done',event_pro='DoneTable')
widget_control,tbl_base,/realize
xmanager,'TableInfo',tbl_base,/no_block
RETURN
END
;==========================================
PRO DispCountRates,event
; Widget table which displays the count rates and other information.
widget_control,event.top,get_uvalue = pState

buffer = (*pState).curbuff
if not ptr_valid((*pState).countRatePtr[buffer]) then return
countRate = (*(*pState).countRatePtr[buffer])*60.0

ratetext = strarr(16)
for i = 0,15 do begin
  ratetext[i] = 'Det'+string(i+1)+': '+string(countRate[i])+' cpm'
endfor
widget_control,(*pState).textWid,set_value = rateText
widget_control,event.top,set_uvalue = pState
RETURN
END
;==========================================
PRO VAN_NORM,event
widget_control,event.top,get_uvalue = pState
buffer = (*pState).curbuff
IF NOT PTR_VALID((*pState).BuffPtr[buffer]) THEN BEGIN
  void = dialog_message('No data in buffer',dialog_parent=event.top)
  RETURN
END

cd,(*pState).dataPath
file = DIALOG_PICKFILE(filter='*.van')

ndet = (*pState).ndet[buffer]
IF ndet EQ 0 THEN RETURN
normfact = fltarr(ndet)
OPENR, lun, file, /GET_LUN
FOR i=0,ndet-1 DO BEGIN
  readf,lun,x
  normfact[i] = x
ENDFOR
FREE_LUN, lun

buffer = (*pState).curbuff
nchan = (*pState).buffchan[buffer]
errorPtr = ptr_new(/allocate_heap)
dataPtr = ptr_new(/allocate_heap)
dataPtr = (*pState).BuffPtr[buffer]
errorPtr = (*pState).errorBuffPtr[buffer]
olddata = *dataPtr
olderror = *errorPtr
newdata = dblarr(ndet,nchan)
newerror = dblarr(ndet,nchan)

for i=0,ndet-1 do begin
  olddata[i,0:nchan-1] = normfact[i]*temporary(olddata[i,0:nchan-1])
  olderror[i,0:nchan-1] = normfact[i]*temporary(olderror[i,0:nchan-1])
endfor

*dataPtr = olddata
*errorPtr = olderror
(*pState).errorPtr = errorPtr
(*pState).dataPtr = dataPtr
(*pState).BuffPtr[buffer]=dataPtr
(*pState).errorBuffPtr[buffer]=errorPtr
  old = (*pState).treatment[buffer]
  new = old+' normalized to vanadium'
  (*pState).treatment[buffer] = new
widget_control,event.top,set_uvalue = pState

RETURN
END
;==========================================
PRO Norm2Pv,event
; Normalize data to P(v)
widget_control,event.top,get_uvalue = pState

nws = (*pState).nws
nbuff = (*pState).nbuff
ws = (*pState).curws

buffer = (*pState).curbuff
nchan = (*pState).buffchan[buffer]
ndet = (*pState).ndet[buffer]

IF nchan EQ 0 THEN BEGIN
  void = dialog_message('No data in buffer',$
       dialog_parent=event.top)
  RETURN
ENDIF

CASE (*pState).mode[buffer] OF

'velocity': BEGIN
IF PTR_VALID((*pState).BuffPtr[buffer]) THEN BEGIN
  nchan = (*pState).buffchan[buffer]
  ndet = (*pState).ndet[buffer]
  dataPtr = ptr_new(/allocate_heap)
  dataPtr = (*pState).BuffPtr[buffer]
  errorPtr = ptr_new(/allocate_heap)
  errorPtr = (*pState).errorBuffPtr[buffer]
  PvPtr = ptr_new(/allocate_heap)
  PvPtr = (*pState).BuffPvPtr[buffer]
  MonPvPtr = ptr_new(/allocate_heap)
  MonPvPtr = (*pState).PvMonPtr[buffer]
  MonPv = FLTARR(nchan)
  MonPv = *MonPvPtr
  data = FLTARR(ndet,nchan)
  error = FLTARR(ndet,nchan)
  newdata = FLTARR(ndet,nchan)
  newerror = FLTARR(ndet,nchan)
  Pv = FLTARR(nchan)
  Pv = *PvPtr
  data = *dataPtr
  error = *errorPtr
  newdata = data
  newdata[0,0:nchan-1] = data[0,0:nchan-1]/MonPv[0:nchan-1]
  newerror[0,0:nchan-1] = error[0,0:nchan-1]*newdata[0,0:nchan-1]/MonPv[0:nchan-1]
  FOR i=1,16 DO BEGIN
    u = fltarr(nchan) & v = fltarr(nchan)
    u[0:nchan-1] = data[i,0:nchan-1]
    v[0:nchan-1] = Pv[0:nchan-1]
    newdata[i,0:nchan-1] = data[i,0:nchan-1]/Pv[0:nchan-1]
    newerror[i,0:nchan-1] = (1.0/v[0:nchan-1]^2)*sqrt(u[0:nchan-1]*v[0:nchan-1]^2+$
                            v[0:nchan-1]*u[0:nchan-1]^2)
  ENDFOR
  index = where(FINITE(newdata) NE 1)
  if index[0] ne -1 then begin
    newdata[index] = 0.0
    newerror[index] = 0.0
  endif else begin
    newdata[index] = 0.0
    newerror[index] = 0.0
  endelse

  MonPtr = ptr_new(/allocate_heap)
  MonPtr = (*pState).BuffMonPtr[buffer]
  *MonPtr = newdata[0,0:nchan-1]
  (*pState).BuffMonPtr[buffer] = MonPtr
  *dataPtr = newdata
  *errorPtr = newerror
  (*pState).errorPtr = errorPtr
  (*pState).dataPtr = dataPtr
  (*pState).BuffPtr[buffer]=dataPtr
  (*pState).errorBuffPtr[buffer]=errorPtr
  void = dialog_message('Normalization to P(v) complete',$
       dialog_parent=event.top,/information)

  old = (*pState).treatment[buffer]
  new = old+'/P(v)'
  (*pState).treatment[buffer] = new
  widget_control,event.top,set_uvalue = pState
ENDIF ELSE BEGIN
  void = dialog_message('No data in buffer',$
       dialog_parent=event.top)
ENDELSE
END

'standard': BEGIN
IF PTR_VALID((*pState).BuffPtr[buffer]) THEN BEGIN
  nchan = (*pState).buffchan[buffer]
  ndet = (*pState).ndet[buffer]
  dataPtr = ptr_new(/allocate_heap)
  dataPtr = (*pState).BuffPtr[buffer]
  errorPtr = ptr_new(/allocate_heap)
  errorPtr = (*pState).errorBuffPtr[buffer]
  PvPtr = ptr_new(/allocate_heap)
  PvPtr = (*pState).BuffPvPtr[buffer]
  MonPvPtr = ptr_new(/allocate_heap)
  MonPvPtr = (*pState).PvMonPtr[buffer]
  MonPv = FLTARR(nchan)
  MonPv = *MonPvPtr
  data = FLTARR(ndet,nchan)
  error = FLTARR(ndet,nchan)
  newdata = FLTARR(ndet,nchan)
  newerror = FLTARR(ndet,nchan)
  Pv = FLTARR(nchan)
  Pv = *PvPtr
  data = *dataPtr
  error = *errorPtr
  newdata = data
  newdata[0,0:nchan-1] = data[0,0:nchan-1]/MonPv[0:nchan-1]
  newerror[0,0:nchan-1] = error[0,0:nchan-1]*newdata[0,0:nchan-1]/MonPv[0:nchan-1]
  FOR i=1,16 DO BEGIN
    u = fltarr(nchan) & v = fltarr(nchan)
    u[0:nchan-1] = data[i,0:nchan-1]
    v[0:nchan-1] = Pv[0:nchan-1]
    newdata[i,0:nchan-1] = data[i,0:nchan-1]/Pv[0:nchan-1]
    newerror[i,0:nchan-1] = (1.0/v[0:nchan-1]^2)*sqrt(u[0:nchan-1]*v[0:nchan-1]^2+$
                            v[0:nchan-1]*u[0:nchan-1]^2)
  ENDFOR
  index = where(FINITE(newdata) NE 1)
  if index[0] ne -1 then begin
    newdata[index] = 0.0
    newerror[index] = 0.0
  endif else begin
    newdata[index] = 0.0
    newerror[index] = 0.0
  endelse

  MonPtr = ptr_new(/allocate_heap)
  MonPtr = (*pState).BuffMonPtr[buffer]
  *MonPtr = newdata[0,0:nchan-1]
  (*pState).BuffMonPtr[buffer] = MonPtr
  *dataPtr = newdata
  *errorPtr = newerror
  (*pState).errorPtr = errorPtr
  (*pState).dataPtr = dataPtr
  (*pState).BuffPtr[buffer]=dataPtr
  (*pState).errorBuffPtr[buffer]=errorPtr
  void = dialog_message('Normalization to P(v) complete',$
       dialog_parent=event.top,/information)

  old = (*pState).treatment[buffer]
  new = old+'/P(v)'
  (*pState).treatment[buffer] = new
  widget_control,event.top,set_uvalue = pState
ENDIF ELSE BEGIN
  void = dialog_message('No data in buffer',$
       dialog_parent=event.top)
ENDELSE
END

ELSE: BEGIN
void = dialog_message('Modes other than standard not supported',$
       dialog_parent=event.top)
      END
ENDCASE

RETURN
END
;==========================================
PRO dbRebinWs,event
; Rebins current data set using John Copley's rebinning routine
; called DAVE_REBIN.PRO.
;
widget_control,event.top,get_uvalue = pState
ws = (*pState).curws
IF NOT PTR_VALID((*pState).energyPtr[ws]) THEN BEGIN
  void = dialog_message('No data in workspace',$
         dialog_parent=event.top)
  RETURN
ENDIF

IF n_elements(*(*pState).energyPtr[ws]) eq 0 THEN BEGIN
  void = dialog_message('No data in workspace',$
         dialog_parent=event.top)
  RETURN
ENDIF

widget_control,(*pState).chanwidth,get_value = chanw
chanw = fix(chanw[0])
IF chanw LE 1 THEN BEGIN
  void = dialog_message('Bin size must be greater than 1 channel',$
         dialog_parent=event.top)
  RETURN
ENDIF
  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
;widget_control,(*pState).xrangelo,get_value = xlo
;widget_control,(*pState).xrangehi,get_value = xhi
xlo = float(xlo[0]) & xhi = float(xhi[0])
nchan=(*pState).nchan[ws]

x=FLTARR((*pState).nchan[ws])
y=FLTARR((*pState).nchan[ws])
yerr=FLTARR((*pState).nchan[ws])

energyPtr = ptr_new(/allocate_heap)
wsPtr = ptr_new(/allocate_heap)
wsErrPtr = ptr_new(/allocate_heap)

energyRebPtr = ptr_new(/allocate_heap)
wsRebPtr = ptr_new(/allocate_heap)
wsErrRebPtr = ptr_new(/allocate_heap)

energyPtr = (*pState).energyPtr[ws]
wsPtr = (*pState).wsPtr[ws]
wsErrPtr = (*pState).wsErrPtr[ws]

x=*energyPtr
y=*wsPtr
yerr=*wsErrPtr

nchan = (*pState).nchan[ws]
nx = n_elements(x) ; *
xlo = min(x) & xhi = max(x)   ; *
dx = (xhi-xlo)/(nx)
nchan = fix(1.0*nchan/(1.0*chanw)) ; *
nxnew = nchan
xnew = hfbs_makepoints(xlo = xlo,xhi = xhi,npts = nchan)
dxnew = xnew[1]-xnew[0]

drebin_histo,[x[0:nx-1]-0.5*dx,x[nx-1]+0.5*dx],y,yerr,$
           [xnew[0:nxnew-1]-0.5*dxnew,xnew[nxnew-1]+0.5*dxnew],$
           ynew,errnew

;dave_rebin,[x[0:nx-1]-0.5*dx,x[nx-1]+0.5*dx],y,yerr,$
;           [xnew[0:nxnew-1]-0.5*dxnew,xnew[nxnew-1]+0.5*dxnew],$
;           ynew,errnew,/silent
whereFinite = where(finite(y) eq 1,countFinite)
y = y[whereFinite]
yerr = yerr[whereFinite]
xnew = xnew[whereFinite]

*energyRebPtr = xnew
*wsRebPtr = ynew
*wsErrRebPtr = errnew

*(*pState).energyPtr[(*pState).TargetWs] = xnew
*(*pState).wsPtr[(*pState).TargetWs] = ynew
*(*pState).wsErrPtr[(*pState).TargetWs] = errnew
(*pState).nchan[(*pState).TargetWs] = n_elements(xnew)
(*pState).nlabels[(*pState).TargetWs] = (*pState).nlabels[ws]
(*pState).info = 'Averaging complete'
;void = dialog_message('Averaging Complete',$
;         dialog_parent=event.top,/information)
widget_control,event.top,set_uvalue = pState

RETURN
END
;==========================================
PRO plotDetsDB,event
widget_control,event.top,get_uvalue = pState,/no_copy

widget_control,(*pState).detSlider,get_value = detector
detector = fix(detector[0])
(*pState).plotType = 1
nbuff = 5
filledBuffers = intarr(nbuff)
for i = 0,nbuff-1 do begin
  filledBuffers[i] = ptr_valid((*pState).BuffPtr[i])
endfor
whereok = where(filledBuffers eq 1,numBuffers)
;  numBuffers = number of buffers currently loaded
if numBuffers eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

legendTxt = strarr(numBuffers)
FOR i=0,numBuffers-1 DO BEGIN
    text = 'Buffer: '+string(whereok[i]+1)
    legendTxt[i] = hfbs_symname((*pState).symselect[whereok[i]])+':  '+strcompress(text)
ENDFOR
dypos = 0.05
xpos = 0.15
ypos = FLTARR(numBuffers)
ypos = 0.9-dypos*FINDGEN(numBuffers)

if (*pState).scale eq 0 then begin  ; autoscale
;
endif else begin  ; user scaled limits
  xlo = (*pState).xrangelo
  xhi = (*pState).xrangehi
  ylo = (*pState).yrangelo
  yhi = (*pState).yrangehi
endelse

case (*pState).xlabel of
'Energy': xlabel = '!6E (!4l!6eV)'
'temp':   xlabel = 'T (K)'
else:     xlabel = ''
endcase
xlabel = (*pState).xlabel

theseColors = (*pState).theseColors
colors = (*pState).colors

wset, (*pState).winPix
errcolors = {thiscolor:theseColors[0]}
symcolor = theseColors[0]
if (*pState).scale eq 0 then begin
  plot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*],xtitle = xlabel,$
       psym = hfbs_selsym((*pState).symselect[whereok[0]]),/nodata,color = (*pState).colors.white
endif else begin
  plot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*],xtitle = xlabel,$
       psym = hfbs_selsym((*pState).symselect[whereok[0]]),/nodata,color = (*pState).colors.white,$
       xrange = [xlo,xhi],yrange = [ylo,yhi],xstyle = 1,ystyle = 1
endelse
oplot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*],$
     psym = hfbs_selsym((*pState).symselect[whereok[0]]),color = symcolor

if (*pState).errbars then begin
  hfbs_cerrplot,(*(*pState).BuffEnergyPtr[whereok[0]]),(*(*pState).BuffPtr[whereok[0]])[detector,*]-$
           (*(*pState).errorBuffPtr[whereok[0]])[detector,*],(*(*pState).BuffPtr[whereok[0]])[detector,*]+$
           (*(*pState).errorBuffPtr[whereok[0]])[detector,*],width = 0.0,errcolors = errcolors
endif

if numBuffers gt 1 then begin
  for i = 1,numBuffers-1 do begin
    errcolors = {thiscolor:theseColors[i]}
    symcolor = theseColors[i]
    oplot,(*(*pState).BuffEnergyPtr[whereok[i]]),(*(*pState).BuffPtr[whereok[i]])[detector,*],$
          psym = hfbs_selsym((*pState).symselect[whereok[i]]),color = symcolor
    if (*pState).errbars then begin
      hfbs_cerrplot,(*(*pState).BuffEnergyPtr[whereok[i]]),(*(*pState).BuffPtr[whereok[i]])[detector,*]-$
            (*(*pState).errorBuffPtr[whereok[i]])[detector,*],(*(*pState).BuffPtr[whereok[i]])[detector,*]+$
            (*(*pState).errorBuffPtr[whereok[i]])[detector,*],width = 0.0,errcolors = errcolors
    endif
  endfor
endif
FOR k = 0,numBuffers - 1 DO BEGIN
    xyouts,xpos,ypos[k],legendTxt[k],/normal,color = theseColors[k]
ENDFOR

wset,(*pState).winVis
device,copy = [0,0,(*pState).winxsize,(*pState).winysize,0,0,(*pState).winPix]
widget_control,event.top,set_uvalue = pState,/no_copy
RETURN
END
;==========================================
pro OmitErrorBars,event
widget_control,event.top,get_uvalue = pState,/no_copy
(*pState).errBars = 0
if (*pState).plotType eq 0 then begin
  wset,(*pState).winPix
  hfbs_dbPlotZoom,pState,(*pState).xrangelo,(*pState).xrangehi,$
           (*pState).yrangelo,(*pState).yrangehi
  wset,(*pState).winVis
  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
endif else begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  plotDetsDB,event
  widget_control,event.top,get_uvalue = pState,/no_copy
endelse
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;==========================================
pro IncludeErrorBars,event
widget_control,event.top,get_uvalue = pState,/no_copy
(*pState).errBars = 1
if (*pState).plotType eq 0 then begin
  wset,(*pState).winPix
  hfbs_dbPlotZoom,pState,(*pState).xrangelo,(*pState).xrangehi,$
           (*pState).yrangelo,(*pState).yrangehi
  wset,(*pState).winVis
  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
endif else begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  plotDetsDB,event
  widget_control,event.top,get_uvalue = pState,/no_copy
endelse
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;==========================================
PRO PlotData,event
;
widget_control,event.top,get_uvalue = pState
widget_control,(*pState).plotId,get_value = winId
xmin = (*pState).xrangelo
xmax = (*pState).xrangehi
;widget_control,(*pState).xrangelo,get_value = xmin
;xmin = float(xmin[0])
;widget_control,(*pState).xrangehi,get_value = xmax
;xmax = float(xmax[0])
ymin = (*pState).yrangelo
ymax = (*pState).yrangehi
;widget_control,(*pState).yrangelo,get_value = ymin
;ymin = float(ymin[0])
;widget_control,(*pState).yrangehi,get_value = ymax
;ymax = float(ymax[0])
device,copy = [xmin,ymin,xmax,ymax,0,0,(*pState).winPix]

if event.press eq 1 then begin   ; test for left mouse press
  ;print,'clicked in the window'
  (*pState).xstart = event.x
  (*pState).ystart = event.y
  widget_control,event.id,draw_motion_events = 1
endif else if event.type eq 2 then begin  ; test for motion event
  wset,winId

  device,copy = [xmin,ymin,xmax,ymax,0,0,(*pState).winPix]
  plots,[(*pState).xstart,event.x,event.x,(*pState).xstart,(*pState).xstart],$
        [(*pState).ystart,(*pState).ystart,event.y,event.y,(*pState).ystart],$
        /device
endif else if event.release eq 1 then begin  ; test for button release
  ;print,'button released'
  widget_control,event.id,draw_motion_events = 0
endif else if event.press eq 4 then begin ; Test for right mouse press
  ;print,'stupid'
  ;print,event.x,event.y
endif
widget_control,event.top,set_uvalue = pState
RETURN
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_dbWinDraw,event
widget_control,event.top,get_uvalue = pState,/no_copy

widget_control,(*pState).selPlotField,get_value = strdets
indexPtr = hfbs_ChooseDets(strdets)
index = *indexPtr
nchoices = n_elements(index)

if nchoices eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

case event.type of
0: begin  ; button press
   (*pState).mouse = event.press
   widget_control,(*pState).plotID,draw_motion_events = 1
   if (*pState).mouse eq 1 then (*pState).scale = 1
   if (*pState).mouse eq 4 then begin
      (*pState).scale = 0
        (*pState).mouse = 0
       if (*pState).plotType eq 0 then begin   ; plot the workspace
            wset,(*pState).winPix
        hfbs_dbPlotZoom,pState,(*pState).xrangelo,(*pState).xrangehi,$
         (*pState).yrangelo,(*pState).yrangehi
           wset,(*pState).winVis
           device, copy = [0,0,(*pState).winxsize,(*pState).winysize,0,0,(*pState).winPix]
       endif else begin
            widget_control,event.top,set_uvalue = pState,/no_copy
            plotDetsDB,event
            widget_control,event.top,get_uvalue = pState,/no_copy
        endelse
        widget_control,event.top,set_uvalue = pState,/no_copy
     return
   endif
   (*pState).xp1 = event.x
   (*pState).yp1 = event.y
   wset, (*pState).winVis
   device, copy = [0,0,(*pState).winxsize,(*pState).winysize,0,0,(*pState).winPix]
   end
1: begin ; button release
   if ((*pState).mouse eq 1) then begin
     x = (*pState).xp1 < (*pState).xp2
     y = (*pState).yp1 < (*pState).yp2
     w = abs((*pState).xp1 - (*pState).xp2)
     h = abs((*pState).yp1 - (*pState).yp2)
     x2 = x+w
     y2 = y+h
     lc = convert_coord(x, y, /device, /to_data)
     uc = convert_coord(x2, y2, /device, /to_data)
     wset,(*pState).winVis
     xlo = lc[0] & xhi = uc[0]
     ylo = lc[1] & yhi = uc[1]
     (*pState).xrangelo = xlo
        (*pState).xrangehi = xhi
     (*pState).yrangelo = ylo
        (*pState).yrangehi = yhi
     (*pState).scale = 1

          if (*pState).plotType eq 0 then begin
            wset,(*pState).winPix
        hfbs_dbPlotZoom,pState,(*pState).xrangelo,(*pState).xrangehi,$
         (*pState).yrangelo,(*pState).yrangehi
           wset,(*pState).winVis
           device, copy = [0,0,(*pState).winxsize,(*pState).winysize,0,0,(*pState).winPix]
          endif else begin
              widget_control,event.top,set_uvalue = pState,/no_copy
              plotDetsDB,event
              widget_control,event.top,get_uvalue = pState,/no_copy
          endelse
   endif
   (*pState).mouse = 0
   widget_control,(*pState).plotID,draw_motion_events = 0
   end
2: begin ; mouse motion
    if ((*pState).mouse eq 1) then begin
      (*pState).xp2 = event.x
      (*pState).yp2 = event.y
      xc = [(*pState).xp1, event.x, event.x, (*pState).xp1, (*pState).xp1]
      yc = [(*pState).yp1, (*pState).yp1, event.y, event.y, (*pState).yp1]
      wset, (*pState).winVis
      device, copy = [0,0,(*pState).winxsize,(*pState).winysize,0,0,(*pState).winPix]
      plots, xc, yc, /device,color = (*pState).colors.yellow
    endif
   end
else:
endcase

widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;==========================================
pro hfbs_dbClearCurrentBuffer,event
widget_control,event.top,get_uvalue = pState,/no_copy
nbuff = (*pState).curbuff
(*pState).BuffPtr[nbuff] = ptr_new()
(*pState).errorBuffPtr[nbuff] = ptr_new()
(*pState).BuffEnergyPtr[nbuff] = ptr_new()
(*pState).filename[nbuff] = 'Empty'

widget_control,(*pState).buffer1,set_value = (*pState).filename[0]
widget_control,(*pState).buffer2,set_value = (*pState).filename[1]
widget_control,(*pState).buffer3,set_value = (*pState).filename[2]
widget_control,(*pState).buffer4,set_value = (*pState).filename[3]
widget_control,(*pState).buffer5,set_value = (*pState).filename[4]


widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hfbs_db_event,event
if dave_set_focus(event) then return
; This event handler added 01/10/02 in order to handle events in
; the workspace operations text field
widget_control,event.top,get_uvalue = pState,/no_copy
if event.id eq (*pState).txtField then begin
  widget_control,(*pState).txtField,get_value = inString
  inString = strcompress(inString[0])
  eqPos = strpos(inString,'=')
  indexString = strmid(inString,1,eqPos-1)
  destVar = strmid(inString,0,eqPos)
  execString = strmid(inString,eqPos+1)

  nws = n_elements((*pState).wsPtr)
  dataIndex = intarr(nws)
  for i = 0,nws-1 do begin
    if n_elements(*(*pState).wsPtr[i]) gt 0 then dataIndex[i] = 1
  endfor
  valid = where(dataIndex eq 1,totValid)

  if totValid eq 0 then begin
    void = dialog_message('No workspaces have data',/error)
    widget_control,event.top,set_uvalue = pState,/no_copy
    return
  endif
  qtys = (*pState).qtys
  errs = (*pState).errs

  result = dave_evaluate(execString,qtys,errs)
  if strupcase(size(result,/tname)) eq "STRING" then begin
    void = dialog_message('Could not evaluate expression',/error)
    widget_control,event.top,set_uvalue = pState,/no_copy
    return
  endif
  x = (*(*pState).xs).(0)
  yout = (*result).qty
  yerrout = (*result).err

  *(*pState).energyPtr[indexString-1] = x
  *(*pState).wsPtr[indexString-1] = yout
  *(*pState).wsErrPtr[indexString-1] = yerrout
  (*pState).nchan[indexString-1] = n_elements(x)

  nws = n_elements((*pState).wsPtr)
  dataIndex = intarr(nws)
  for i = 0,nws-1 do begin
    if n_elements(*(*pState).wsPtr[i]) gt 0 then dataIndex[i] = 1
  endfor
  valid = where(dataIndex eq 1,totValid)

  wsString = strarr(totValid)
  wseString = strarr(totValid)
  wsxString = strarr(totValid)
  for i = 0,totValid-1 do begin
    x = *(*pState).energyPtr[valid[i]]
    y = *(*pState).wsPtr[valid[i]]
    yerr = *(*pState).wsErrPtr[valid[i]]
    wsxString[i] = 'wx'+strtrim(string(valid[i]+1),2)
    wsString[i] = 'w'+strtrim(string(valid[i]+1),2)
    wseString[i] = 'we'+strtrim(string(valid[i]+1),2)
    wstrExpr = 'w'+strtrim(string(valid[i]+1),2)+'=y'
    westrExpr = 'we'+strtrim(string(valid[i]+1),2)+'=yerr'
    wxstrExpr = 'wx'+strtrim(string(valid[i]+1),2)+'=x'
    r = execute(wstrExpr,1)
    r = execute(westrExpr,1)
    r = execute(wxstrExpr,1)
  endfor
  stateString = '{'
  errString = '{'
  xString = '{'
  for i = 0,totValid-1 do begin
      if i gt 0 then begin
       xString = xString+','+wsxString[i]+':'+wsxString[i]
       stateString = stateString+','+wsString[i]+':'+wsString[i]
       errString = errString+','+wsString[i]+':'+wseString[i]
     endif else begin
       xString = xString+wsxString[i]+':'+wsxString[i]
       stateString = stateString+wsString[i]+':'+wsString[i]
       errString = errString+wsString[i]+':'+wseString[i]
      endelse
  endfor
  xvarString = '*(*pState).xs='+xString+'}'
  errString = '*(*pState).errs='+errString+'}'
  stateString = '*(*pState).qtys='+stateString+'}'
;  print,xvarString
;  print,errString
;  print,stateString
  r = execute(stateString,1)
  r = execute(errString,1)
  r = execute(xvarString,1)

endif
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;==========================================
PRO hfbs_db,notifyIDs,group_leader = group_leader
; Widget definition module
tvlct,rorig,gorig,borig,/get
;yout = hfbs_dirValid((*inPtr).datDir)
;if yout eq 0 then begin
;  strout = ['Data directory is invalid on this system','Please select another']
;  void = dialog_message(dialog_parent = event.top,strout,/error)
;  directory = DIALOG_PICKFILE(title = 'Select data directory',/directory)
;  (*(*pState).inPtr).datDir = directory
;endif

;yout = hfbs_dirValid((*inPtr).workDir)
;if yout eq 0 then begin
;  strout = ['Working directory is invalid on this system','Please select another']
;  void = dialog_message(dialog_parent = event.top,strout,/error)
;  directory = DIALOG_PICKFILE(title = 'Select data directory',/directory)
;  (*(*pState).inPtr).workDir = directory
;endif

file_path = (*!dave_defaults).workDir;(*inPtr).workDir


printPath = file_path
dataPath = file_path

bsize=100
base_size=350
bbsize=200
base=  widget_base(/ROW,title='Backscattering Data Display',$
       /base_align_left,MBAR = bar)
filemenu = widget_button(bar,value = 'File',/menu)
void = widget_button(filemenu,value = 'Open DAVE file into Selected Buffer',event_pro='hfbsdbLoadDAVE')
void = widget_button(filemenu,value = 'Write current buffer to file', event_pro='hfbs_dbWriteBuffer')
void = widget_button(filemenu,value = 'Clear current buffer', event_pro='hfbs_dbClearCurrentBuffer')
void = widget_button(filemenu,value = 'Save WS into 3 cols', event_pro='SaveWsCols')
void = widget_button(filemenu,value = 'Detector count rates', event_pro='DispCountRates')
void = widget_button(filemenu,value = 'Exit',event_pro='hfbs_doneDB')
plotmenu = widget_button(bar,value = 'Plotting Options',/menu)
symdesc = REPLICATE({ flags:0, name:'' }, 12)
symdesc.flags = [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
symdesc.name = [ 'Plot Symbols', 'Circles\SelCircles', 'Triangles\SelTriangles', $
              'Diamonds\SelDiamonds', 'Boxes\SelBoxes','Horizontal Lines\SelLines','Continuous Line\SelContLine',$
              'Dotted Line\SelDotLine','Dashed Line\SelDashLine','Dash-Dot Line\SelDashDotLine',$
              'Dash-dot-dot-dot Line\SelDashDotDotDotLine','Long Dashes Line\SelLongDashLine' ]
plotsymmenu = CW_PDMENU(plotmenu, symdesc,/mbar)


button37 = widget_button(plotmenu,value = 'Print',event_pro='Print2PsFile')

void = widget_button(plotmenu,value = 'Omit error bars',event_pro='OmitErrorBars')
void = widget_button(plotmenu,value = 'Include error bars',event_pro='IncludeErrorBars')

fitdesc = REPLICATE({ flags:0, name:'' }, 7)
fitdesc.flags = [ 1, 0, 0, 0, 0, 0, 0 ]
fitdesc.name = [ 'Select a Fit Function', 'Gaussian(s)\SelGaussDB', 'Lorentzian(s)\SelLorentzDB', $
              'Voigt\SelVoigtDB', 'Gaussian+Lorentzian\SelGaussLorDB','Kohlrausch\SelKohlrauschDB',$
              'Resolution Broadened Kohlrausch\SelResKohlDB']

miscmenu = widget_button(bar,value = 'Misc',/menu)
button21 = widget_button(miscmenu,value = 'About',event_pro='About')
button22 = widget_button(miscmenu,value = 'Table',event_pro='TableInfo')

base1 = widget_base(base,/column,/base_align_center,xsize=base_size)
base3 = widget_base(base,/column,/base_align_center)
base3a = widget_base(base3,/row,/base_align_center)

base4 = widget_base(base3,/row,/base_align_center) ; base for workspace operations
base5 = widget_base(base3,/row,/base_align_center) ; base for workspace plot selections
base5a = widget_base(base3,/row,/base_align_center)   ; base for rebinning operations
base5b = widget_base(base5a,/row,/base_align_center,/frame) ;
base5c = widget_base(base5a,/row,/base_align_center,/frame) ;
base6 = widget_base(base3,/column,/base_align_center) ; base for graphics window


base1a = widget_base(base1,/row,/base_align_center,xsize=base_size)



detvalues    = ['Monitor','Det 1','Det 2','Det 3','Det 4','Det 5','Det 6',$
                'Det 7','Det 8','Det 9','Det 10','Det 11','Det 12',$
                'Det 13','Det 14','Det 15','Det 16','Empty','Empty',$
                'Empty','P(v) Monitor','P(v) Det Low',$
                'P(v) Det High']

wsvalues    = ['WS 1','WS 2','WS 3','WS 4','WS 5',$
               'WS 6','WS 7','WS 8','WS 9','WS 10',$
               'WS 11','WS 12','WS 13','WS 14','WS 15']

; Need to arrange these better in the main widget
chanwidth = cw_field(base5b,/string,title='Binning',value=2,/column,xsize = 3)
void = widget_button(base5b,value = 'Boxcar Average WS-->',event_pro = 'dbRebinWs')
TargetWs = widget_droplist(base5b,value = wsvalues,title = 'Target WS',event_pro='SelTargWs')
;;;;;;;;;;;;;;;;;;;;

workspaces = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']

selplotbase = widget_base(base3,/row,/base_align_center)
;;;;;;;;
selPlotField  = cw_field(base5c,/string,title='WS to plot',value='1',xsize=18,/column)
;;;;;;;;

winxsize = 500 & winysize = 425
plotWs = widget_button(base5c,value='Plot WS',event_pro='hfbs_dbPlotWs')
plotId = widget_draw(base3,xsize=winxsize,ysize=winysize,/button_events,$
         event_pro = 'hfbs_dbWinDraw')

titlebuffbase = widget_base(base1,/row,/base_align_center)
buffbase = widget_base(base1,/row,/base_align_center)


void = widget_label(titlebuffbase,value='Active Buffer')
buffvalues    = ['Buffer 1','Buffer 2','Buffer 3','Buffer 4','Buffer 5']
void = widget_label(titlebuffbase,value='           ')

buffdrop = WIDGET_DROPLIST(buffbase, VALUE=buffvalues,event_pro='SelBuffer')
void = widget_label(titlebuffbase,value='Active Workspace')

wsvalues_new = [wsvalues,'1 (constant)']
void = widget_label(buffbase,value='           ')
wsdrop = WIDGET_DROPLIST(buffbase, VALUE=wsvalues,event_pro='SelWork')

; Replace clumsy droplists with a single text field into which the
; user types the workspace operations
txtField = cw_field(base4,xsize = 30,value = '',title = 'Expression,e.g.w1=w2+5.0*w3',$
           /return_events,/frame)

buffer1  = cw_field(base1,/string,title='Buff 1',value='Empty',/noedit,xsize=15)
buffer2  = cw_field(base1,/string,title='Buff 2',value='Empty',/noedit,xsize=15)
buffer3  = cw_field(base1,/string,title='Buff 3',value='Empty',/noedit,xsize=15)
buffer4  = cw_field(base1,/string,title='Buff 4',value='Empty',/noedit,xsize=15)
buffer5  = cw_field(base1,/string,title='Buff 5',value='Empty',/noedit,xsize=15)

base9 = widget_base(base1,/row,/base_align_center,/frame)

;;;;;;;;;
detSlider = widget_slider(base1,title='Plot detectors',value = 1,minimum = 1,$
              maximum = 16,event_pro='plotDetsDB')
selDetField  = cw_field(base9,/string,title='Sum detectors',value='5-14',xsize=18,/column)
void = widget_button(base9,value='Sum->WS',event_pro='hfbs_dbSumDetsNew')
;;;;;;;;;

nws = 16 ; number of workspaces
nchan = -1+LONARR(nws)

helpPath=''

; Fit menus
fitbase = widget_base(base1,/column,/base_align_center)

void = widget_label(fitbase,value='Status')
INIT_TEXT = ''
textWid = widget_text(fitbase,value=INIT_TEXT,xsize=40,ysize=3,/scroll)

colors = hfbs_GetColor(/Load, Start=1)
ncolors = 16
ncolors = 16
z = 0l
names = strarr(ncolors)
names = strlowcase(tag_names(colors))
theseColors = lonarr(ncolors)
for i = 0,ncolors-1 do begin
  strTest = 'z=colors.'+string(names[i])
  r = execute(strTest)
  theseColors[i] = z
endfor
;theseColors = shift(theseColors,-1)
newColors = lonarr(ncolors)
newColors = [colors.white,$
             colors.yellow,$
             colors.cyan,$
             colors.red,$
             colors.green,$
             colors.blue,$
             colors.magenta,$
             colors.pink,$
             colors.orchid,$
             colors.sky,$
             colors.beige,$
             colors.charcoal,$
             colors.gray,$
             colors.navy,$
             colors.aqua,$
             colors.black]

centertlb,base
widget_control,base,/realize

nfitmax = 10
RebChan = 0
VanFile = ''
nptrmax = 100
CurMacroName = 'none'
threeDplot = 0
imagePlot = 0
sig2noise = 0
;CamType = 0   ; sine cam (triangle cam is CamType = 1)
CamType = 1 ; triangle cam
; Initialize the plotting symbols
symselect = intarr(16)
symselect = [0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3]
legendTxt = ''
wstreatment = strarr(nws)
wstreatment = REPLICATE('', nws)
treatment = strarr(5)
BuffLabel = strarr(5)
sumTBM = lonarr(5)
sumWBM = lonarr(5)
TBMrate = fltarr(5)
sumFC = fltarr(5)
DopFreq = fltarr(5)
Crate = fltarr(5)
ndet = intarr(5)
nlabels = strarr(16)
TimeBin = fltarr(5)
detangles = fltarr(16)
detqs = fltarr(16)
detangles = ['monitor','14.46','20.98','27.08','32.31','36.0','43.75','51.5','59.25','67.0',$
             '74.75','82.5','90.25','98.0','105.75','113.5','121.5']
lamo = 6.27

;winPix = !d.window
treatment = ['counts','counts','counts','counts','counts']

widget_control,plotId,get_value = winVis
window,/free,/pixmap,xsize = winxsize,ysize = winysize & winPix = !d.window

state = {xrangelo:0, xrangehi:0,nchan:nchan,VanFile:VanFile,textWid:textWid,$
          xlo:0.0, xhi:0.0,yrangelo:0.0,yrangehi:1.0,curplot:0,CurMacroName:CurMacroName,$
          ylo:0.0,yhi:0.0,MonPtr:ptr_new(),PvLowPtr:ptr_new(),xstart:0,ystart:0,$
          PvHighPtr:ptr_new(),PvMonPtr:ptrarr(5),dataPtr:ptr_new(),FCPtr:ptrarr(5),$
          ndet:ndet,plotId:plotId,scale:0,printPath:printPath,sumTBM:sumTBM,sumWBM:sumWBM,$
          errorPtr:ptr_new(),wsdrop:wsdrop,energy:0.0,buffchan:LONARR(5),DopFreq:DopFreq,$
          curws:0,curdet:0,nws:nws,curbuff:0,helpPath:helpPath,RebChan:RebChan,TBMrate:TBMrate,$
          buffdrop:buffdrop,nbuff:5,buffer1:buffer1,filename:[REPLICATE('Empty',5)],$
          buffer2:buffer2,buffer3:buffer3,buffer4:buffer4,xlabel:'Energy',Crate:Crate,$
          buffer5:buffer5,BuffPtr:ptrarr(5),errorBuffPtr:ptrarr(5),scan_livetimePtr:ptrarr(5),$
          BuffMonPtr:ptrarr(5),BuffPvPtr:ptrarr(5),detvalues:'',chanwidth:chanwidth,$
          energyPtr:ptrarr(nws,/allocate_heap),wsPtr:ptrarr(nws,/allocate_heap),$
          SelDetField:SelDetField,selPlotField:selPlotField,$
          wsErrPtr:ptrarr(nws,/allocate_heap),lines:0,sym:0,threeDplot:threeDplot,$
          comments:strarr(nws),mode:strarr(nws),start_time:strarr(nws),imagePlot:imagePlot,$
          stop_time:strarr(nws),cycles:strarr(nws),live_time:strarr(nws),BuffLabel:BuffLabel,$
          cycle_time:strarr(nws),op:0,ws3:0,TimeBin:TimeBin,$
          c1:1.0,c2:1.0,TargetWs:0,sumFC:sumFC,nlabels:nlabels,$
          BuffEnergyPtr:ptrarr(5),detcountPtr:ptrarr(5),moncount:LONARR(5),detangles:detangles,$
          xdisplo:-60.0,xdisphi:60.0,functionselect:0,wstreatment:wstreatment,detqs:detqs,$
          CamType:CamType,$
          symselect:symselect,legendTxt:legendTxt,treatment:treatment,dataPath:dataPath,$
          wholeFile:[REPLICATE('',5)],tempPtr:ptrarr(5),info:'',$
          countRatePtr:ptrarr(5),$
          xp1:0.0,$
          xp2:0.0,$
          yp1:0.0,$
          yp2:0.0,$
          mouse:0,$
          plotType:0,$  ; plotType = 0 for ws and plotType = 1 for detectors
          winxsize:winxsize,$
          winysize:winysize,$
          winPix:winPix,$
          winVis:winVis,$
          convert2Energy:0,$
          errBars:1,$
          file_path:file_path,$
          colors:colors,$
          theseColors:newColors,$
          detSlider:detSlider,$
          norm2FC:0,$
          rorig:rorig,$
          gorig:gorig,$
          borig:borig,$
          txtField:txtField,$
          qtys:ptr_new(/allocate_heap),$
          errs:ptr_new(/allocate_heap),$
          xs:ptr_new(/allocate_heap),$
          ;inPtr:inPtr,$
          notifyIDs:notifyIDs}

widget_control,base,set_uvalue=ptr_new(state)
ret = dave_set_focus(base)
xmanager,'hfbs_db',base,cleanup='hfbs_dbCleanup',/no_block
return
END
