; $Id: hfbs_davereduce.pro,v 1.6 2005/02/09 16:58:00 dimeo Exp $
;###############################################################################
;
; NAME:
;  HFBS_DAVEREDUCE
;
; PURPOSE:
;  GUI application for reduction of HFBS data
;
; CATEGORY:
;  DAVE, HFBS, Data Reduction
;
; 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_daveReduce.pro
;
; Utility for reducing raw HFBS data (.HFBS or .HSCN).  This
; program allows user to perform normalization to the beam
; monitor and normalization to a vanadium run.
;
; Written by R.M.Dimeo (11/04/01)
;
; Modification history
; -----------------------
; 11/30/01 (RMD): Every time a new file is loaded, the detector
; grouping is set to 1-16 with a single detector in each group.
;
;;;;;;;;;;;;
pro HFBS_DaveReduceCleanup,tlb
widget_control,tlb,get_uvalue = pState,/no_copy
tvlct,(*pState).rorig,(*pState).gorig,(*pState).borig
if (*pState).runFlag eq 1 then begin
  s = size((*pState).notifyIDs)
  if s[0] eq 1 then count = 0 else count = s[2]-1
  for j = 0,count do begin
    hfbsReduceInfo = {HFBSREDUCEEVENT,$
                            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 = hfbsReduceInfo
    endif
  endfor
endif

wdelete,(*pState).winPix
if ptr_valid((*pState).xPtr) then ptr_free,(*pState).xPtr
if ptr_valid((*pState).yPtr) then ptr_free,(*pState).yPtr
if ptr_valid((*pState).yerrPtr) then ptr_free,(*pState).yerrPtr
if ptr_valid((*pState).xoPtr) then ptr_free,(*pState).xoPtr
if ptr_valid((*pState).yoPtr) then ptr_free,(*pState).yoPtr
if ptr_valid((*pState).dataoPtr) then ptr_free,(*pState).dataoPtr
if ptr_valid((*pState).erroroPtr) then ptr_free,(*pState).erroroPtr
ptr_free,pState
return
end
;;;;;;;;;;;;
pro HFBS_DaveReduceDismiss,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*(*(*pState).inPtr).dataStrPtr).specificPtr) ne 0 then begin
  text = 'Do you want to save your workspace?'
  response = dialog_message(dialog_parent = event.top,text,/question)
  if strupcase(response) eq 'YES' then begin
    widget_control,event.top,set_uvalue = pState,/no_copy
    hfbs_daveReduceSaveWorkSpace,event
    widget_control,event.top,get_uvalue = pState,/no_copy
  endif
endif
if (*pState).runFlag eq 1 then begin
  s = size((*pState).notifyIDs)
  if s[0] eq 1 then count = 0 else count = s[2]-1
  for j = 0,count do begin
    hfbsReduceInfo = {HFBSREDUCEEVENT,$
                            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 = hfbsReduceInfo
    endif
  endfor
endif
widget_control,event.top,set_uvalue = pState,/no_copy
widget_control,event.top,/destroy
end
;;;;;;;;;;;;
pro hfbs_daveRedDeSensitize,event
widget_control,event.top,sensitive = 0
return
end
;;;;;;;;;;;;
pro hfbs_daveRedSensitize,event
widget_control,event.top,sensitive = 1
return
end
;;;;;;;;;;;;
pro HFBS_SubtractBG_NEW,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  strout = 'You must load in the signal file first'
  void = dialog_message(dialog_parent = event.top,strout)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

; First go through the treatment pointer for the signal file.
oldText = *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr
nstring = n_elements(oldText)
rebinBG = 0
norm2Mon = 0 & norm2Van = 0 & norm2One = 0
for i = 0,nstring-1 do begin
  if strpos(strupcase(oldText[i]),'MONITOR') ne -1 then begin	; normalization to beam monitor
    norm2Mon = 1
  endif
  if strpos(strupcase(oldText[i]),'VANADIUM') ne -1 then begin	; normalization to vanadium
    norm2Van = 1
    ; get the vanadium file name from the string
    colonPos = strpos(oldText[i],':')
    vanfile = strtrim(strmid(oldText[i],colonPos+1),2)
  endif
  if strpos(strupcase(oldText[i]),'SCALE') ne -1 then begin	; scale peaks to one
    norm2One = 1
  endif
  if strpos(strupcase(oldText[i]),'REBINNED') ne -1 then begin	; rebin background file
    ; extract the rebin parameters
    xloPos = strpos(strupcase(oldText[i]),'XLO')
    xhiPos = strpos(strupcase(oldText[i]),'XHI')
    nbinsPos = strpos(strupcase(oldText[i]),'NBINS')
    xlo = float(strmid(oldText[i],xloPos+4,xhiPos-1-xloPos-1-4))
    xhi = float(strmid(oldText[i],xhiPos+4,nbinsPos-1-xhiPos-1-4))
    nbins = fix(strmid(oldText[i],nbinsPos+6))
    rebinBG = 1
  endif
endfor

widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveRedDeSensitize,event
widget_control,event.top,get_uvalue = pState,/no_copy
file = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.hscn', '*.hfbs'],$
                               title = 'Select raw background data file')

widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveRedSensitize,event
widget_control,event.top,get_uvalue = pState,/no_copy

if strpos(file,'.hscn') ne -1 then daqmode = 'elastic'
if strpos(file,'.hfbs') ne -1 then daqmode = 'inelastic'
if file eq '' then begin
  void = dialog_message('You did not select an appropriate raw data file',$
            dialog_parent = event.top)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

;widget_control,hourglass = 1

if daqmode eq 'elastic' then begin	; read in a fixed window scan data file type
  strout = 'Subtraction of elastic scan files not supported'
  void = dialog_message(dialog_parent = event.top,strout)
  ;widget_control,hourglass = 0
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

if daqmode eq 'inelastic' then begin	; read in a dynamic run
  HFBS_ReadHFBS,file,0,energy,data,error,ndet,nchan,comments,$
                integ_int,$
                Norm2Mon = norm2Mon,$
                norm2One = norm2One,$
                doppler = fdoppler,$
                ncycles = ncycles,$
                temperature = temperature

  data = transpose(data)
  error = transpose(error)
  header = comments
  scPos = strpos(header[1],':')	; position of semicolon in header entry for user
  user = strpos(header[1],scPos+1)	; string var with user's name(s)
  sumFc = total(data[*,0])
 ;------Begin vanadium normalization here
  if norm2Van eq 1 then begin

   if strpos(vanfile,'.hscn') ne -1 then begin
     HFBS_ReadHSCN,vanfile,vantime,vanctemp,vanstemp,vandata,vanerror,vancomments,$
                                 vanTBM,vanFC,vanheader,vanxout,vantitles
     ndet = 16
     normFactors = dblarr(ndet)
     loIndex = where(vanstemp eq min(vanstemp),count)
     for i = 0,ndet-1 do begin
       normFactors[i] = vandata[i+1,loIndex[0]]
     endfor
   endif
   if strpos(vanfile,'.hfbs') ne -1 then begin
     HFBS_ReadHFBS,vanfile,0,vanenergy,vandata,vanerror,vanndet,vannchan,vancomments,$
                  vaninteg_int,norm2Mon = 1
     ndet = 16
     normFactors = dblarr(ndet)
     for i = 0,ndet-1 do begin
       normFactors[i] = int_tabulated(vanenergy,vandata[i+1,*],/sort)
     endfor
   endif
   vanave = (moment(normFactors))[0]
   normFactors = normFactors/vanave
   for j = 0,ndet-1 do begin
     data[*,j+1] = data[*,j+1]/normFactors[j]
     error[*,j+1] = error[*,j+1]/normFactors[j]
    endfor
  endif
;------end vanadium normalization here
if rebinBG eq 1 then begin		; rebin the background file
  datSize = size(data)
  nx = datSize[1] & ny = datSize[2]
  ndet = ny-1
  nchan = nbins
  rebdata = fltarr(nchan,ndet+1)
  reberror = fltarr(nchan,ndet+1)
  xbin = hfbs_makepoints(xlo = xlo,xhi = xhi,npts = nbins)
  binsize = (xhi-xlo)/(nbins-1.0)
  oldbinsize = (max(energy)-min(energy))/(n_elements(energy)-1.0)
  chanw = round(binsize/oldbinsize)
  yint = fltarr(nbins)
  errint = fltarr(nbins)
  y = fltarr(nx) & yerr = fltarr(nx)
  for i = 0,ndet do begin
    x = energy
    y[*] =  data[*,i];(*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty[i,*]
    yerr[*] = error[*,i];(*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).err[i,*]
    ysmooth = smooth(y,chanw,/edge_truncate)
    yerr = yerr/sqrt(chanw)
    yint = interpol(ysmooth,x,xbin)
    errint = interpol(yerr,x,xbin)
    rebdata[0:nchan-1,i] = yint[0:nchan-1]
    reberror[0:nchan-1,i] = errint[0:nchan-1]
  endfor
  energy = xbin
  data = rebdata
  error = reberror
endif
;---end rebin background here---;
  detangles = [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]
  ndet = n_elements(detangles)	; number of q-values
  widget_control,(*pState).groupSlider,set_slider_max = fix(ndet),set_slider_min = 1
  ;widget_control,(*pState).groupSlider,set_value = fix(ndet)
  lamo = 6.27
  q = fltarr(ndet)
  q = (4.0*!pi/lamo)*sin(0.5*!dtor*detangles)
  x = energy
  y = q

  ; now perform the subtraction
  sigqty = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty
  sigerr = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).err
  sigx = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).x
  sigy = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).y

  qty = dblarr(nchan,ndet+1)
  err = dblarr(nchan,ndet+1)
  x = dblarr(nchan)
  y = dblarr(ndet)
  for i = 0,ndet do begin
    qty[*,i] = sigqty[*,i] - interpol(data[*,i],energy,sigx)
    err[*,i] = sqrt(sigerr[*,i]^2 + (interpol(error[*,i],energy,sigx))^2)
  endfor
  x = sigx
  y = sigy
  *(*pState).xPtr = x
  *(*pState).yPtr = qty[*,1]
  *(*pState).yerrPtr = err[*,1]
  (*pState).xviewrange = [min(x),max(x)]
  dy = max(y)-min(y)
  (*pState).yviewrange = [min(y)-0.1*dy,max(y)+0.1*dy]

  *(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = {qty:qty,$
                                                err:err,$
                                                x:x,$
                                                y:y}

  *(*pState).dataoPtr = qty
  *(*pState).erroroPtr = err
  *(*pState).xoPtr = x
  *(*pState).yoPtr = y

  old = *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr
  newText = 'Background subtracted: '+strtrim(file,2)
  new = [old,newText]
  *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = new
  ;widget_control,hourglass = 0
  wset,(*pState).winPix
  widget_control,event.top,set_uvalue = pState,/no_copy
  hfbs_daveReducePlot,event
  widget_control,event.top,get_uvalue = pState,/no_copy
  wset,(*pState).winVis
  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro hfbs_GroupDetectors,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
yout = hfbsGroupWidget(group_leader = event.top,(*pState).selDetPtr)
;
; Now cycle through the detectors and do the grouping
qty = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty
err = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).err
x = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).x
q = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).y

qtsize = size(qty)
nx = qtsize[1] & ny = qtsize[2]
newqty = dblarr(nx,ny)
ndet = ny
newq = dblarr(ndet)
newerr = dblarr(nx,ny)
for i = 0,ndet-1 do begin
  wherevalid = where(yout[i,*] eq 1,count)
  if count gt 0 then begin
    for j = 0,count-1 do begin
      newqty[*,i] = qty[*,wherevalid[j]] + newqty[*,i]
	  newerr[*,i] = err[*,wherevalid[j]]^2 + newerr[*,i]^2
      newq[i] = newq[i] + q[wherevalid[j]]
    endfor
    newq[i] = newq[i]/(1.0*count)
    newerr[*,i] = sqrt(newerr[*,i])
  endif
endfor

keepGroup = intarr(ndet)
for i = 0,ndet-1 do begin
  if total(yout[i,*]) ne 0 then begin
    keepGroup[i] = 1
  endif
endfor
keepTheseGroups = where(keepGroup eq 1,count)
widget_control,(*pState).groupSlider,set_slider_max = count
; Now reform the elements of the structure, histPtr...
newHist = {qty:newqty[*,keepTheseGroups],$
                err:newerr[*,keepTheseGroups],$
                x:x,$
                y:newq[keepTheseGroups]}
*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = newHist
; Now update the pointer that keeps track of the groups present
thisArray = 0*intarr(count,count)
for i = 0,count-1 do begin
  thisArray[i,i] = 1
endfor
*(*pState).selDetPtr = thisArray
text = 'Detectors have been regrouped'
oldText = *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr
text = [oldText,text]
*(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = text
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReducePlot,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

x = *(*pState).xPtr
y = *(*pState).yPtr
yerr = *(*pState).yerrPtr

if (*pState).autoscale eq 1 then begin
  (*pState).xviewrange = [min(x),max(x)]
  dy = max(y)-min(y)
  (*pState).yviewrange = [min(y)-0.1*dy,max(y)+0.1*dy]
endif
xlabel = (*(*(*pState).inPtr).dataStrPtr).commonStr.xlabel
;wset,(*pState).winPix
plot,x,y,psym = 8,xrange = (*pState).xviewrange,$
      yrange = (*pState).yviewrange,xstyle = 1,ystyle = 1,$
      xtitle = xlabel,title = (*pState).title
errplot,x,y-yerr,y+yerr,width = 0.0
;wset,(*pState).winVis
;device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
;empty
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReduceChangeGroup,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
widget_control,(*pState).groupSlider,get_value = group
group = group - 1
y =  (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty[*,group[0]]
yerr = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).err[*,group[0]]
x = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).x
qvalue = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).y[group[0]]
(*pState).title = 'Q = '+strtrim(string(qvalue,format = '(f6.2)'),2)+' (!6!sA!r!u!9 %!6!n!E-1!N)'

*(*pState).xPtr = x
*(*pState).yPtr = y
*(*pState).yerrPtr = yerr
wset,(*pState).winPix
widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveReducePlot,event
widget_control,event.top,get_uvalue = pState,/no_copy
wset,(*pState).winVis
device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
empty
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveLoadReduce,event
widget_control,event.top,get_uvalue = pState,/no_copy
widget_control,(*pState).normgroup,get_value = normvalue
thisArray = 0*intarr(16,16)
for i = 0,15 do begin
 thisArray[i,i] = 1
endfor
*(*pState).selDetPtr = thisArray

; first value is normalization to beam monitor
norm2Mon = normvalue[0]
; second value is normalization to a vanadium run
norm2Van = normvalue[1]
; third value is normalization of each peak to one
norm2One = normvalue[2]

; Get the current date to provide the date stamp on the workspace
caldat,systime(/julian),month,day,year
date = strtrim(string(month),2)+$
       '/'+strtrim(string(day),2)+$
       '/'+strtrim(string(year),2)
instrument = 'HFBS'
filepath = (*!dave_defaults).datDir;(*(*pState).inPtr).datDir

widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveRedDeSensitize,event
widget_control,event.top,get_uvalue = pState,/no_copy
if (!version).release ge 5.4 then begin
;file = dialog_pickfile(dialog_parent = event.top,/read, $
;                               filter = ['*.hscn', '*.hfbs'],$
;                               title = 'Select raw data file',$
;                               path = filepath)
file = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.hscn'],$
                               title = 'Select raw data file',$
                               path = filepath)
endif else begin
file = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = '*.hscn',$
                               title = 'Select raw data file')
endelse

widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveRedSensitize,event
widget_control,event.top,get_uvalue = pState,/no_copy

if strpos(file,'.hscn') ne -1 then daqmode = 'elastic'
if strpos(file,'.hfbs') ne -1 then daqmode = 'inelastic'
if file eq '' then begin
  void = dialog_message('You did not select an appropriate raw data file')
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

;widget_control,hourglass = 1

if daqmode eq 'elastic' then begin	; read in a fixed window scan data file type
  HFBS_ReadHSCN,file,time,ctemp,stemp,data,error,comments,$
                TBM,FC,header,xout,titles,WBM = WBM,norm2Mon = norm2Mon,$
                norm2One = norm2One

 ;------Begin vanadium normalization here
  if norm2Van eq 1 then begin
    if (!version).release ge 5.4 then begin
;      vanfile = dialog_pickfile(dialog_parent = event.top,/read, $
;                                     filter = ['*.hscn', '*.hfbs'],$
;                                     title = 'Select vanadium data file')
      vanfile = dialog_pickfile(dialog_parent = event.top,/read, $
                                     filter = ['*.hscn','*.hfbs'],$
                                     title = 'Select vanadium data file')
    endif else begin
      vanfile = dialog_pickfile(dialog_parent = event.top,/read, $
                                      filter = '*.hscn',$
                                      title = 'Select vanadium data file')
    endelse
    if vanfile eq '' then begin
     void = dialog_message(dialog_parent = event.top,$
              'You did not select an appropriate raw data file',/error)
     widget_control,event.top,set_uvalue = pState,/no_copy
     return
   endif
   if strpos(vanfile,'.hscn') ne -1 then begin
     HFBS_ReadHSCN,vanfile,vantime,vanctemp,vanstemp,vandata,vanerror,vancomments,$
                                 vanTBM,vanFC,vanheader,vanxout,vantitles
     ndet = 16
     normFactors = dblarr(ndet)
     loIndex = where(vanstemp eq min(vanstemp),count)
     for i = 0,ndet-1 do begin
       normFactors[i] = vandata[i+1,loIndex[0]]
     endfor
   endif
   if strpos(vanfile,'.hfbs') ne -1 then begin
     HFBS_ReadHFBS,vanfile,0,vanenergy,vandata,vanerror,vanndet,vannchan,vancomments,$
                  vaninteg_int,norm2Mon = 1
     ndet = 16
     normFactors = dblarr(ndet)
     for i = 0,ndet-1 do begin
       normFactors[i] = int_tabulated(vanenergy,vandata[i+1,*],/sort)
     endfor
   endif
   vanave = (moment(normFactors))[0]
   normFactors = normFactors/vanave
   for j = 0,ndet-1 do begin
     data[j+1,*] = data[j+1,*]/normFactors[j]
     error[j+1,*] = error[j+1,*]/normFactors[j]
    endfor
  endif
;------end vanadium normalization here
  data = transpose(data)
  error = transpose(error)

  datsize = size(data)
  scPos = strpos(header[1],':')	; position of semicolon in header entry for user
  user = strpos(header[1],scPos+1)	; string var with user's name(s)
  time = temporary(time)/60.0
  sx = datsize[1]		; number of temperatures
  sy = datsize[2]
  nchan = sy
  ncycles = sx
  detangles = [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]
  ndet = n_elements(detangles)	; number of q-values
  lamo = 6.27
  q = fltarr(ndet)
  q = (4.0*!pi/lamo)*sin(0.5*!dtor*detangles)
  x = stemp
  y = q
  widget_control,(*pState).groupSlider,set_slider_max = fix(ndet),set_slider_min = 1
  ;widget_control,(*pState).groupSlider,set_value = fix(ndet)
  *(*pState).xPtr = x
  *(*pState).yPtr = data[*,1]
  *(*pState).yerrPtr = error[*,1]
  (*pState).xviewrange = [min(x),max(x)]
  dy = max(y)-min(y)
  (*pState).yviewrange = [min(y)-0.1*dy,max(y)+0.1*dy]

  ; transposed data and interchanged x and y here to be consistent with
  ; Copley's definitions (11/28/01)
  *(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = {qty:data[*,1:16],$
                                                err:error[*,1:16],$
                                                x:x,$
                                                y:y}
  *(*pState).dataoPtr = data
  *(*pState).erroroPtr = error
  *(*pState).xoPtr = x
  *(*pState).yoPtr = y

  (*(*(*pState).inPtr).dataStrPtr).commonStr.instrument = instrument
  (*(*(*pState).inPtr).dataStrPtr).commonStr.xlabel = 'T ';(K)'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.ylabel = 'Q ';(!6!sA!r!u!9 %!6!n!E-1!N)'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.xunits = 'temperature:kelvin'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.yunits = 'wavevector:A-1'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.histunits = ''
  (*(*(*pState).inPtr).dataStrPtr).commonStr.histlabel = 'I (arbitrary units)'
  treatment = ['file: '+file]
  treatment = [treatment,'converted from RAW to DAVE']
  if norm2Mon eq 1 then treatment = [treatment, 'monitor normalization']
  if norm2Van eq 1 then treatment = [treatment,'vanadium normalization: '+strtrim(vanfile,2)]
  if norm2One eq 1 then treatment = [treatment,'peaks scaled to one']
  *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = treatment
  (*(*(*pState).inPtr).dataStrPtr).commonStr.xtype = 'POINTS'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.ytype = 'POINTS'

  specific = {nchan:nchan,$							; number of "energy" channels
              ndet:ndet,$							; number of detectors (or groups)
              ncycles:ncycles,$						; number of raw data file updates
              phiPtr:ptr_new(detangles),$			; detector angles
              qPtr:ptr_new(q),$						; wavevector transfer for each detector
              ePtr:ptr_new(e),$						; energy
              monPtr:ptr_new(transpose(data[*,0])),$
              monErrPtr:ptr_new(transpose(error[*,0])),$
              instrument:instrument,$
              wavelength:lamo,$
              camType:'',$
              daqmode:daqmode,$
              dopplerFrequency:0.0,$
              date:date,$
              user:user,$
              veldist:0.0,$
              temp_sample:stemp,$
              temp_setpoint:ctemp,$
              temp_control:ctemp,$
              timePtr:ptr_new(time),$
              rawFileName:file,$
              comments:header,$
              TBMPtr:ptr_new(TBM),$
              FCPtr:ptr_new(FC),$
              WBMPtr:ptr_new(WBM)}

  *(*(*(*pState).inPtr).dataStrPtr).specificPtr = specific
  ;widget_control,hourglass = 0
  wset,(*pState).winPix
  widget_control,event.top,set_uvalue = pState,/no_copy
  hfbs_daveReducePlot,event
  widget_control,event.top,get_uvalue = pState,/no_copy
  wset,(*pState).winVis
  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

if daqmode eq 'inelastic' then begin	; read in a dynamic run
  HFBS_ReadHFBS,file,0,energy,data,error,ndet,nchan,comments,$
                integ_int,$
                Norm2Mon = norm2Mon,$
                norm2One = norm2One,$
                doppler = fdoppler,$
                ncycles = ncycles,$
                temperature = temperature;,$
;                sumfc = sumfc,$
;                sumtbm = sumtbm,$
;                sumwbm = sumwbm
;  print,'FC: ',sumfc
;  print,'WBM: ',sumwbm
  header = comments
  scPos = strpos(header[1],':')	; position of semicolon in header entry for user
  user = strpos(header[1],scPos+1)	; string var with user's name(s)
  sumFc = total(data[0,*])
 ;------Begin vanadium normalization here
  if norm2Van eq 1 then begin
    if (!version).release ge 5.4 then begin
      vanfile = dialog_pickfile(dialog_parent = event.top,/read, $
                                     filter = ['*.hscn', '*.hfbs'],$
                                     title = 'Select vanadium data file')
    endif else begin
      vanfile = dialog_pickfile(dialog_parent = event.top,/read, $
                                      filter = '*.hscn',$
                                      title = 'Select vanadium data file')
    endelse
    if vanfile eq '' then begin
     void = dialog_message(dialog_parent = event.top,$
               'You did not select an appropriate raw data file',/error)
     widget_control,event.top,set_uvalue = pState,/no_copy
     return
   endif
   if strpos(vanfile,'.hscn') ne -1 then begin
     HFBS_ReadHSCN,vanfile,vantime,vanctemp,vanstemp,vandata,vanerror,vancomments,$
                                 vanTBM,vanFC,vanheader,vanxout,vantitles
     ndet = 16
     normFactors = dblarr(ndet)
     loIndex = where(vanstemp eq min(vanstemp),count)
     for i = 0,ndet-1 do begin
       normFactors[i] = vandata[i+1,loIndex[0]]
     endfor
   endif
   if strpos(vanfile,'.hfbs') ne -1 then begin
     HFBS_ReadHFBS,vanfile,0,vanenergy,vandata,vanerror,vanndet,vannchan,vancomments,$
                  vaninteg_int,norm2Mon = 1
     ndet = 16
     normFactors = dblarr(ndet)
     for i = 0,ndet-1 do begin
       normFactors[i] = int_tabulated(vanenergy,vandata[i+1,*],/sort)
     endfor
   endif
   vanave = (moment(normFactors))[0]
   normFactors = normFactors/vanave
   for j = 0,ndet-1 do begin
     data[j+1,*] = data[j+1,*]/normFactors[j]
     error[j+1,*] = error[j+1,*]/normFactors[j]
    endfor
  endif
;------end vanadium normalization here

  detangles = [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]
  ndet = n_elements(detangles)	; number of q-values
  widget_control,(*pState).groupSlider,set_slider_max = fix(ndet),set_slider_min = 1
  lamo = 6.27
  q = fltarr(ndet)
  q = (4.0*!pi/lamo)*sin(0.5*!dtor*detangles)
  x = energy
  y = q
  *(*pState).xPtr = x
  *(*pState).yPtr = data[1,*]
  *(*pState).yerrPtr = error[1,*]
  (*pState).xviewrange = [min(x),max(x)]
  dy = max(y)-min(y)
  (*pState).yviewrange = [min(y)-0.1*dy,max(y)+0.1*dy]


  specific = {nchan:nchan,$							; number of "energy" channels
              ndet:ndet,$							; number of detectors (or groups)
              monPtr:ptr_new(transpose(data[0,*])),$
              monErrPtr:ptr_new(transpose(error[0,*])),$
              ncycles:ncycles,$						; number of raw data file updates
              phiPtr:ptr_new(detangles),$			; detector angles
              qPtr:ptr_new(q),$						; wavevector transfer for each detector
              ePtr:ptr_new(energy),$				; energy
              instrument:instrument,$
              wavelength:lamo,$
              camType:'triangular',$
              daqmode:daqmode,$
              dopplerFrequency:fdoppler,$
              date:date,$
              user:user,$
              veldist:0.0,$
              temp_sample:temperature,$
              temp_setpoint:temperature,$
              temp_control:temperature,$
              rawFileName:file,$
              comments:comments,$
              sumfc:sumfc,$
              sumtbm:0.0,$
              sumwbm:0.0}


  hbar_omega = '!6!sh!r!e/!n !7x!6'
  xlabel = 'E ';hbar_omega+' (!4l!6eV)'
  ylabel = 'Q ';'Q (!6!sA!r!u!9 %!6!n!E-1!N)'
  xunits = 'energy:ueV'
  yunits = 'wavevector:A-1'
  histlabel = 'I (arbitrary units)'
  histunits = ''

  ; transposed data and interchanged x and y here to be consistent with
  ; Copley's definitions (11/28/01)
  data = transpose(data)
  data = data[*,1:ndet]
  error = transpose(error)
  error = error[*,1:ndet]

  *(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = {qty:data,$
                                                err:error,$
                                                x:x,$
                                                y:y}

  *(*pState).dataoPtr = data
  *(*pState).erroroPtr = error
  *(*pState).xoPtr = x
  *(*pState).yoPtr = y
  (*(*(*pState).inPtr).dataStrPtr).commonStr.instrument = instrument
  (*(*(*pState).inPtr).dataStrPtr).commonStr.xtype = 'POINTS'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.ytype = 'POINTS'
  (*(*(*pState).inPtr).dataStrPtr).commonStr.xlabel = xlabel
  (*(*(*pState).inPtr).dataStrPtr).commonStr.ylabel = ylabel
  (*(*(*pState).inPtr).dataStrPtr).commonStr.histlabel = histlabel
  (*(*(*pState).inPtr).dataStrPtr).commonStr.xunits = xunits
  (*(*(*pState).inPtr).dataStrPtr).commonStr.yunits = yunits
  (*(*(*pState).inPtr).dataStrPtr).commonStr.histunits = histunits
  treatment = ['file: '+file]
  treatment = [treatment,'converted from RAW to DAVE','converted to energy','normalized to P(v)']
  if norm2Mon eq 1 then treatment = [treatment, 'monitor normalization']
  if norm2Van eq 1 then treatment = [treatment,'vanadium normalization: '+strtrim(vanfile,2)]
  if norm2One eq 1 then treatment = [treatment,'peaks scaled to one']
  *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = treatment

  *(*(*(*pState).inPtr).dataStrPtr).specificPtr = specific
  ;widget_control,hourglass = 0
  wset,(*pState).winPix
  widget_control,event.top,set_uvalue = pState,/no_copy
  hfbs_daveReducePlot,event
  widget_control,event.top,get_uvalue = pState,/no_copy
  wset,(*pState).winVis
  device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReduceDisplayTreatment,event
; Display file header info and the contents of the treatment
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*(*(*pState).inPtr).dataStrPtr).specificPtr) eq 0 then begin
  text = 'No data has been loaded'
  void = dialog_message(dialog_parent = event.top,text)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
text = (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).comments
text = [text,*(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr]
void = HFBS_DispTreat(group_leader = event.top,text)
;void = dialog_message(dialog_parent = event.top,text,/information)
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReduceSaveWorkspace,event
widget_control,event.top,get_uvalue = pState,/no_copy
filepath = (*!dave_defaults).workDir;(*(*pState).inPtr).workDir
filename = DIALOG_PICKFILE(dialog_parent = event.top,$
                                              title = 'Enter filename',$
                                              /write,filter = '*.dave',$
                                              path = filepath)
if filename eq '' then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
filename = filename+'.dave'
state = *(*pState).inPtr
davePtr = ptr_new(state,/no_copy)
save, davePtr, FILENAME = filename
ptr_free,davePtr
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveOldBinning,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
qty = *(*pState).dataoPtr
err = *(*pState).erroroPtr
y = *(*pState).yoPtr
x = *(*pState).xoPtr
newState = {qty:qty,err:err,y:y,x:x}
*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = newState
widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveReduceChangeGroup,event
widget_control,event.top,get_uvalue = pState,/no_copy
; If the data has been rebinned prior to this step, then
; search the current treatment string for an ocurrence of
; the rebinning and REMOVE IT!
oldText = *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr
nstring = n_elements(oldText)
whereValid = where(strpos(oldText,'Rebinned') ne -1,countValid)
while countValid gt 0 do begin
  newText = strarr(n_elements(oldText)-1)
  newText = HFBS_RemElInVec(oldText,whereValid[0])
  oldText = newText
  whereValid = where(strpos(oldText,'Rebinned') ne -1,countValid)
endwhile
*(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = oldText
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReduceRebin,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
xsort = sort(*(*pState).xPtr)
x = (*(*pState).xPtr)[xsort]
npts = n_elements(x)
xlo = min(x)
xhi = max(x)
oldbinsize = max(deriv(x))
rebVals = hfbs_RebWidget(xlo = xlo,xhi = xhi,binsize = oldbinsize,group_leader = event.top)
xlo = rebVals[0] & xhi = rebVals[1] & binsize = rebVals[2]
nbins = 1+fix((xhi-xlo)/binsize)

qty =  (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty
datSize = size(qty)
nx = datSize[1] & ny = datSize[2]
ndet = ny-1
nchan = nbins
data = fltarr(nchan,ndet+1)
error = fltarr(nchan,ndet+1)
xbin = hfbs_makepoints(xlo = xlo,xhi = xhi,npts = nbins)

chanw = round(binsize/oldbinsize)
if chanw le 1 then begin
  strout = 'Bin size is too small'
  void = dialog_message(/error,strout,dialog_parent = event.top)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
yint = fltarr(nbins)
errint = fltarr(nbins)

for i = 0,ndet do begin
  y =  (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty[*,i]
  yerr = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).err[*,i]
  ysmooth = smooth(y,chanw,/edge_truncate)
  yerr = yerr/sqrt(chanw)
  yint = interpol(ysmooth,x,xbin)
  errint = interpol(yerr,x,xbin)
  data[0:nchan-1,i] = yint[0:nchan-1]
  error[0:nchan-1,i] = errint[0:nchan-1]
endfor
oldY = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).y
newState = {qty:data,err:error,x:xbin,y:oldY}
*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr = newState
text = 'Rebinned into equal channel widths:'+$
          'xlo='+strtrim(xlo,2)+', '+$
          'xhi='+strtrim(xhi,2)+', '+$
          'nbins='+strtrim(nbins,2)

widget_control,event.top,set_uvalue = pState,/no_copy
hfbs_daveReduceChangeGroup,event
widget_control,event.top,get_uvalue = pState,/no_copy

oldText = *(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr
text = [oldText,text]
*(*(*(*pState).inPtr).dataStrPtr).commonStr.treatmentPtr = text
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReduceSaveConFile,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  strout = 'No data present'
  void = dialog_message(/error,strout,dialog_parent = event.top)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
if (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).daqmode eq 'elastic' then begin
  strout = 'Cannot write a fixed-window scan out as a .CON file'
  void = dialog_message(/error,strout,dialog_parent = event.top)
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif
detangles = *(*(*(*(*pState).inPtr).dataStrPtr).specificPtr).phiPtr
sumTBM = (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).sumtbm

sumFC = total((*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty[*,0])
sumWBM = (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).sumwbm
comments = (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).comments
file = (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).rawFileName

data = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).qty
energy = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).x
error = (*(*(*(*pState).inPtr).dataStrPtr).commonStr.histPtr).err

if n_elements((*(*(*(*pState).inPtr).dataStrPtr).specificPtr).temp_sample) gt 0 then begin
  temperature = (*(*(*(*pState).inPtr).dataStrPtr).specificPtr).temp_sample
endif
datsize = size(data)
nchan = datSize[1]
sumFC = total(data[0:nchan-1,0])

; 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',$
                title = 'Enter output filename',$
                dialog_parent = event.top)
  newfile = newfile+'.con'
  OPENW, lun, newfile, /GET_LUN
  ; write header
  for i=0,nheader-1 do begin
    printf,lun,header[i]
  endfor

;  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 n_elements(temperature) gt 0 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
  detangle = ['beam monitor',string(detangles)]
  for i=0,16 do begin
    printf,lun,'#Detector '+string(i)+':  '+detangle[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[j,i],error[j,i],format='(3(E15.6,x))'
    endfor
  endfor
  ;
  free_lun, lun
  void = dialog_message(/information,'Data file successfully written',$
            dialog_parent = event.top)

widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro hfbs_daveReduceDraw,event
widget_control,event.top,get_uvalue = pState,/no_copy
if not ptr_valid((*pState).xPtr) 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
      if (*pState).mouse eq 4 then begin
        (*pState).autoscale = 1
        wset,(*pState).winPix
        widget_control,event.top,set_uvalue = pState,/no_copy
        hfbs_daveReducePlot,event
        widget_control,event.top,get_uvalue = pState,/no_copy
        wset,(*pState).winVis
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
      endif
      if (*pState).mouse eq 1 then begin
        widget_control,(*pState).plotWin,draw_motion_events = 1
        (*pState).autoscale = 0
        (*pState).xbox[0] = event.x
        (*pState).ybox[0] = event.y
        wset,(*pState).winVis
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
      endif
    end
1:  begin
      if (*pState).mouse eq 4 then begin
        (*pState).mouse = 0B
      endif
      if (*pState).mouse eq 1 then begin
        xll = (*pState).xbox[0] < (*pState).xbox[1]
        yll = (*pState).ybox[0] < (*pState).ybox[1]
        w = abs((*pState).xbox[1]-(*pState).xbox[0])
        h = abs((*pState).ybox[1]-(*pState).ybox[0])
        xur = xll + w
        yur = yll + h
        ll = convert_coord(xll,yll,/device,/to_data)
        ur = convert_coord(xur,yur,/device,/to_data)
        (*pState).xviewrange = [ll[0],ur[0]]
        (*pState).yviewrange = [ll[1],ur[1]]
        wset,(*pState).winPix
        widget_control,event.top,set_uvalue = pState,/no_copy
        hfbs_daveReducePlot,event
        widget_control,event.top,get_uvalue = pState,/no_copy
        wset,(*pState).winVis
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
        widget_control,(*pState).plotWin,draw_motion_events = 0
        (*pState).mouse = 0B
      endif
    end
2:  begin
       if (*pState).mouse eq 1 then begin
         (*pState).xbox[1] = event.x
         (*pState).ybox[1] = event.y
         xc = [(*pState).xbox[0],event.x,event.x,(*pState).xbox[0],(*pState).xbox[0]]
         yc = [(*pState).ybox[0],(*pState).ybox[0],event.y,event.y,(*pState).ybox[0]]
         wset,(*pState).winVis
         device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
         plots,xc,yc,/device
         empty
       endif
     end
else:
endcase

widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_daveReducePrint,event
widget_control,event.top,get_uvalue = pState,/no_copy
if n_elements(*(*pState).xPtr) eq 0 then begin
  void = dialog_message(dialog_parent = event.top,'Nothing loaded yet')
  widget_control,event.top,set_uvalue = pState,/no_copy
  return
endif

  printPath = (*!dave_defaults).workDir;(*(*pState).inPtr).workDir
  ;cd,printPath
  printFile = printPath + 'idl.ps'
  thisDevice = !d.name
  ; use one of Fanning's routines, PS_FORM.PRO, to allow
  ; user to interactively configure
  ; the postscript output
  deviceKeywords = ps_form(Cancel = canceled,parent = event.top,filename = printFile)
  if canceled ne 1 then begin
    SET_PLOT, 'PS'
    DEVICE, _EXTRA = deviceKeywords
    widget_control,event.top,set_uvalue = pState,/no_copy
    hfbs_daveReducePlot,event
    widget_control,event.top,get_uvalue = pState,/no_copy
    DEVICE, /CLOSE_FILE
    set_plot,thisDevice
  endif
widget_control,event.top,set_uvalue = pState,/no_copy
return
end
;;;;;;;;;;;;
pro HFBS_DaveReduce_event,event
return
end
;;;;;;;;;;;;
pro HFBS_DaveReduce,notifyIDs,inPtr,group_leader = group_leader
; widget definition module
; Get colors upon entering the reduction utility
tvlct,rorig,gorig,borig,/get
loadct,0,/silent
butsize = 250

numtags = n_tags(*(*(*inPtr).dataStrPtr).commonStr.histPtr)
if numtags ne 0 then begin
   x = (*(*(*inPtr).dataStrPtr).commonStr.histPtr).x
   y = (*(*(*inPtr).dataStrPtr).commonStr.histPtr).y
   data = (*(*(*inPtr).dataStrPtr).commonStr.histPtr).qty
   error = (*(*(*inPtr).dataStrPtr).commonStr.histPtr).err
   xoPtr = ptr_new(x)
   yoPtr = ptr_new(y)
   dataoPtr = ptr_new(data)
   erroroPtr = ptr_new(error)
   xPtr = ptr_new(x)
   yPtr = ptr_new(data[1,*])
   yerrPtr = ptr_new(error[1,*])
endif else begin
   xoPtr = ptr_new(/allocate_heap)
   yoPtr = ptr_new(/allocate_heap)
   dataoPtr = ptr_new(/allocate_heap)
   erroroPtr = ptr_new(/allocate_heap)
   xPtr =  ptr_new(/allocate_heap)
   yPtr =  ptr_new(/allocate_heap)
   yerrPtr =  ptr_new(/allocate_heap)
endelse

; create the filled circle symbols for use in plotting the data
th = hfbs_makepoints(xlo = 0.0,xhi = 2.0*!pi,npts = 30)
xsym = cos(th) & ysym = sin(th)
usersym,xsym,ysym

if n_elements(notifyIDs) eq 0 and n_elements(inPtr) eq 0 then begin
  tlb = widget_base(/row,title = 'Fixed Window Scan Data Reduction Utility',$
                  tlb_frame_attr = 1,mbar = bar)
  runFlag = 0	; running as standalone
  notifyIDs = [0L,0L] & inPtr = 0.0	; give these some dummy values
endif else begin
  tlb = widget_base(/row,title = 'Fixed Window Scan Data Reduction Utility',group_leader = group_leader,$
                  tlb_frame_attr = 1,mbar = bar)
  runFlag = 1	; running from other application
endelse

base = widget_base(tlb,/col)
filemenu = widget_button(bar,value = 'File',/menu)
treatmenu = widget_button(bar,value = 'Treatment',/menu)
printmenu = widget_button(bar,value = 'Print',/menu)
void = widget_button(treatmenu,value = 'Rebin data',event_pro = 'HFBS_daveReduceRebin')
void = widget_button(treatmenu,value = 'Original binning',event_pro = 'HFBS_daveOldBinning')
void = widget_button(filemenu,value = 'Load and Reduce',$
         event_pro = 'HFBS_daveLoadReduce')
void = widget_button(filemenu,value = 'Save workspace',$
         event_pro = 'HFBS_daveReduceSaveWorkspace')
;void = widget_button(filemenu,value = 'Save as a .CON file',$
;         event_pro = 'HFBS_daveReduceSaveConFile')
void = widget_button(treatmenu,value = 'Group Detectors',$
         event_pro = 'HFBS_GroupDetectors')
void = widget_button(treatmenu,value = 'Background Subtraction',$
         event_pro = 'HFBS_SubtractBG_NEW')
void = widget_button(treatmenu,value = 'Display data treatment',$
         event_pro = 'HFBS_DisplayTreatment')
;void = widget_button(treatmenu,value = 'Launch PAN',$
;         event_pro = 'HFBS_RedLaunchPAN',sensitive = 0)

void = widget_button(printmenu,value = 'Print current screen to PS file',$
         event_pro = 'HFBS_daveReducePrint')
void = widget_button(filemenu,value = 'Dismiss',$
         event_pro = 'HFBS_daveReduceDismiss')
normtypes = ['monitor', 'vanadium','peak value to one']
normgroup = cw_bgroup(base, normtypes, /col, /nonexclusive,$
                   label_top='Selection',/no_release,$
                   frame=1,set_value=0,/return_index)
groupSlider = widget_slider(base,title='Group',value = 1,maximum = 20,$
                     minimum = 1,event_pro='hfbs_daveReduceChangeGroup')

winxsize = 400 & winysize = 350
plotWin = widget_draw(tlb,xsize = winxsize,ysize = winysize,$
               /button_events,event_pro = 'hfbs_daveReduceDraw')

centertlb,tlb
widget_control,tlb,/realize
widget_control,plotWin,get_value = winVis
window,/free,/pixmap,xsize = winxsize,ysize = winysize
winPix = !d.window
thisArray = 0*intarr(16,16)
for i = 0,15 do begin
 thisArray[i,i] = 1
endfor
selDetPtr = ptr_new(thisArray)
state = 	{inPtr:inPtr,$
            notifyIDs:notifyIDs,$
            normgroup:normgroup,$
            plotWin:plotWin,$
            winVis:winVis,$
            winPix:winPix,$
            runFlag:runFlag,$
            groupSlider:groupSlider,$
            mouse:0B,$,
            autoscale:1,$
            xviewrange:[0.0,1.0],$
            yviewrange:[0.0,1.0],$
            xbox:[0.0,1.0],$
            ybox:[0.0,1.0],$
            xPtr:xPtr,$
            yPtr:yPtr,$
            yerrPtr:yerrPtr,$
            dataoPtr:dataoPtr,$
            erroroPtr:erroroPtr,$
            title:'',$
            xoPtr:xoPtr,$
            yoPtr:yoPtr,$
         	rorig:rorig,$
         	gorig:gorig,$
         	borig:borig,$
            selDetPtr:selDetPtr}

pState = ptr_new(state)

widget_control,tlb,set_uvalue = pState,/no_copy
xmanager,'HFBS_DaveReduce',tlb,cleanup = 'HFBS_DaveReduceCleanup'
end