;###############################################################################
;
; NAME:
;  FOCUSREDUCTION__DEFINE
;
; PURPOSE:
;  See description below.
;
; CATEGORY:
;  DAVE, focus, data reduction
;
; AUTHOR:
;
;PD Dr. Philip Tregenna-Piggott,
;Laboratory for Neutron Scattering,
;ETHZ and Paul-Scherrer Institute,
;CH-5232 Villigen PSI,
;Switzerland.
;
;Tel. :+41 56 310 54 05
;Fax. :+41 56 310 29 39
;Email:philip.tregenna@psi.ch
;
;Based on the Program HFBSREDUCTION__DEFINE by:
;   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.
;
;###############################################################################
;
; NAME:
;       FOCUSREDUCTION__DEFINE
;
; PURPOSE:
;
;       This object widget program performs the data reduction steps for
;   data sets collected on the Direct Geometry TOF Spectrometer FOCUS, at SINQ, PSI.
;   This program is meant to run in the DAVE environment.
;
; AUTHOR:
;
;PD Dr. Philip Tregenna-Piggott,
;Laboratory for Neutron Scattering,
;ETHZ and Paul-Scherrer Institute,
;CH-5232 Villigen PSI,
;Switzerland.
;
;Tel. :+41 56 310 54 05
;Fax. :+41 56 310 29 39
;Email:philip.tregenna@psi.ch
;
; CATEGORY:
;
;       Objects, widgets, data reduction, DAVE software
;
; CALLING SEQUENCE:
;
;       object = obj_new('focusreduction')
;
;
; INPUT PARAMETERS:
;
;       NONE
;
; INPUT KEYWORDS:
;
;   GROUP_LEADER   - Parent widget of FOCUSREDUCTION object widget
;   NOTIFYID    - Vector of TOP and ID of calling widget
;   WORKDIR      - working directory, where DAVE and/or CON files will be put
;   DATDIR      - data directory, directory of raw data
;
; REQUIRED PROGRAMS:
;
;        DREBIN.PRO
;    OPAN_Q_REBIN_WIDGET.PRO
;   opan_rebin_FOCUS_Energy_widget.pro
;   opan_time_rebin_widget.pro
;   focusDetGroupWidget.pro
;   Graphical_Masking.pro
;   Scroll_Spectra_Masking.pro
;   PlotDiffractionData.pro
;
;
; COMMON BLOCKS:
;
;       NONE
;
; RESTRICTIONS
;
;       NONE
;
; OBJECT METHODS:
;
; There are no explicitly private object methods in IDL but the
; methods used in this class are divided into PUBLIC and PRIVATE
; to indicate which ones should be used by users who wish to run
; the program from the command line, for instance.  Execution of
; the program's controls from the command line is described in the
; example below.
;
; PUBLIC OBJECT PROCEDURE METHODS:
;
;
;
; PRIVATE OBJECT PROCEDURE METHODS:
;
;
; EXAMPLE
;
;
; MODIFICATION HISTORY:
;
;       Written by Philip Tregenna-Piggott, 23 June, 2006.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Obtain programs (Filges and Koennecke) to read in the hdf files
@napi45
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; functions not defined here must be defined in order to avoid syntax errors when called
FORWARD_FUNCTION opan_rebin_FOCUS_Energy_widget,opan_Q_rebin_widget,opan_vanCalProb_widget, $
  opan_Temperature_widget,PlotDiffractionData,Graphical_Masking

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusReductionCleanup,tlb
widget_control,tlb,get_uvalue = self
if obj_valid(self) then begin
  s = size(self->getNotifyIds())
  if s[0] ne 0 then begin
    if s[0] eq 1 then count = 0 else count = s[2]-1
    for j = 0,count do begin
      focusInfo = {focusReductionEvent,$
                            ID:(self->getNotifyIds())[0,j],$
                            Top:(self->getNotifyIds())[1,j],$
                            Handler:0l,$
                            daveFiles:self->getDaveFiles()}
      if widget_info((self->getNotifyIds())[0,j],/valid_id) then begin $
        widget_control,(self->getNotifyIds())[0,j],send_event = focusInfo
      endif
    endfor
  endif else begin
    ;obj_destroy,self
  endelse
endif
obj_destroy,self
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function focusreduction::getDaveFiles
return,self.daveFiles
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::cleanup
; First let's restore the colors
tvlct,*self.rPtr,*self.gPtr,*self.bPtr
; Now free up the pointers
ptr_free,self.odata1dPtr,self.oerror1dPtr
ptr_free,self.oxvals1DPtr,self.oyvals1DPtr
ptr_free,self.data1dPtr,self.error1dPtr
ptr_free,self.dataPtr,self.errorPtr
ptr_free,self.xvalsPtr,self.yvalsPtr
ptr_free,self.notifyIdPtr;,self.daveFiles
ptr_free,self.rPtr,self.bPtr,self.selDetPtr
ptr_free,self.pgroup_leader,self.sigFilePtr
ptr_free,self.detPtr,self.vanFilePtr,self.bgFilePtr
ptr_free,self.tempPtr,self.treatmentPtr,self.lambda_fieldPtr
ptr_free,self.Mon_tcPtr,self.Mon_cumPtr,self.headerPtr,self.instrumentPtr
ptr_free,self.titlePtr,self.gPtr,self.tof_corr_structurePtr,self.good_det1DPtr
ptr_free,self.Sample_NamePtr,self.data2dPtr,self.xvals2dPtr,self.error2dPtr
ptr_free,self.detarr2d,self.good_det2DPtr,self.distance2d,self.theta2d,self.Data2dIndexPtr
ptr_free,self.AzimutalAnglePtr

; Delete any pixmap windows
wdelete,self.winPix
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::quit,event = event
; Widget, destroy thyself
widget_control,self.tlb,/destroy
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::selSigFiles,event = event
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.hdf'],$
                               title = 'Select raw signal data file(s)',$
                               path = self.datDir, $
                               /multiple_files)
;print,'files =',files
nfiles = n_elements(files)
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,/information, $
   'At least one of the selected files is invalid')
  return
endif
*self.sigFilePtr = files
delim=path_sep()
nfiles = n_elements(files)
dispFiles = strarr(nfiles)
for i = 0,nfiles-1 do begin
  text = files[i]
  textLen = strlen(text)
;we must somehow try and recognise a standard focus file
    delimpos=strpos(text,delim,/reverse_search)
    pointpos=strpos(text,'.',/reverse_search)
    length=pointpos-delimpos-1
     if strlowcase(strmid(text,(textlen-11),1)) eq 'n' and $
  strlowcase(strmid(text,(textlen-20),5)) eq 'focus' and $
  length eq 16 then begin
    pos = textLen-10
    dispFiles[i] = strmid(text,pos,6)
  endif else begin
    dispFiles[i] =strmid(text,(delimpos+1),length)
    endelse
endfor
widget_control,self.fileText,set_value = dispFiles
;
;
;
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)

  widget_control, self.runGroup, get_value=runGroup
;if only one file selected then switch to single sample runs
if rungroup eq 1 and nfiles eq 1 then begin
rungroup=0
  widget_control, self.runGroup, set_value=runGroup
endif
      if runGroup eq 1 then filename+='++'   ;set to 'sum runs'
widget_control, self.stem1, set_value=filename
widget_control, self.diffstem1, set_value=filename

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::selSigRuns,event = event
  widget_control, self.Signal_runs, get_value=strdets
;print,'strdets =',strdets
dets=opan_selectgroups_focus_runs(strdets,group_leader = event.top)
;print,'dets =',dets

nfiles=n_elements(dets)
C=strarr(nfiles)
for i = 0,nfiles-1 do begin
C(i)=strtrim(dets(i),2)
length=strlen(C(i))
zero_add=6-length
    for j=0,zero_add-1 do begin
    C(i)='0'+C(i)
    endfor
endfor
files_short=('*'+C+'.hdf')
files=strarr(nfiles)
for i = 0, nfiles-1 do begin
  res=file_search(self.datDir,files_short(i))
  if n_elements(res) gt 1 then begin
    void = dialog_message(dialog_parent = event.top,/information, $
      'Signal Runs: Specification via file number ambiguous. Remove duplicates in raw directory.')
    return
  endif else begin
    files(i)=res
  endelse
endfor
;
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,/information, $
   'At least one of the selected files is invalid')
  return
endif
;print, 'help,Sigfiles'
;help,files
*self.sigFilePtr = files
nfiles = n_elements(files)
dispFiles = strarr(nfiles)
for i = 0,nfiles-1 do begin
  text = files[i]
  textLen = strlen(text)
  pos = textLen-10
 ; pos = textLen
    dispFiles[i] = strmid(text,pos,6)
; dispFiles[i] = files(i)
endfor
widget_control,self.fileText,set_value = dispFiles
;
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)

  widget_control, self.runGroup, get_value=runGroup
;if only one file selected then switch to single sample runs
if rungroup eq 1 and nfiles eq 1 then begin
rungroup=0
  widget_control, self.runGroup, set_value=runGroup
endif
      if runGroup eq 1 then filename+='++'   ;set to 'sum runs'
widget_control, self.stem1, set_value=filename
widget_control, self.diffstem1, set_value=filename

return

end



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::selBgFiles,event = event
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.hdf'],$
                               title = 'Select background data file(s)',$
                               path = self.datDir,$
                               /multiple_files)
nfiles = n_elements(files)
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,/information, $
   'At least one of the selected files is invalid')
  return
endif
*self.bgFilePtr = files
delim=path_sep()
nfiles = n_elements(files)
dispFiles = strarr(nfiles)
for i = 0,nfiles-1 do begin
  text = files[i]
  textLen = strlen(text)
;we must somehow try and recognise a standard focus file
     delimpos=strpos(text,delim,/reverse_search)
    pointpos=strpos(text,'.',/reverse_search)
    length=pointpos-delimpos-1
     if strlowcase(strmid(text,(textlen-11),1)) eq 'n' and $
  strlowcase(strmid(text,(textlen-20),5)) eq 'focus' and $
  length eq 16 then begin
    pos = textLen-10
    dispFiles[i] = strmid(text,pos,6)
  endif else begin
    dispFiles[i] =strmid(text,(delimpos+1),length)
    endelse
endfor

widget_control,self.bgText,set_value = dispFiles
;print, '*self.bgFilePtr =',*self.bgFilePtr
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::selEmptyRuns,event = event
  widget_control, self.Background_runs, get_value=strdets
;print,'strdets =',strdets
dets=opan_selectgroups_focus_runs(strdets)
;print,'dets =',dets

nfiles=n_elements(dets)
C=strarr(nfiles)
for i = 0,nfiles-1 do begin
C(i)=strtrim(dets(i),2)
length=strlen(C(i))
zero_add=6-length
    for j=0,zero_add-1 do begin
    C(i)='0'+C(i)
    endfor
endfor
files_short=('*'+C+'.hdf')
files=strarr(nfiles)
for i = 0, nfiles-1 do begin
  res=file_search(self.datDir,files_short(i))
  if n_elements(res) gt 1 then begin
    void = dialog_message(dialog_parent = event.top,/information, $
      'Empty Runs: Specification via file number ambiguous. Remove duplicates in raw directory.')
    return
  endif else begin
    files(i)=res
  endelse
endfor
;
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,/information, $
   'At least one of the selected files is invalid')
  return
endif
*self.bgFilePtr = files
nfiles = n_elements(files)
dispFiles = strarr(nfiles)
for i = 0,nfiles-1 do begin
  text = files[i]
  textLen = strlen(text)
  pos = textLen-10
 ; pos = textLen
    dispFiles[i] = strmid(text,pos,6)
; dispFiles[i] = files(i)
endfor
widget_control,self.bgText,set_value = dispFiles

;print, '*self.bgFilePtr =',*self.bgFilePtr
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::selVanFile,event = event
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.hdf'],$
                               title = 'Select vanadium data file(s)',$
                               path = self.datDir,$
                               /multiple_files)
nfiles = n_elements(files)
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,/error,'At least one of the selected files is invalid')
  return
endif
*self.vanFilePtr = files
delim=path_sep()
nfiles = n_elements(files)
dispFiles = strarr(nfiles)
for i = 0,nfiles-1 do begin
  text = files[i]
  textLen = strlen(text)
;we must somehow try and recognise a standard focus file
     delimpos=strpos(text,delim,/reverse_search)
    pointpos=strpos(text,'.',/reverse_search)
    length=pointpos-delimpos-1
     if strlowcase(strmid(text,(textlen-11),1)) eq 'n' and $
  strlowcase(strmid(text,(textlen-20),5)) eq 'focus' and $
  length eq 16 then begin
    pos = textLen-10
    dispFiles[i] = strmid(text,pos,6)
  endif else begin
    dispFiles[i] =strmid(text,(delimpos+1),length)
    endelse
endfor
widget_control,self.vanText,set_value = dispFiles
;print, '*self.vanFilePtr =',*self.vanFilePtr
widget_control,self.elasticGroup,set_value = 0
return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::selVanRun,event = event
  widget_control, self.Vanadium_run, get_value=strdets
;print,'strdets =',strdets
dets=opan_selectgroups_focus_runs(strdets)
;print,'dets =',dets
;help,dets
;dets=dets[0]
nfiles=n_elements(dets)
C=strarr(nfiles)
for i = 0,nfiles-1 do begin
C(i)=strtrim(dets(i),2)
length=strlen(C(i))
zero_add=6-length
    for j=0,zero_add-1 do begin
    C(i)='0'+C(i)
    endfor
endfor
files_short=('*'+C+'.hdf')
files=strarr(nfiles)
for i = 0, nfiles-1 do begin
  res=file_search(self.datDir,files_short(i))
  if n_elements(res) gt 1 then begin
    void = dialog_message(dialog_parent = event.top,/information, $
      'Vanadium Runs: Specification via file number ambiguous. Remove duplicates in raw directory.')
    return
  endif else begin
    files(i)=res
  endelse 
endfor
;
if (1.0*total(file_test(files,/regular)) ne nfiles) then begin
  void = dialog_message(dialog_parent = event.top,/information, $
   'At least one of the selected files is invalid')
  return
endif
;print, 'help,Vfiles'
;help,files
;files=files[0]
*self.vanFilePtr = files
nfiles = n_elements(files)
dispFiles = strarr(nfiles)
for i = 0,nfiles-1 do begin
  text = files[i]
  textLen = strlen(text)
  pos = textLen-10
 ; pos = textLen
    dispFiles[i] = strmid(text,pos,6)
; dispFiles[i] = files(i)
endfor
widget_control,self.vanText,set_value = dispFiles
;
;
widget_control,self.elasticGroup,set_value = 0
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function focusreduction::getnotifyIds
return,*self.notifyIdPtr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusReductionEvents,event
if dave_set_focus(event) then return
if tag_names(event,/structure_name) eq 'WIDGET_BASE' then begin
  widget_control,event.top,get_uvalue = self
  self->resize,event = event
  return
endif
widget_control,event.id,get_uvalue = cmd
call_method,cmd.method,cmd.object,event = event
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::plotData,event = event
if n_elements(*self.dataPtr) eq 0 then return
widget_control,self.grpSlider,get_value = val
if (size(*self.dataPtr))[0] eq 1 then val = 1
if val gt (size(*self.dataPtr))[2] then return
;print,'val =',val
;print,'(size(*self.dataPtr))[2] =',(size(*self.dataPtr))[2]
;val = fix(val[0])
z = reform((*self.dataPtr)[*,val-1])
zerr = reform((*self.errorPtr)[*,val-1])
x = (*self.xvalsPtr)
y = (*self.yvalsPtr)[val-1]
;print,'x =',x
;print,''
;print,'y =',y
;print,''
;print,'z =',z
;print,''
if self.autoscale eq 1 then begin
  self.xrange = [min(x),max(x)]
  dz = 0.1*(max(z)-min(z))
  self.yrange = [min(z)-max(zerr)-dz, $
                 max(z)+max(zerr)+dz]
endif
;print,self.xrange
;print,''
;print,self.yrange
;
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
;
;
if y eq 0 then begin
title=strtrim((*self.InstrumentPtr).sample,2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Sum Over All Detectors'
endif else begin
    if DataOutput eq 0 then begin
    title=strtrim((*self.InstrumentPtr).sample,2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Q = '+strtrim(string(y),2)
    endif else begin
    title=strtrim((*self.InstrumentPtr).sample,2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Phi Group = '+strtrim(string(val),2)
    endelse
endelse

;print,'self.NormFactor: ',self.NormFactor
;
purged=where(z ne (-1.0/self.NormFactor),count)
if count ne 0 then begin
xpurge=x[purged]
zpurge=z[purged]
zerrpurge=zerr[purged]
plot,xpurge,zpurge,psym = 4,xrange = self.xrange,yrange = self.yrange, $
     xstyle = 1,ystyle = 1,xtitle = self.xlabel, ytitle = self.zlabel, title = title
errplot,xpurge,zpurge-zerrpurge,zpurge+zerrpurge,width = 0.0
endif else begin
plot,x,z,psym = 4,xrange = self.xrange,yrange = self.yrange, $
     xstyle = 1,ystyle = 1,xtitle = self.xlabel, ytitle = self.zlabel, title = title
errplot,x,z-zerr,z+zerr,width = 0.0
endelse
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::doNothing,event = event
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::ebinning,event = event
widget_control,self.DataOutputTypesGroup,get_value = DataOutputType
; DataOutputType 0 S(Q,w)
; DataOutputType 1 S(theta,w)
; DataOutputType 2 S(theta,t)
if DataOutputType ne 2 then begin
self.xlabel = 'Energy / meV'
endif else begin
self.xlabel = 'Time / microseconds'
endelse
self.units=0
;   is energy binning requested?
widget_control,self.ebin_Group,get_value = thisValue
if thisValue[0] eq 0 then return
if n_elements(*self.dataPtr) eq 0 then return
data = *self.dataPtr
error = *self.errorPtr
x = *self.xvalsPtr
;help,data
;help,error
widget_control,self.ebin_Group1,get_value = ebin_command
;   modify default(0), use previous(1), modify previous(2)
IF DataOutputType ne 2 then begin
;   modify default(0), use previous(1), modify previous(2)
if ebin_command eq 0 then begin
;
total_bins=n_elements(x)
;print,'total_bins =',total_bins
;if min(x) lt -50.0 then begin
;nb_xlo=-50.0
;xtemp=x(where(x ge min(x)) and where(x lt -50.0))
;total_bins-=n_elements(xtemp)
;x=x[n_elements(xtemp):*]
;print,n_elements(x)
;endif else begin
;nb_xlo=min(x)
;endelse
nb_xlo=min(x)
;print,'total_bins =',total_bins
nb_xhi=-max(x)
;print,'x: ',x
;print,'min(x): ',min(x)
;print,'max(x): ',max(x)
;print,'-max(x): ',-max(x)
b_xlo=nb_xhi
b_xhi=max(x)
xtemp=x[where(x lt nb_xhi)]
;print,nb_xlo
;print,nb_xhi
;
;help,xtemp
;print,xtemp
nb_nbins=n_elements(xtemp)
;
;step=x[nb_nbins]-x[nb_nbins-1]
;b_nbins=long(((b_xhi-b_xlo)/step)+1)
;
b_nbins=fix(total_bins-nb_nbins)
step=(b_xhi-b_xlo)/(b_nbins-1)

;   find interpolated range
;    print,count
;    print,(nb_nbins+1)
;    print,n_elements(x)
    ix=x[nb_nbins-1:total_bins-1]
;ix=x[(nb_nbins+1):*]
ix_plus=ix[1:*]
ix_minus=ix[0:(n_elements(ix)-1)]
ix_diff=ix_plus-ix_minus
;print,ix_diff
u=1+bytarr(n_elements(ix_diff))
ustep=step*u
where_int=where(ix_diff gt ustep,count)
;print,'where_int =',where_int
;print,'where_int + 1 =',where_int+1
if count ge 1 then begin
;help,ix
ix=[ix[0],ix[(where_int+1)]]
;help,ix
i_xlo=b_xlo
i_xhi=max(ix)
i_nbins=round((step+i_xhi-i_xlo)/step)
endif else begin
i_nbins=0
i_xlo=b_xlo
i_xhi=b_xlo
endelse
range=1
unit=0
;help,step
;ebin = opan_rebin_widget(x,group_leader = event.top)

;help,x
;print,x

ebin = opan_rebin_FOCUS_Energy_widget(x,nb_xlo=nb_xlo,nb_xhi=nb_xhi,nb_nbins=nb_nbins, $
                    b_xlo=b_xlo,b_xhi=b_xhi,b_nbins=b_nbins,step=step, $
                    i_xlo=i_xlo,i_xhi=i_xhi,i_nbins=i_nbins, total_bins=total_bins, $
                    range=range,unit=unit,group_leader = event.top)
;ebin = {nb_xlo:nb_xlo,nb_xhi:nb_xhi,nb_nbins:nb_nbins,b_xlo:b_xlo,b_xhi:b_xhi,b_nbins:b_nbins, $
;       i_xlo:i_xlo,i_xhi:i_xhi,i_nbins:i_nbins,step:step,  $
;       range:range, unit:unit, cancel:cancel}
nb_xlo=ebin.nb_xlo
nb_xhi=ebin.nb_xhi
nb_nbins=ebin.nb_nbins
b_xlo=ebin.b_xlo
b_xhi=ebin.b_xhi
b_nbins=ebin.b_nbins
step=ebin.step
i_xlo=ebin.i_xlo
i_xhi=ebin.i_xhi
i_nbins=ebin.i_nbins
total_bins=ebin.total_bins
range=ebin.range
unit=ebin.unit
cancel=ebin.cancel
;Now write the contents to a file
filename = 'ebinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,nb_xlo
printf,lun,nb_xhi
printf,lun,nb_nbins
printf,lun,b_xlo
printf,lun,b_xhi
printf,lun,b_nbins
printf,lun,step
printf,lun,i_xlo
printf,lun,i_xhi
printf,lun,i_nbins
printf,lun,total_bins
printf,lun,range
printf,lun,unit
free_lun,lun,/force
;
;print,unit
    if cancel eq 1 then return
       if unit eq 1 then begin
x*=8.06554097d
self.units=1
self.xlabel = 'Energy / Wavenumbers'
       endif
    if unit eq 2 then begin
x*=241.7989052d
self.units=2
self.xlabel = 'Energy / GHz'
    endif
    if unit eq 3 then begin
x*=0.2417989052d
self.units=3
self.xlabel = 'Energy / THz'
    endif
    if unit eq 4 then begin
x*=11.604615407811d
self.units=4
self.xlabel = 'Energy / K'
    endif
endif
;
;   option: modify previous values
if ebin_command eq 1 then begin
;check to see whether file exists
filename = 'ebinParameters.txt'
if file_test(self.workDir+filename) eq 1 then begin
filename = filepath(filename,root_dir = self.workDir)
openr,lun,filename,/get_lun
readf,lun,nb_xlo
readf,lun,nb_xhi
readf,lun,nb_nbins
readf,lun,b_xlo
readf,lun,b_xhi
readf,lun,b_nbins
readf,lun,step
readf,lun,i_xlo
readf,lun,i_xhi
readf,lun,i_nbins
readf,lun,total_bins
readf,lun,range
readf,lun,unit
free_lun,lun,/force
;help,step
;help,x
;print,x
xcall=x
if unit eq 1 then xcall*=8.06554097d
if unit eq 2 then xcall*=241.7989052d
if unit eq 3 then xcall*=0.2417989052d
if unit eq 4 then xcall*=11.604615407811d
ebin = opan_rebin_FOCUS_Energy_widget(xcall,nb_xlo=nb_xlo,nb_xhi=nb_xhi,nb_nbins=nb_nbins, $
                    b_xlo=b_xlo,b_xhi=b_xhi,b_nbins=b_nbins,step=step, $
                    i_xlo=i_xlo,i_xhi=i_xhi,i_nbins=i_nbins, total_bins=total_bins, $
                    range=range,unit=unit,group_leader = event.top)
;ebin = {nb_xlo:nb_xlo,nb_xhi:nb_xhi,nb_nbins:nb_nbins,b_xlo:b_xlo,b_xhi:b_xhi,b_nbins:b_nbins, $
;       i_xlo:i_xlo,i_xhi:i_xhi,i_nbins:i_nbins,  $
;       range:range, unit:unit, cancel:cancel}
nb_xlo=ebin.nb_xlo
nb_xhi=ebin.nb_xhi
nb_nbins=ebin.nb_nbins
b_xlo=ebin.b_xlo
b_xhi=ebin.b_xhi
b_nbins=ebin.b_nbins
;help,ebin.b_nbins

step=ebin.step
i_xlo=ebin.i_xlo
i_xhi=ebin.i_xhi
i_nbins=ebin.i_nbins
total_bins=ebin.total_bins
range=ebin.range
unit=ebin.unit
cancel=ebin.cancel
;Now write the contents to a file
filename = 'ebinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,nb_xlo
printf,lun,nb_xhi
printf,lun,nb_nbins
printf,lun,b_xlo
printf,lun,b_xhi
printf,lun,b_nbins
printf,lun,step
printf,lun,i_xlo
printf,lun,i_xhi
printf,lun,i_nbins
printf,lun,total_bins
printf,lun,range
printf,lun,unit
free_lun,lun,/force
;
;print,ebin.unit
    if cancel eq 1 then return
       if unit eq 1 then begin
x*=8.06554097d
self.units=1
self.xlabel = 'Energy / Wavenumbers'
       endif
if unit eq 2 then begin
x*=241.7989052d
self.units=2
self.xlabel = 'Energy / GHz'
    endif
    if unit eq 3 then begin
x*=0.2417989052d
self.units=3
self.xlabel = 'Energy / THz'
    endif
    if unit eq 4 then begin
x*=11.604615407811d
self.units=4
self.xlabel = 'Energy / K'
    endif
endif else begin
message=string('THE FILE '+self.workDir+'ebinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
;help,message
msg=message
;help,msg
;msg = 'THE FILE "ebinParameters.txt" HAS NOT BEEN FOUND.  REVERTING TO DEFAULT '
;help,msg
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb
;if the file does not exist then revert to default
total_bins=n_elements(x)
nb_xlo=min(x)
nb_xhi=-max(x)
b_xlo=nb_xhi
b_xhi=max(x)
xtemp=x[where(x lt nb_xhi)]
nb_nbins=n_elements(xtemp)
b_nbins=fix(total_bins-nb_nbins)
step=(b_xhi-b_xlo)/(b_nbins-1)

;   find interpolated range
    ix=x[nb_nbins-1:total_bins-1]
ix_plus=ix[1:*]
ix_minus=ix[0:(n_elements(ix)-1)]
ix_diff=ix_plus-ix_minus
u=1+bytarr(n_elements(ix_diff))
ustep=step*u
where_int=where(ix_diff gt ustep,count)
if count ge 1 then begin
ix=[ix[0],ix[(where_int+1)]]
i_xlo=b_xlo
i_xhi=max(ix)
i_nbins=round((step+i_xhi-i_xlo)/step)
endif else begin
i_nbins=0
i_xlo=b_xlo
i_xhi=b_xlo
endelse
range=1
unit=0
ebin = opan_rebin_FOCUS_Energy_widget(x,nb_xlo=nb_xlo,nb_xhi=nb_xhi,nb_nbins=nb_nbins, $
                    b_xlo=b_xlo,b_xhi=b_xhi,b_nbins=b_nbins,step=step, $
                    i_xlo=i_xlo,i_xhi=i_xhi,i_nbins=i_nbins, total_bins=total_bins, $
                    range=range,unit=unit,group_leader = event.top)
nb_xlo=ebin.nb_xlo
nb_xhi=ebin.nb_xhi
nb_nbins=ebin.nb_nbins
b_xlo=ebin.b_xlo
b_xhi=ebin.b_xhi
b_nbins=ebin.b_nbins
step=ebin.step
i_xlo=ebin.i_xlo
i_xhi=ebin.i_xhi
i_nbins=ebin.i_nbins
total_bins=ebin.total_bins
range=ebin.range
unit=ebin.unit
cancel=ebin.cancel
;Now write the contents to a file
filename = 'ebinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,nb_xlo
printf,lun,nb_xhi
printf,lun,nb_nbins
printf,lun,b_xlo
printf,lun,b_xhi
printf,lun,b_nbins
printf,lun,step
printf,lun,i_xlo
printf,lun,i_xhi
printf,lun,i_nbins
printf,lun,total_bins
printf,lun,range
printf,lun,unit
free_lun,lun,/force
;
    if cancel eq 1 then return
       if unit eq 1 then begin
x*=8.06554097d
self.units=1
self.xlabel = 'Energy / Wavenumbers'
       endif
if unit eq 2 then begin
x*=241.7989052d
self.units=2
self.xlabel = 'Energy / GHz'
    endif
    if unit eq 3 then begin
x*=0.2417989052d
self.units=3
self.xlabel = 'Energy / THz'
    endif
    if unit eq 4 then begin
x*=11.604615407811d
self.units=4
self.xlabel = 'Energy / K'
    endif
endelse
endif

;
if ebin_command eq 2 then begin

;check to see whether file exists
filename = 'ebinParameters.txt'
if file_test(self.workDir+filename) eq 1 then begin
filename = filepath(filename,root_dir = self.workDir)
openr,lun,filename,/get_lun
readf,lun,nb_xlo
readf,lun,nb_xhi
readf,lun,nb_nbins
readf,lun,b_xlo
readf,lun,b_xhi
readf,lun,b_nbins
readf,lun,step
readf,lun,i_xlo
readf,lun,i_xhi
readf,lun,i_nbins
readf,lun,total_bins
readf,lun,range
readf,lun,unit
free_lun,lun,/force
;
nb_nbins=fix(nb_nbins)
b_nbins=fix(b_nbins)
i_nbins=fix(i_nbins)
range=fix(range)
unit=fix(unit)
;
       if unit eq 1 then begin
x*=8.06554097
self.units=1
self.xlabel = 'Energy / Wavenumbers'
       endif
if unit eq 2 then begin
x*=241.7989052d
self.units=2
self.xlabel = 'Energy / GHz'
    endif
    if unit eq 3 then begin
x*=0.2417989052d
self.units=3
self.xlabel = 'Energy / THz'
    endif
    if unit eq 4 then begin
x*=11.604615407811d
self.units=4
self.xlabel = 'Energy / K'
    endif
endif else begin
;revert to default
message=string('THE FILE '+self.workDir+'ebinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
msg=message
;help,msg
;msg = 'THE FILE "ebinParameters.txt" HAS NOT BEEN FOUND.  REVERTING TO DEFAULT '
;help,msg
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb
;if the file does not exist then revert to default
total_bins=n_elements(x)
nb_xlo=min(x)
nb_xhi=-max(x)
b_xlo=nb_xhi
b_xhi=max(x)
xtemp=x[where(x lt nb_xhi)]
nb_nbins=n_elements(xtemp)
b_nbins=fix(total_bins-nb_nbins)
step=(b_xhi-b_xlo)/(b_nbins-1)

;   find interpolated range
    ix=x[nb_nbins-1:total_bins-1]
ix_plus=ix[1:*]
ix_minus=ix[0:(n_elements(ix)-1)]
ix_diff=ix_plus-ix_minus
u=1+bytarr(n_elements(ix_diff))
ustep=step*u
where_int=where(ix_diff gt ustep,count)
if count ge 1 then begin
ix=[ix[0],ix[(where_int+1)]]
i_xlo=b_xlo
i_xhi=max(ix)
i_nbins=round((step+i_xhi-i_xlo)/step)
endif else begin
i_nbins=0
i_xlo=b_xlo
i_xhi=b_xlo
endelse
range=1
unit=0
ebin = opan_rebin_FOCUS_Energy_widget(x,nb_xlo=nb_xlo,nb_xhi=nb_xhi,nb_nbins=nb_nbins, $
                    b_xlo=b_xlo,b_xhi=b_xhi,b_nbins=b_nbins,step=step, $
                    i_xlo=i_xlo,i_xhi=i_xhi,i_nbins=i_nbins, total_bins=total_bins, $
                    range=range,unit=unit,group_leader = event.top)
nb_xlo=ebin.nb_xlo
nb_xhi=ebin.nb_xhi
nb_nbins=ebin.nb_nbins
b_xlo=ebin.b_xlo
b_xhi=ebin.b_xhi
b_nbins=ebin.b_nbins
step=ebin.step
i_xlo=ebin.i_xlo
i_xhi=ebin.i_xhi
i_nbins=ebin.i_nbins
total_bins=ebin.total_bins
range=ebin.range
unit=ebin.unit
cancel=ebin.cancel
;Now write the contents to a file
filename = 'ebinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,nb_xlo
printf,lun,nb_xhi
printf,lun,nb_nbins
printf,lun,b_xlo
printf,lun,b_xhi
printf,lun,b_nbins
printf,lun,step
printf,lun,i_xlo
printf,lun,i_xhi
printf,lun,i_nbins
printf,lun,total_bins
printf,lun,range
printf,lun,unit
free_lun,lun,/force
;
    if cancel eq 1 then return
       if unit eq 1 then begin
x*=8.06554097d
self.units=1
self.xlabel = 'Energy / Wavenumbers'
       endif
if unit eq 2 then begin
x*=241.7989052d
self.units=2
self.xlabel = 'Energy / GHz'
    endif
    if unit eq 3 then begin
x*=0.2417989052d
self.units=3
self.xlabel = 'Energy / THz'
    endif
    if unit eq 4 then begin
x*=11.604615407811d
self.units=4
self.xlabel = 'Energy / K'
    endif
endelse
endif
;print,ebin
;print,tag_names(ebin)
;datSize = size(data)
;nx = datSize[1]
;if ebin_structure.nbins gt nx then begin
;  strout = 'Number of desired bins cannot exceed the number of input bins'
;  void = dialog_message(dialog_parent = event.top,strout)
;  return
;endif

case range of
0: begin
;   include all data, only a part of which is to be binned
;   find data not to be binned
        where_x_lt_nb_xhi=where(x lt nb_xhi,count)
;       print,where_x_lt_nb_xhi
;       print,n_elements(where_x_lt_nb_xhi)
        if count ge 1 then begin
        xnb1=x[where_x_lt_nb_xhi]
       xnb=x[where(xnb1 ge nb_xlo)]
       nodata_count=where(x lt nb_xlo,count)
    ; numerical bug fix
       if fix(nb_xlo) eq fix(min(x)) then begin
       count = -1
       xnb=xnb1
       endif
;       print,count
;       print,'min xnb =',min(xnb)
;       print,'nodata =',nodata
;       print,'min(x) =',min(x)
;       print,'nb_xlo =',nb_xlo
         if count lt 0 then begin
 ;        print,'count =',count
        datanb=data[0:n_elements(xnb)-1,*]
        errornb=error[0:n_elements(xnb)-1,*]
            endif else begin
        datanb=data[0+count:n_elements(xnb)-1+count,*]
        errornb=error[0+count:n_elements(xnb)-1+count,*]
           endelse
        endif
       xlo = b_xlo & xhi = b_xhi
       nbins = b_nbins
 ;      dx = (xhi-xlo)/(nbins-1.0)
       dx=step
       x_out = xlo+dx*dindgen(nbins)
;      print, 'total =',n_elements(x_out)+n_elements(xnb)+n_elements(nodata)
    end
1: begin
;   include only binned data,
       xlo = b_xlo & xhi = b_xhi
       nbins = b_nbins
 ;      dx = (xhi-xlo)/(nbins-1.0)
       dx=step
       x_out = xlo+dx*dindgen(nbins)
    end
2: begin
;   include only binned data, exclude interpolated region
        x_out = b_xlo+step*dindgen(b_nbins)
        xlo = i_xhi & xhi = b_xhi
       nbins = b_nbins-i_nbins
       x_out=x_out[where(x_out ge xlo)]
  ;     dx = (xhi-xlo)/(nbins-1.0)
 ;     print,'step =',step
 ;     print,'xlo =',xlo
 ;     print,'xhi =',xhi
 ;     print,'nbins =',nbins
 ;     print,'x_out =',x_out
end
else:
endcase
;
;
;
;
oxrange = '('+strtrim(string(min(x)),2)+','+strtrim(string(max(x)),2)+')'
xrange = '('+strtrim(string(xlo),2)+','+strtrim(string(xhi),2)+')'
if self.units eq 0 then ustring='Energy Units = meV'
if self.units eq 1 then ustring='Energy Units = wavenumbers'
if self.units eq 2 then ustring='Energy Units = GHz'
if self.units eq 3 then ustring='Energy Units = THz'
if self.units eq 4 then ustring='Energy Units = K'
treat = ['data have been rebinned in Energy.', $
        'Old bins:'+strtrim(string(n_elements(x)),2), $
       ustring, $
        'Old Energy-range: '+oxrange, $
        'New bins:'+strtrim(string(nbins),2), $
        'New Energy-range: ',xrange]
*self.treatmentPtr = [*self.treatmentPtr,treat]
;print, nb_nbins
;print, n_elements(xnb)
;print,''
;print, b_nbins
;print, n_elements(xb)

;oxrange = '('+strtrim(string(min(x)),2)+','+strtrim(string(max(x)),2)+')'
;xrange = '('+strtrim(string(xlo),2)+','+strtrim(string(xhi),2)+')'
;treat = ['data has been rebinned in energy.', $
;        'Old bins:'+strtrim(string(nx),2), $
;        'Old x-range: '+oxrange, $
;        'New bins:'+strtrim(string(nbins),2), $
;        'New x-range: ',xrange]
;*self.treatmentPtr = [*self.treatmentPtr,treat]

; Ok, we've done the error checking...now do the rebinning
;
drebin,x,data,error,x_out,z_out,dz_out, $
    /points,/to_points,err=err,emsg=emsg
;print, 'energy binning'
;help,x
;help,data
;help,error
;help,x_out
;help,z_out
;help,dz_out

print,emsg
if err ne 0 then return

if n_elements(datanb) ne 0 then begin
;print,'n_elements(datanb) =',n_elements(datanb)
z=[datanb,z_out]
dz=[errornb,dz_out]
x=[xnb,x_out]
endif else begin
z=z_out
dz=dz_out
x=x_out
endelse
;
;
*self.dataPtr=z
*self.errorPtr=dz
*self.xvalsPtr=x

;print,z[800,0]
if ebin_command eq 0 then widget_control,self.ebin_group1,set_value = 1 ; as requested by Thierry and Fanni

ENDIF ELSE BEGIN
; the user wishes S(theta,t)
self.units=5
nx=n_elements(x)

if ebin_command eq 0 then begin

tmin=min(x, max = tmax)
ntbins=nx
step=(tmax-tmin)/(ntbins)
time_structure = opan_time_rebin_widget(tmin,tmax,ntbins,step,x,group_leader = event.top)
;out = {tmin:thmin,tmax:thmax,step:step,ntbins:ntbins,cancel:1}
  if time_structure.cancel eq 1 then return
tmin = time_structure.tmin & tmax = time_structure.tmax
ntbins = time_structure.ntbins
step=time_structure.step
;write the contents to a file
filename = 'tbinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,tmin
printf,lun,tmax
printf,lun,ntbins
printf,lun,step
free_lun,lun,/force
;
endif

if ebin_command eq 1 then begin

filename = 'tbinParameters.txt'
    if file_test(self.workDir+filename) eq 1 then begin
filename = filepath(filename,root_dir = self.workDir)
openr,lun,filename,/get_lun
readf,lun,tmin
readf,lun,tmax
readf,lun,ntbins
readf,lun,step
free_lun,lun,/force
ntbins=fix(ntbins)


    endif else begin
;revert to default
message=string('THE FILE '+self.workDir+'tbinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
msg=message
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb

tmin=min(x, max = tmax)
ntbins=nx
step=(tmax-tmin)/(ntbins)
    endelse
time_structure = opan_time_rebin_widget(tmin,tmax,ntbins,step,x,group_leader = event.top)
;out = {tmin:thmin,tmax:thmax,step:step,ntbins:ntbins,cancel:1}
  if time_structure.cancel eq 1 then return
tmin = time_structure.tmin & tmax = time_structure.tmax
ntbins = time_structure.ntbins
step=time_structure.step
;write the contents to a file
filename = 'tbinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,tmin
printf,lun,tmax
printf,lun,ntbins
printf,lun,step
free_lun,lun,/force
;
endif


if ebin_command eq 2 then begin

filename = 'tbinParameters.txt'
    if file_test(self.workDir+filename) eq 1 then begin
filename = filepath(filename,root_dir = self.workDir)
openr,lun,filename,/get_lun
readf,lun,tmin
readf,lun,tmax
readf,lun,ntbins
readf,lun,step
free_lun,lun,/force
ntbins=fix(ntbins)


    endif else begin
;revert to default
message=string('THE FILE '+self.workDir+'tbinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
msg=message
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb

tmin=min(x, max = tmax)
ntbins=nx
step=(tmax-tmin)/(ntbins)
time_structure = opan_time_rebin_widget(tmin,tmax,ntbins,step,x,group_leader = event.top)
;out = {tmin:thmin,tmax:thmax,step:step,ntbins:ntbins,cancel:1}
  if time_structure.cancel eq 1 then return
tmin = time_structure.tmin & tmax = time_structure.tmax
ntbins = time_structure.ntbins
step=time_structure.step
;write the contents to a file
filename = 'tbinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,tmin
printf,lun,tmax
printf,lun,ntbins
printf,lun,step
free_lun,lun,/force
    endelse
;
endif


oxrange = '('+strtrim(string(min(x)),2)+','+strtrim(string(max(x)),2)+')'
xrange = '('+strtrim(string(tmin),2)+','+strtrim(string(tmax),2)+')'
treat = ['data have been rebinned in time.', $
        'Old bins:'+strtrim(string(nx),2), $
        'Old time-range: '+oxrange, $
        'New bins:'+strtrim(string(ntbins),2), $
        'New time-range: ',xrange]
*self.treatmentPtr = [*self.treatmentPtr,treat]



 tbins=tmin+step/2.0
 tbins_arr=tbins
    while tbins lt (tmax-step*1.49999) do begin
    tbins+=step
    tbins_arr=[tbins_arr,tbins]
    endwhile
;print,'tbins_arr =',tbins_arr
;print,ntbins
;ntbins=n_elements(tbins_arr) ; just in case


  drebin,x,data,error,tbins_arr,z_out,dz_out,/points,/to_points, $
     err = err,emsg = emsg
;
;
*self.dataPtr=z_out
*self.errorPtr=dz_out
*self.xvalsPtr=tbins_arr

if ebin_command eq 0 then widget_control,self.ebin_group1,set_value = 1 ; as requested by Thierry and Fanni

ENDELSE


;print,n_elements(x)
;print,b_nbins+nb_nbins
;help,data
;help,error
;help,z_out
;help,dz_out
;help,x_out

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::qbinning,event = event
z = *self.dataPtr
dz = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
; is the data to be output in spe format
widget_control,self.FormatTypesGroup,get_value = vals
if vals eq 3 then begin
msg=string('SPE Output Format Requested.  No Q-Grouping Shall Be Performed')
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb

mindz=min(dz[where(dz gt 0)])
;print,'mindz =',mindz
wherezero=where(dz eq 0,count)
if count ne 0 then dz(wherezero)=mindz
*self.dataPtr=z
*self.errorPtr=dz
return
endif


;print, 'self.ndet passed =',self.ndet
;   sum all or re-bin
widget_control,self.Qbin_Group,get_value = thisValue
    if thisValue[0] eq 0 then begin
    ;sum all
;print,'lambda0 = ',lambda0
;print,'min(*self.yvalsPtr) =',min(*self.yvalsPtr)
;print,'max(*self.yvalsPtr) =',max(*self.yvalsPtr)
 z=total(z,2)
dz=sqrt(total(dz^2,2))
;print,'total(dz) quick =',total(dz)
;

;
;print,'count =',count
wheregtzero=where(dz gt 0,count)
if count ne 0 then begin
mindz=min(dz[wheregtzero])
wherezero=where(dz eq 0,count)
if count ne 0 then dz(wherezero)=mindz
endif
;print,'count =',count
y=0.0
signdet=1
*self.dataPtr=z
*self.errorPtr=dz
*self.yvalsPtr=y
;*self.xvalsPtr*=241.7989052
self.ndet=signdet
;print,'(size(*self.dataPtr))[2] =',(size(*self.dataPtr))[2]
;print,'(size(sigData))[2] =',(size(sigData))[2]
;print,'(size(sigData))[2] =',(size(sigData))[2]
return
 endif

widget_control,self.qbin_Group1,get_value = qbin_command
;   modify default(0), use previous(1), modify previous(2)
;should the output be S(Q,w) , S(theta,w) or  S(theta,t)
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
IF DataOutput eq 0 then begin ; convert to Q and re-bin
;wherezero=where(dz eq 0,count)
;if count ne 0 then dz(wherezero)=1.0
;*self.errorPtr=dz
;*self.dataPtr=z
;*self.xvalsPtr=x
;*self.yvalsPtr=y
;return
;print,min(y) & print,max(y)
signdet=self.ndet

;help,signdet

tof_corr_structure=*self.tof_corr_structurePtr
lambda0=tof_corr_structure.lambdatof
;print,'lambda0 =',lambda0

ny=n_elements(y)
nx=n_elements(x)
uy = 1+bytarr(ny)
ux = 1+bytarr(nx)
phimat = double(ux#y)
;converts wavelength to energy in meV
k0=2.0d*!dpi/lambda0
;print,'k0 =',k0
;1 meV = 2.072099427*k^2
alpha=2.072099427d
E0=81.80320651d/lambda0^2
if self.units eq 1 then begin
E0*=8.06554097d
alpha*=8.06554097d
endif
if self.units eq 2 then begin
E0*=241.7989052d
alpha*=241.7989052d
endif
if self.units eq 3 then begin
E0*=0.2417989052d
alpha*=0.2417989052d
endif
if self.units eq 4 then begin
E0*=11.604615407811d
alpha*=11.604615407811d
endif


;as given by Craig
;qmat = sqrt((2.0*eo-xmat-2.0*sqrt(eo*(eo-xmat))*cos(phimat*!dtor))/alpha)
;
;as adapted by Philip
;
xmat = double(x#uy)
qmat = sqrt((2.0d*E0-xmat-2.0d*sqrt(E0*(E0-xmat))*cos(phimat*!dtor))/alpha)

    if qbin_command eq 0 then begin; modify default
qmin = min(qmat,max = qmax)
nqbins=5
step=(qmax-qmin)/(nqbins)
      daveDeSensitizeButtons,event

qbin_structure = opan_Q_rebin_widget(lambda0,qmin,qmax,nqbins,step,group_leader = event.top)
      daveSensitizeButtons,event
;qbin_structure = {qmin:qmin,qmax:qmax,step:step,nqbins:nqbins,cancel:1}

         if qbin_structure.cancel eq 1 then begin
; if cancel then some over detectors
 z=total(z,2)
dz=sqrt(total(dz^2,2))

wheregtzero=where(dz gt 0,count)
if count ne 0 then begin
mindz=min(dz[wheregtzero])
wherezero=where(dz eq 0,count)
if count ne 0 then dz(wherezero)=mindz
endif

y=0.0
signdet=1
*self.dataPtr=z
*self.errorPtr=dz
*self.yvalsPtr=y
return
       endif
;print,qbin_structure
;
qmin=qbin_structure.qmin
qmax=qbin_structure.qmax
step=qbin_structure.step
nqbins=qbin_structure.nqbins
;   write the contents to a file
filename = 'QbinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,qmin
printf,lun,qmax
printf,lun,nqbins
printf,lun,step
free_lun,lun,/force
    endif
;
;
;
    if qbin_command eq 1 then begin; modify previous
filename = 'QbinParameters.txt'
    if file_test(self.workDir+filename) eq 1 then begin
filename = filepath(filename,root_dir = self.workDir)
openr,lun,filename,/get_lun
readf,lun,qmin
readf,lun,qmax
readf,lun,nqbins
readf,lun,step
free_lun,lun,/force
nqbins=fix(nqbins)
    endif else begin
;revert to default
message=string('THE FILE '+self.workDir+'QbinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
msg=message
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb
qmin = min(qmat,max = qmax)
nqbins=5
step=(qmax-qmin)/(nqbins)
    endelse
daveDeSensitizeButtons,event
qbin_structure = opan_Q_rebin_widget(lambda0,qmin,qmax,nqbins,step,group_leader = event.top)
daveSensitizeButtons,event
;qbin_structure = {qmin:qmin,qmax:qmax,step:step,nqbins:nqbins,cancel:1}
         if qbin_structure.cancel eq 1 then begin
; if cancel then some over detectors
 z=total(z,2)
dz=sqrt(total(dz^2,2))


wheregtzero=where(dz gt 0,count)
if count ne 0 then begin
mindz=min(dz[wheregtzero])
wherezero=where(dz eq 0,count)
if count ne 0 then dz(wherezero)=mindz
endif



y=0.0
signdet=1
*self.dataPtr=z
*self.errorPtr=dz
*self.yvalsPtr=y
return
       endif
;
qmin=qbin_structure.qmin
qmax=qbin_structure.qmax
step=qbin_structure.step
nqbins=qbin_structure.nqbins
;   write the contents to a file
filename = 'QbinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,qmin
printf,lun,qmax
printf,lun,nqbins
printf,lun,step
free_lun,lun,/force
    endif

    if qbin_command eq 2 then begin; use previous
filename = 'QbinParameters.txt'
    if file_test(self.workDir+filename) eq 1 then begin
filename = filepath(filename,root_dir = self.workDir)
openr,lun,filename,/get_lun
readf,lun,qmin
readf,lun,qmax
readf,lun,nqbins
readf,lun,step
free_lun,lun,/force
nqbins=fix(nqbins)
    endif else begin
;revert to default
message=string('THE FILE '+self.workDir+'QbinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
msg=message
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb
qmin = min(qmat,max = qmax)
nqbins=5
step=(qmax-qmin)/(nqbins)
      daveDeSensitizeButtons,event
qbin_structure = opan_Q_rebin_widget(lambda0,qmin,qmax,nqbins,step,group_leader = event.top)
      daveSensitizeButtons,event
qmin=qbin_structure.qmin
qmax=qbin_structure.qmax
step=qbin_structure.step
nqbins=qbin_structure.nqbins
filename = 'QbinParameters.txt'
filename = filepath(filename,root_dir = self.workDir)
openw,lun,filename,/get_lun
printf,lun,qmin
printf,lun,qmax
printf,lun,nqbins
printf,lun,step
free_lun,lun,/force
;qbin_structure = {qmin:qmin,qmax:qmax,step:step,nqbins:nqbins,cancel:1}
         if qbin_structure.cancel eq 1 then begin
; if cancel then some over detectors
 z=total(z,2)
dz=sqrt(total(dz^2,2))
mindz=min(dz[where(dz gt 0)])
;print,'mindz =',mindz
wherezero=where(dz eq 0,count)
if count ne 0 then dz(wherezero)=mindz
;print,'count =',count
;
y=0.0
signdet=1
*self.dataPtr=z
*self.errorPtr=dz
*self.yvalsPtr=y
return
       endif
    endelse
;
;   write the contents to a file
    endif
;
;
;
 qbins=qmin+step/2.0
 qbins_arr=qbins
    while qbins lt (qmax-step*1.49999) do begin
    qbins+=step
    qbins_arr=[qbins_arr,qbins]
    endwhile
;print,'qbins_arr =',qbins_arr
;print,nqbins
nqbins=n_elements(qbins_arr) ; just in case
;print,nqbins

if nqbins eq 1 then begin
 z=total(z,2)
dz=sqrt(total(dz^2,2))
wheregtzero=where(dz gt 0,count)
if count ne 0 then begin
mindz=min(dz[wheregtzero])
wherezero=where(dz eq 0,count)
if count ne 0 then dz(wherezero)=mindz
endif
y=0.0
signdet=1
*self.dataPtr=z
*self.errorPtr=dz
*self.yvalsPtr=y
self.ndet=signdet
return

endif




;qmin=qbin_structure.qmin
;qmax=qbin_structure.qmax
;nqbins=qbin_structure.nqbins
;
;print,'qmin =',qmin
;print,'qmax =',qmax
;print,'nqbins =',nqbins
;uq = 1+bytarr(nqbins)
;dq = (qmax-qmin)/(nqbins)
;qbins = qmin+dq/2.0+dq*findgen(nqbins)
;print,qbins
;
dataReb = fltarr(nx,nqbins)
errReb = fltarr(nx,nqbins)
;
;do the same for the actual values....
;
;help,z
;help,dz
;help,nx
;help,qmat
; Now do the rebinning in Q

for i = 0,nx-1 do begin
  z_in = reform(z[i,*])
  dz_in = reform(dz[i,*])
  x_in = reform(qmat[i,*])
  drebin,x_in,z_in,dz_in, qbins_arr,z_out,dz_out,/points,/to_points, $
     err = err,emsg = emsg
  dataReb[i,*] = z_out
  errReb[i,*] = dz_out
endfor



;print,'errReb[*,0]: ',errReb[*,0]

ndet=n_elements(qbins_arr)

; At this point we have to cull the data to remove points
; first we have to work out which energy points are encompassed by the Q bins
Qbinstep=qbins_arr[1]-qbins_arr[0]


for i = 0, nqbins-1 do begin
Qlowerlimit=qbins_arr[i]-(Qbinstep/2.0)
phimin=min(y)
Qmin= sqrt((2.0d*E0-x-2.0d*sqrt(E0*(E0-x))*cos(phimin*!dtor))/alpha)
reject=where(QlowerLimit lt Qmin,count)
if count ne 0 then begin
  dataReb[reject,i] = -1.0
  errReb[reject,i] = 0.0

    if total(errReb[*,i]) eq 0 then begin
;    print,'i: ',i
;    print,'Qlowerlimit: ',Qlowerlimit
;    print,'Qmin: ',Qmin
    endif

endif
;
Qupperlimit=qbins_arr[i]+(Qbinstep/2.0)
phimax=max(y)
Qmax= sqrt((2.0d*E0-x-2.0d*sqrt(E0*(E0-x))*cos(phimax*!dtor))/alpha)

reject=where(QupperLimit gt Qmax,count)
if count ne 0 then begin
  dataReb[reject,i] = -1.0
  errReb[reject,i] = 0.0

    if total(errReb[*,i]) eq 0 then begin
;    print,'i: ',i
;    print,'Qupperlimit: ',Qupperlimit
;    print,'Qmax: ',Qma
    endif

endif
endfor

;  if i eq 0 then begin
; print, 'q binning'
; help,z_in
;  help,dz_in
;  help,x_in
;  help,z_out
;  help,dz_out
;     print, 'Q emsg =',emsg
;     print, 'Q emsg =',err
;endif
;     print, 'Q emsg =',emsg

;help,dataReb
;help,errReb

;whereLTone=where(dataReb lt 1,count)
;if count ne 0 then begin
;dataReb(whereLTone)=0.0
;errReb(whereLTone)=1.0
;print,whereLTone
;endif

;print,'count =',count
wheregtzero=where(errReb gt 0,count)
if count ne 0 then begin
mindz=min(errReb[wheregtzero])
wherezero=where(errReb eq 0,count)
if count ne 0 then errReb[wherezero]=mindz
;print,'count =',count
endif
self.ndet=ndet
*self.dataPtr=dataReb
*self.errorPtr=errReb
*self.yvalsPtr=qbins_arr

;help,*self.dataPtr
;help,*self.errorPtr
;help,*self.xvalsPtr
;help,*self.yvalsPtr
;return
oyrange = '('+strtrim(string(min(qmat)),2)+','+strtrim(string(max(qmat)),2)+')'
yrange = '('+strtrim(string(min(qbins_arr)),2)+','+strtrim(string(max(qbins_arr)),2)+')'
treat = ['data has been rebinned in Q.', $
        'Old Q-range: '+oyrange, $
        'New Q-range: ',yrange ,$
        'New bins:'+strtrim(string(ndet),2)]
*self.treatmentPtr = [*self.treatmentPtr,treat]


ENDIF
;
;
;
if DataOutput eq 1 or DataOutput eq 2 then begin ; group in phi


file='PhiBinParameters.sav'
   fileOut = filepath(file,root_dir = self.workDir)

    if qbin_command eq 0 then begin

array = intarr(self.ndet,self.ndet)
;help,array
;print,n_elements(self.ndet)
for i = 0,self.ndet-1 do begin
  array[i,i] = 1
endfor
*self.selDetPtr = array

*self.selDetPtr = focusDetGroupWidget(group_leader = event.top,self.selDetPtr,y)
DetPtr=*self.selDetPtr
save, filename=fileout, DetPtr

    endif

    if qbin_command eq 1 then begin
        if file_test(self.workDir+file) eq 1 then begin
    restore, fileout
;    help,Detptr
    *self.selDetPtr=Detptr
       ;print,'Modify Previous'
        ;print,(size(Detptr))[1]
        ;print,self.ndet
    *self.selDetPtr = focusDetGroupWidget(group_leader = event.top,self.selDetPtr,y)
     DetPtr=*self.selDetPtr
save, filename=fileout, DetPtr
  endif else begin
;revert to default
message=string('THE FILE '+self.workDir+'PhiBinParameters.sav HAS NOT BEEN FOUND;  REVERTING TO DEFAULT ')
msg=message
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb

       array = intarr(self.ndet,self.ndet)
for i = 0,self.ndet-1 do begin
  array[i,i] = 1
endfor
*self.selDetPtr = array

*self.selDetPtr = focusDetGroupWidget(group_leader = event.top,self.selDetPtr,y)
DetPtr=*self.selDetPtr
save, filename=fileout, DetPtr

       endelse
    endif


    if qbin_command eq 2 then begin
        if file_test(self.workDir+file) eq 1 then begin
    restore, fileout
        *self.selDetPtr=Detptr
       ;print,'Use Previous'
        ;print,(size(Detptr))[1]
        ;print,self.ndet
       endif else begin
       ;revert to default
message=string('THE FILE '+self.workDir+'PhiBinParameters.sav HAS NOT BEEN FOUND;  REVERTING TO DEFAULT ')
msg=message
self->flashMessage_create,msg,tlb
wait,5
self->flashMessage_destroy,tlb
       array = intarr(self.ndet,self.ndet)
       ;help,array
       ;print,'self.ndet =',self.ndet
       ;help,y
for i = 0,self.ndet-1 do begin
  array[i,i] = 1
endfor
*self.selDetPtr = array

*self.selDetPtr = focusDetGroupWidget(group_leader = event.top,self.selDetPtr,y)
;print,'woof'
DetPtr=*self.selDetPtr
save, filename=fileout, DetPtr

       endelse
    endif


wheregtzero=where(total((*self.selDetPtr),2) gt 0,num)
;print,'num =',num
yout=(*self.selDetPtr)[wheregtzero,*]
znew=fltarr((size(z))[1],num)
dznew=fltarr((size(z))[1],num)
ynew=fltarr(num)
treat = ['The data have been binned in groups of phi.', $
        'Number of groups: '+strtrim(string(num),2),  $
        'Phi values for detectors in each group are as follows:']

;help,znew
;help,yout
;print,yout
for i = 0, num-1 do begin
whereone=where(yout[i,*] eq 1,count)
if count eq 0 then return
;print, 'group number =', i
;print, 'Detectors =', whereone
;print,''
;print,count
if count gt 1 then begin
znew[*,i]=total(z[*,whereone],2)
ynew[i]=(moment(y[whereone]))[0] ; mean average of detectors in group
dznew[*,i]=sqrt(total((dz[*,whereone])^2,2))
;print, 'whereone =',whereone
endif else begin
znew[*,i]=z[*,whereone]
dznew[*,i]=sqrt((dz[*,whereone])^2)
ynew[i]=y[whereone] ; mean average of detectors in group
endelse
treat=[treat, $
       'Group '+strtrim(string(i+1),2)+': ', $
       strtrim(string(y[whereone]),2), $
       '']
;       print,'y[whereone] =',y[whereone]
endfor
treat=[treat,'The y vector corresponds to the average value of phi in a given group', $
         '']

;help,znew
;help,dznew
;help,ynew
;print,ynew
;dznew=sqrt(znew)
;print,'count =',count
mindznew=min(dznew[where(dznew gt 0)])
wherezero=where(dznew eq 0,count)
if count ne 0 then dznew(wherezero)=mindznew
;print,'count =',count


*self.dataPtr=znew
*self.errorPtr=dznew
*self.yvalsPtr=ynew

*self.treatmentPtr = [*self.treatmentPtr,treat]

;help,yout
;print,yout(1,*)
endif

if qbin_command eq 0 then widget_control,self.qbin_group1,set_value = 1 ; as requested by Thierry and Fanni

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::remove_tth_degeneracies,event = event

catch, Error_status
if Error_status ne 0 then begin
  catch, /cancel
  msg=strarr(3)
  msg[0]='Something went wrong removing two-theta degeneracies.'
  msg[1]='please report to supplier (focusreduction::remove_tth_degeneracies).'
  msg[2]='Error Message from IDL: '+!ERROR_STATE.MSG
  void=dialog_message(dialog_parent=event.top,/error,msg)
  return
endif

;apply the same detector filtering as before
;
  good_det1D=*self.good_det1DPtr
  data=(*self.data1DPtr)[*,good_det1D]
  detnum=(*self.yvalsPtr)[good_det1D]
  sortorder=sort(detnum)
  detnum=detnum[sortorder]
  data=data[*,sortorder]
  dims=size(data)
  pnewdata=ptr_new(fltarr(dims[1],dims[2]))
  pnewdetnum=ptr_new(fltarr((size(detnum))[1]))
  (*pnewdetnum)[0]=detnum[0]
  (*pnewdata)[*,0]=data[*,0]
  j=0
  for i=1,n_elements(detnum)-1 do begin
    if detnum(i) ne detnum(i-1) then begin
      j+=1
      (*pnewdetnum)[j]=detnum[i]
      (*pnewdata)[*,j]=data[*,i]
    endif else begin
      (*pnewdata)[*,j]+=data[*,i]
    endelse
  endfor
  data=(*pnewdata)[*,0:j]
  detnum=(*pnewdetnum)[0:j]
  ptr_free,pnewdata
  ptr_free,pnewdetnum
  *self.dataPtr = data
  *self.errorPtr = sqrt(data)
  *self.yvalsPtr = detnum
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::normalize_to_vanadium,event = event

catch, Error_status
if Error_status ne 0 then begin
  catch, /cancel
  msg=strarr(3)
  msg[0]='Unable to normalise to Vanadium.'
  msg[1]='Check to see whether you have removed any dead detectors'
  msg[2]='Error Message from IDL: '+!ERROR_STATE.MSG
  void=dialog_message(dialog_parent=event.top,/error,msg)
  return
endif

if n_elements(*self.dataPtr) eq 0 then return     ; no sample data file available
if n_elements(*self.vanFilePtr) eq 0 then return  ; no vanadium data file available

;first pull out the current data values
;
sigData = *self.dataPtr
sigError = *self.errorPtr
sigX = *self.xvalsPtr
sigY = *self.yvalsPtr
sigMon_tc = *self.Mon_tcPtr
sigMon_cum = *self.Mon_cumPtr
sigTemp = *self.tempPtr
signdet=self.ndet
tof_corr_structure=*self.tof_corr_structurePtr
Sample_instrument_details=*self.InstrumentPtr

widget_control,self.DetectorBankTypesGroup,get_value = DBT ;merge conv, merge all, lower, middle, upper, 2D
widget_control,self.FormatTypesGroup,get_value = FormatType ;dave, igor, ascii, mslice

;get the vanadium
;
self->Sum_Vandium_Runs,event = event,err = err
vtemperature = *self.tempPtr
vtemperature = vtemperature[0]
if vtemperature eq 0 then vtemperature = 298.0

if (DBT eq 1) or (DBT eq 5) $      ; 1=merge all (2D inclusive), 5=2D only
  or (FormatType eq 3) then begin  ; mslice
  self->subtract_bad_detectors,event = event,err = err,/PREVIOUS
endif else begin                   ; conventional bank only, no mslice
  self->remove_tth_degeneracies,event = event
endelse
detnum=*self.yvalsPtr

;convert to energy unless the desired quantity is S(theta,t)
;
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
if DataOutput ne 2 then self->convert_to_energy,event=event,/not4

;get rough fit over all detectors to determine fwhm
;
xvan=*self.xvalsPtr & yvan=*self.dataPtr
ndet = n_elements(detnum)
x=xvan & y=total(yvan,2)
i1=n_elements(x)-1  
i0=(where(x ge (-x[i1])))[0]
x=x[i0:i1] & y=y[i0:i1]
result = gaussfit(x,y,p,nterms=5)
fwhm=p[2]*2.*sqrt(2.*alog(2.))

;display,x,y & display,x,result,/over,color=[255,0,0]
;print,"fwhm = ",fwhm

;now take +/- 2*fwhm as the fitting range
;
x=xvan
i0=(where(x ge (p[1]-3.*fwhm)))[0]
i1=(where(x ge (p[1]+3.*fwhm)))[0]
x=x[i0:i1]

;now fit detectors individually
;
area=fltarr(ndet) & fwhm=fltarr(ndet)
for i = 0,ndet-1 do begin
  y=reform(yvan[i0:i1,i])
  result = gaussfit(x,y,p,nterms=5)
  ;if i eq 50 then (display,x,y & display,x,result,/over,color=[255,0,0])
  area[i] = p[0]*sqrt(2.0*!pi*p[2]^2)
  fwhm[i] = p[2]*2.*sqrt(2.*alog(2.))
endfor
;display,area & print,"area = ",area
;display,fwhm & print,"fwhm = ",fwhm

;try to find bad fits
;
wheresmall=where(area lt (0.1*mean(area)),countsmall) ;area < 10% of average
wherebad=where(abs(fwhm-mean(fwhm))/mean(fwhm) gt 0.5,countbad) ;fwhm > 50% off average

;we do have suspicious detectors and ask the user what to do...
;
if (countsmall ne 0) or (countbad ne 0) then begin

  Faulty=[wheresmall,wherebad]
  Faulty=Faulty[where(Faulty ne -1)]
  Faultystring='detectors: '
  for i = 0, n_elements(Faulty) - 1 do begin
    Faultystring+=strtrim(string(Faulty[i]),2)+' '
  endfor
  msg=strarr(7)
  msg[0]='CALIBRATION OF DETECTORS FROM VANADIUM RUN SUSPICIOUS!'
  msg[1]='The following detectors show too little intensity (< 10% avg)'
  msg[2]='or suspicious fwhm values (> +/-50% avg) :'
  msg[3]=Faultystring
  msg[4]=''
  msg[5]='Do you want me to purge these detectors?'
  msg[6]='(can be done with graphical masking too)'
  res = dialog_message(dialog_parent=event.top,/question,msg)

;user decides to ignore this warning, i.e., does not purge
;
  if (res eq 'No') then begin ;abort vanadium calibration
    ;restore data
    ;
    *self.dataPtr = sigData
    *self.errorPtr = sigError
    *self.xvalsPtr = sigX
    *self.yvalsPtr = sigY
    *self.Mon_tcPtr = sigMon_tc
    *self.Mon_cumPtr = sigMon_cum
    *self.tempPtr = sigTemp
    self.ndet=signdet
    *self.InstrumentPtr=Sample_instrument_details
    treat = 'Unable to normalise to vanadium file(s): '+strtrim(string(*self.vanFilePtr),2)
    treat=[treat,'The vanadium calibration was aborted by instruction of the user']
    *self.treatmentPtr = [*self.treatmentPtr,treat]
    return
  endif else begin 
  
;user decides to purge suspicious detectors  
;
    for i = 0, signdet-1 do begin
      woof=where(i eq faulty,count)
      if count eq 0 then begin
        if n_elements(gooddets) eq 0 then gooddets=i else gooddets=[gooddets,i]
      endif
    endfor
    if n_elements(gooddets) eq 0 then begin
      msg=strarr(2)
      msg[1]='Unable to obtain a reasonable fit of the elastic line from all detectors!'
      msg[2]='The Vanadium Calibration must be aborted'+'.'
      void=dialog_message(dialog_parent=event.top,/error,msg)
      treat = msg
      *self.treatmentPtr = [*self.treatmentPtr,treat]
      return
    endif
    sigData=sigData[*,gooddets]
    sigError=sigError[*,gooddets]
    sigY=sigY[gooddets]
    detnum=detnum[gooddets]
    area=area[gooddets]
    signdet=n_elements(gooddets) ;signdet-=n_elements(faulty)
    treat = 'Due to problems with the vanadium calibration, the following detector group(s) were removed'
    treat=[treat,'from the purged and sorted data set: '+Faultystring]
    *self.treatmentPtr = [*self.treatmentPtr,treat]
  endelse
endif

;now lets normalize!
;
stats = moment(area[0:n_elements(detnum)-1])
area = temporary(area)/stats[0]
ux = 1+bytarr(n_elements(sigX))
lambda0=tof_corr_structure.lambdatof
q = (4.0*!pi/lambda0)*sin(0.5*!dtor*detnum)
dwf = ux#(exp(-0.0067*vtemperature/300.0*q^2))  ; Debye-Waller factor for vanadium
a = ux#area
sigData = sigData*dwf/a
sigError = sigError*dwf/a

;write data back to *self
;
*self.dataPtr = sigData
*self.errorPtr = sigError
*self.xvalsPtr = sigX
*self.yvalsPtr = SigY
*self.Mon_tcPtr = sigMon_tc
*self.Mon_cumPtr = sigMon_cum
*self.tempPtr = sigTemp
self.ndet=signdet
*self.InstrumentPtr=Sample_instrument_details
treat = 'Normalised to vanadium file(s): '+strtrim(string(*self.vanFilePtr),2)
*self.treatmentPtr = [*self.treatmentPtr,treat]

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Nexus_read_raw_focus,filename,event = event,err = err
;print,'filename =',filename
;print,'strlen(filename) =',strlen(filename)
;help,filename
if n_elements(filename) eq 0 then Begin
err=1
return
endif
err = 0
hdlerror=0
;bank='merged'
;IF N_ELEMENTS(bank) EQ 0 THEN bank='bank1'
handle=0L
;dummy = nxopen(filename,'read',handle)   ;for nidl
dummy = nxopen(filename,'NXACC_READ',handle) ;for napi45
self.curFile = filename
widget_control,self.DetectorBankTypesGroup,get_value = DBT
if DBT eq 0 then bank='merged'
if DBT eq 1 then bank='merged'
if DBT eq 2 then bank='lowerbank'
if DBT eq 3 then bank='bank1'
if DBT eq 4 then bank='upperbank'
;print,bank
widget_control,self.FormatTypesGroup,get_value = FormatType
;
;
;-------- get some global attributes
    dummy1 = nxgetattr(handle,'file_time',ftime,typ)
    dummy2 = nxgetattr(handle,'file_name',foriname, typ)
    dummy3 = nxgetattr(handle,'owner',owner,typ)
    ;------ open data1d vGroup and get counts, two_theta
    dummy = nxopengroup(handle,'entry1','NXentry')

if (bank ne 'bank1') then begin ; test to see whether the file is old
dummy = nxopengroup(handle,bank,'NXdata')
        IF (dummy EQ 0) THEN BEGIN
        void=DIALOG_MESSAGE(dialog_parent = event.top, $
        'Old file, only one bank! Opening bank1', /information)
         bank = 'bank1'
         widget_control,self.DetectorBankTypesGroup,set_value = 3
        ENDIF ELSE BEGIN
        dummy = nxclosegroup(handle)
        ENDELSE
 endif

    if (FormatType eq 3) then begin

         if (bank eq 'merged') then begin ;read all the data separately

       dummy = nxopengroup(handle,'lowerbank','NXdata')

        dummy = nxopendata(handle,'counts')
        dummy = nxgetdata(handle,cntsl)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'theta')
        dummy = nxgetdata(handle,detnuml)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'time_binning')
        dummy = nxgetdata(handle,tof)
        dummy = nxclosedata(handle)
        dummy = nxclosegroup(handle)


        dummy = nxopengroup(handle,'bank1','NXdata')

        dummy = nxopendata(handle,'counts')
        dummy = nxgetdata(handle,cntsm)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'theta')
        dummy = nxgetdata(handle,detnumm)
        dummy = nxclosedata(handle)

        dummy = nxclosegroup(handle)

        dummy = nxopengroup(handle,'upperbank','NXdata')

        dummy = nxopendata(handle,'counts')
        dummy = nxgetdata(handle,cntsu)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'theta')
        dummy = nxgetdata(handle,detnumu)
        dummy = nxclosedata(handle)

        dummy = nxclosegroup(handle)

    n_detnuml= n_elements(detnuml)
    n_detnumm= n_elements(detnumm)
    n_detnumu= n_elements(detnumu)

    n_detectors=n_detnuml+n_detnumm+n_detnumu
    detnum=[detnuml,detnumm,detnumu]
;    help,detnum
;    help,detnuml
;    help,detnumm
;    help,detnumu
cnts=intarr(n_elements(tof),n_detectors)

    cnts[*,0:n_detnuml-1]=cntsl
    cnts[*,n_detnuml:n_detnuml+n_detnumm-1]=cntsm
    cnts[*,n_detnuml+n_detnumm:n_detnuml+n_detnumm+n_detnumu-1]=cntsu
    AzimutalAngle=fltarr(n_detectors)
    AzimutalAngle[0:n_detnuml-1]=-180.0+!RADEG*(atan(sin(-13.0*!dtor)/sin(2*float(detnuml)*!dtor)))
    AzimutalAngle[n_detnuml:n_detnuml+n_detnumm-1]=-180.0
    AzimutalAngle[n_detnuml+n_detnumm:n_detnuml+n_detnumm+n_detnumu-1]= $
    -180.0+!RADEG*(atan(sin(13.0*!dtor)/sin(2*float(detnumu)*!dtor)))
    sortorder=sort(detnum)
    detnum=(temporary(detnum))[sortorder]
    cnts=(temporary(cnts))[*,sortorder]
    AzimutalAngle=(temporary(AzimutalAngle))[sortorder]
    *self.AzimutalAnglePtr=AzimutalAngle
;help,detnum
         endif else begin
       dummy = nxopengroup(handle,bank,'NXdata')

        dummy = nxopendata(handle,'counts')
        dummy = nxgetdata(handle,cnts)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'theta')
        dummy = nxgetdata(handle,detnum)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'time_binning')
        dummy = nxgetdata(handle,tof)
        dummy = nxclosedata(handle)
        dummy = nxclosegroup(handle)

    AzimutalAngle=fltarr(n_elements(detnum))
    if bank eq 'lowerbank' then AziAngle=-13.0
    if bank eq 'bank1' then AziAngle=0.0
    if bank eq 'upperbank' then AziAngle=13.0
    AzimutalAngle=-180.0+!RADEG*(atan(sin(AziAngle*!dtor)/sin(2*float(detnum)*!dtor)))
    *self.AzimutalAnglePtr=AzimutalAngle
         endelse
    endif else begin

        dummy = nxopengroup(handle,bank,'NXdata')

        dummy = nxopendata(handle,'counts')
        dummy = nxgetdata(handle,cnts)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'theta')
        dummy = nxgetdata(handle,detnum)
        dummy = nxclosedata(handle)

        dummy = nxopendata(handle,'time_binning')
        dummy = nxgetdata(handle,tof)
        dummy = nxclosedata(handle)
        dummy = nxclosegroup(handle)

    endelse
    ; ------- enter 2d detector group
if (DBT eq 1) or (DBT eq 5)  then begin
dummy = nxopengroup(handle,'focus2d','NXdata')
    if dummy then begin
    dummy = nxopendata(handle,'counts')
    dummy = nxgetdata(handle,data2d)
;    help,data2d
    dummy = nxclosedata(handle)
;
    dummy = nxopendata(handle,'time_binning')
    dummy = nxgetdata(handle,tof2d)
;    help,tof2d
    dummy = nxclosedata(handle)
    dummy = nxclosegroup(handle)

       endif else begin
       void=DIALOG_MESSAGE(dialog_parent = event.top, $
       'FOCUS 2D DATA NOT FOUND!', /information)
if DBT eq 5 then begin
err = 1
return
endif
    endelse
endif

    ;------ get title Information
    dummy = nxopendata(handle,'title')
    dummy = nxgetdata(handle,title)
    dummy = nxclosedata(handle)

    ; -------- get sample information
    dummy = nxopengroup(handle,'sample','NXsample')
    dummy = nxopendata(handle,'name')
    dummy = nxgetdata(handle,sample)
    dummy = nxclosedata(handle)
    dummy = nxopendata(handle,'distance')
    dummy = nxgetdata(handle,sadist)
    dummy = nxclosedata(handle)
    dummy = nxopendata(handle, 'temperature')
    if dummy then begin
      dummy = nxgetdata(handle, temp)
      dummy = nxclosedata(handle)
    endif else begin
      ;temp_float = opan_Temperature_widget(filename,group_leader = event.top)
      temp=MAKE_ARRAY(1, /float, value=293.0)  ; no T sensor -> assume T=293K
      treat = ['WARNING: no temperature information -> assuming T=293K.']
      *self.treatmentPtr = [*self.treatmentPtr,treat]
    endelse
    if temp[0] le 0 then begin
      ;temp_float = opan_Temperature_widget(filename,group_leader = event.top)
      temp=MAKE_ARRAY(1, /float, value=293.0)  ; no T sensor -> assume T=293K
      treat = ['WARNING: no temperature information -> assuming T=293K.']
      *self.treatmentPtr = [*self.treatmentPtr,treat]
    endif
    dummy = nxclosegroup(handle)

    ; ------- enter instrument group
    dummy = nxopengroup(handle,'FOCUS','NXinstrument')
    dummy = nxopendata(handle,'tof_monitor')
    IF dummy THEN BEGIN
       dummy = nxgetdata(handle,mcnts)
        dummy = nxclosedata(handle)
    END ELSE mcnts=MAKE_ARRAY(1, /double, value=0.0)

    ; ------- enter monochromator group
    dummy = nxopengroup(handle,'monochromator','NXmonochromator')

    ;------ get lambda
    dummy = nxopendata(handle,'lambda')
    dummy = nxgetdata(handle,lambda)
    dummy = nxclosedata(handle)
    dummy = nxclosegroup(handle)


    ;------- get monitor
    dummy = nxopengroup(handle,'counter','NXmonitor')
    dummy = nxopendata(handle,'monitor')
    dummy = nxgetdata(handle,monitor)
    dummy = nxclosedata(handle)

    ;------ get measurement time
    dummy = nxopendata(handle,'time')
    dummy = nxgetdata(handle,time)
    dummy = nxclosedata(handle)
    dummy = nxclosegroup(handle)

    ;------- fermi-chopper
    dummy = nxopengroup(handle,'fermi_chopper','NXchopper')
    dummy = nxopendata(handle,'rotation_speed')
    dummy = nxgetdata(handle,fermispeed)
    dummy = nxclosedata(handle)

    ;-------- get phase
    dummy = nxopendata(handle,'phase')
    dummy = nxgetdata(handle,fermiphase)
    dummy = nxclosedata(handle)

    ;------ fermi-distance
    dummy = nxopendata(handle,'distance')
    dummy = nxgetdata(handle,fermidist)
    dummy = nxclosedata(handle)
    dummy = nxclosegroup(handle)

    ;-------- disk chopper
    dummy = nxopengroup(handle,'disk_chopper','NXchopper')

    ;------ get speed
    dummy = nxopendata(handle,'rotation_speed')
    dummy = nxgetdata(handle,diskspeed)
    dummy = nxclosedata(handle)
    dummy = nxclosegroup(handle)

    ;------ get 2d detector distances and angles
if (DBT eq 1) or (DBT eq 5)  then begin
    dummy = nxopengroup(handle,'focus2d','NXdetector')
    if dummy then begin
    dummy = nxopendata(handle,'distance')
    dummy = nxgetdata(handle,distance2d)
    dummy = nxclosedata(handle)

    dummy = nxopendata(handle,'polar_angle')
    dummy = nxgetdata(handle,theta2d)
    dummy = nxclosedata(handle)

    dummy = nxclosegroup(handle)
    endif else begin
       void=DIALOG_MESSAGE(dialog_parent = event.top, $
       'FOCUS 2D DETECTOR INFORMATION NOT FOUND!', /information)
if DBT eq 5 then begin
err = 1
return
endif
    endelse
endif

    ;------ close the file
    dummy = nxclosegroup(handle)
    dummy = nxclose(handle)

    IF hdlerror NE 0 THEN BEGIN
       IF hdlerror EQ 1 THEN mes='There was '+STRCOMPRESS(STRING(hdlerror), /REMOVE_ALL)+' error in reading the NEXUS file!' $
       ELSE mes='There were '+STRCOMPRESS(STRING(hdlerror), /REMOVE_ALL)+' errors in reading the NEXUS file!'
       dummy=DIALOG_MESSAGE(mes, /error, DIALOG_PARENT=tof1)
    END
;
; code added by Philip
;
;cd,current=dir
;filename=dir+path_sep()+'FOCUSFile_contents.txt'
;openw,lun,filename,/get_lun
;printf,lun,'file_time  ftime ='
;printf,lun,ftime
;printf,lun,''
;printf,lun,'file_name foriname = '
;printf,lun,foriname
;printf,lun,''
;printf,lun,'owner owner ='
;printf,lun,owner
;printf,lun,''
;printf,lun,'counts cnts  ='
;printf,lun,cnts
;printf,lun,''
;printf,lun,'theta detnum ='
;printf,lun,detnum
;printf,lun,''
;printf,lun,'time_binning tof ='
;printf,lun,tof
;printf,lun,''
;printf,lun,'title  title ='
;printf,lun,title
;printf,lun,''
;printf,lun,'name  sample ='
;printf,lun,sample
;printf,lun,''
;printf,lun,'distance  sadist='
;printf,lun,sadist
;printf,lun,''
;printf,lun,'temperature temp='
;printf,lun,temp
;printf,lun,''
;printf,lun,'tof_monitor mcnts='
;printf,lun,mcnts
;printf,lun,''
;printf,lun,'lambda  lambda= '
;printf,lun,lambda
;printf,lun,''
;printf,lun,'NXmonitor monitor'
;printf,lun,monitor
;printf,lun,''
;printf,lun,'time time ='
;printf,lun,time
;printf,lun,''
;printf,lun,'fermi_chopper fermispeed ='
;printf,lun,fermispeed
;printf,lun,''
;printf,lun,'phase fermiphase ='
;printf,lun,fermiphase
;printf,lun,''
;printf,lun,'distance fermidist ='
;printf,lun,fermidist
;printf,lun,''
;printf,lun,'disk_chopper diskspeed'
;printf,lun,diskspeed
;
;free_lun,lun,/force
;;
;help, mcnts
;help, tof
;
;
;help,cnts
OldData=float(cnts)
;help,OldData
;the last energy point is nonsense, corresponding to an infinite time bin.  We must purge it.
col=(size(OldData))[1]
row=(size(OldData))[2]
;data1d=fltarr(col-1,row)
data1d=OldData[0:(col-2),*]
;help,data1d
tof=tof[0:(col-2)]
if (size(mcnts))[1] ne 1 then mcnts=mcnts[0:(col-2)]
error1D=sqrt(data1d)
wherezero=where(error1D eq 0,thisnum)
if thisnum gt 0 then begin
    error1D[wherezero]=1.0
endif
;
;
;help,tof
;help,mcnts
;print,'detnum =',detnum
;print,'sort(detnum) =',sort(detnum)
;print,total(data1d)

;help,data1d
;
*self.odata1DPtr =data1d
*self.oerror1DPtr=error1D
*self.oxvals1DPtr=tof
*self.oyvals1DPtr=detnum
;convert to point data1d
tof+=(tof[1]-tof[0])/2.0
;
;
*self.data1DPtr = data1d
*self.error1DPtr=error1D
*self.xvalsPtr=tof
*self.yvalsPtr=detnum
;print,'tof: ',tof
;
;
;*self.Mon_cumPtr=monitor
if long(total(mcnts)) eq 0 then begin
*self.Mon_cumPtr=monitor
endif else begin
*self.Mon_cumPtr=long(total(mcnts))
endelse
;print,'*self.Mon_cumPtr =',*self.Mon_cumPtr
*self.Mon_tcPtr=mcnts
*self.tempPtr=temp
*self.detPtr=detnum
;print,*self.detPtr
;
self.ylabel = 'Group'
self.zlabel = 'Intensity'
self.ndet = n_elements(detnum)


;file='syn2d.sav'
;   fileOut = filepath(file,root_dir = self.workDir)
;restore,fileOut
;help,syn2d,/struc
;data2d=syn2d.cnts
;tof2d=syn2d.tt
;distance2d=syn2d.dd
;theta2d=syn2d.tth

IF  (n_elements(data2d) eq 0) OR $
    (n_elements(tof2d) eq 0) OR $
    (n_elements(distance2d) eq 0) OR $
    (n_elements(theta2d) eq 0) then begin
    data2d=0
    error2d=0
    tof2d=0
    distance2d=0
    theta2d=0
endif else begin
;

Old2dData=float(data2d)
;help,OldData
;the last energy point is nonsense, corresponding to an infinite time bin.  We must purge it.
dim1=(size(Old2dData))[1]
dim2=(size(Old2dData))[2]
dim3=(size(Old2dData))[3]
data2d=Old2dData[0:(dim1-2),*,*]
tof2d=tof2d[0:(dim1-2)]
tof2d+=(tof2d[1]-tof2d[0])/2.0
error2d=sqrt(data2d)
wherezero=where(error2d eq 0,thisnum)
if thisnum gt 0 then begin
    error2d[wherezero]=1.0
endif
;print,'tof2d: ',tof2d
;print,'distance2d[0]: ',distance2d[0]

ENDELSE

*self.xvals2dPtr=tof2d
*self.data2dPtr = data2d
*self.error2dPtr = error2d
*self.distance2d=distance2d
*self.theta2d=theta2d


;print,'self.ndet =',self.ndet
;print,temp
;help,temp
;help,title
;print,title
;help,ftime
;help,foriname
;help,diskspeed
;help,fermidist
;help,fermiphase
;help,fermispeed
;print,sample
;help,sample
;print,owner
;help,owner
;help,lambda
;help,sadist
;sample=string(sample)
;
;   create structure with instrumental details
instrument_details={instrument_details, $
              ftime:ftime,   $
              foriname:foriname,    $
              owner:owner,     $
              title:title,     $
              sample:sample,    $
              sadist:sadist,  $
              temp:temp,   $
              lambda:lambda,$
              fermispeed:fermispeed,    $
              fermiphase:fermiphase,    $
              fermidist:fermidist,$
              diskspeed:diskspeed, $
              MONtoDET:2.784, $
              FCtoDET:3.0, $
              FCtoSAM:0.5, $
              SAMtoDET:2.5}
;
;print,instrument_details

;MONtoDET=monitor to detector distance
;FCtoDET=Fermi chopper to detector
;FCtoSAM=Fermi chopper to sample
;SAMtoDET=Sample to detector


*self.InstrumentPtr=instrument_details
;
;
;   All the information not required for the data1d reduction are stored in the header
header = strarr(12)
;help,ftime
;help,diskspeed
;help,fermidist
;print,sample
;help,sample
;print,owner
;help,owner
;sample=string(sample)

header[0]='file_time = '+strtrim(string(ftime),2)
header[1]='Original file name = '+strtrim(string(foriname),2)
header[2]='Owner = '+strtrim(string(owner),2)
header[3]='Title = '+strtrim(string(title),2)
header[4]='Sample name = '+strtrim(string(sample),2)
header[5]='Distance to sample = '+strtrim(string(sadist),2)
header[6]='Temperature of sample = '+strtrim(string(temp),2)
header[7]='Wavelength / A  = '+strtrim(string(lambda),2)
header[8]='Speed of Fermi chopper = '+strtrim(string(fermispeed),2)
header[9]='Phase of Fermi chopper = '+strtrim(string(fermiphase),2)
header[10]='Fermi Distance = '+strtrim(string(fermidist),2)
header[11]='Disk Chopper Speed = '+strtrim(string(diskspeed),2)
*self.headerPtr = header
;for  i=0,11 do begin
;print,header[i]
;endfor
;
;
;
;help,data1d

IF (DBT NE 1) AND (DBT NE 5) THEN BEGIN
*self.data2dPtr = 0
*self.error2dPtr = 0
*self.xvals2dPtr=0
ENDIF
IF (DBT EQ 5) THEN BEGIN
*self.data1dPtr = 0
*self.error1dPtr = 0
*self.yvalsPtr=0
self.ndet = 1
ENDIF




END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::TOF_corr,event=event
;

CATCH, Error_status
if Error_status ne 0 then begin
  catch, /cancel
  msg=strarr(5)
  msg[0]='Unable to find elastic peak for the purpose of wavelength calibration.'
  msg[1]='This error is extremely rare and is rather worrying.'
  msg[2]='If you are summing runs together, make sure they were collected under the same conditions'
  msg[3]='Error Message from IDL: '+!ERROR_STATE.MSG
  msg[4]='The wavelength will now be derived from the monochromator'
  void=dialog_message(dialog_parent=event.top,/error,msg)
  widget_control,self.elasticGroup,set_value = 2
  treat = 'Elastic Line Calculated From Sample File(s), Monochromator'
  *self.treatmentPtr = [*self.treatmentPtr,treat]
  lambda=instrument_details.lambda
  tof_shift=0.0
  tof_corr_structure={tof_corr_structure,tof_shift:tof_shift[0],lambdatof:lambda[0]}
  *self.tof_corr_structurePtr=tof_corr_structure
  widget_control,(*self.lambda_fieldPtr).lambda_monochromator,set_value = string(instrument_details.lambda)
  widget_control,(*self.lambda_fieldPtr).lambda_tof,set_value = ''
  return
endif

if total(*self.Mon_tcPtr) eq 0 then begin
self->TOF_corr_oldfile,event=event
return
endif

;
widget_control,self.elasticGroup,get_value = elasticGroup



instrument_details=*self.InstrumentPtr
;
if elasticGroup[0] eq 0 then begin
;
if n_elements(*self.VanFilePtr) ne 0 then begin

;Store All the data Locally
;
sigData = *self.dataPtr
sigError = *self.errorPtr
sigx = *self.xvalsPtr
sigy = *self.yvalsPtr
sigTemp = *self.tempPtr
sigMon_cum = *self.Mon_cumPtr
sigMon_tc = *self.Mon_tcPtr
signdet=self.ndet
Sample_instrument_details=*self.InstrumentPtr

;print,'woofy'
;print,'vanfile= ',vanfile
self->Sum_Vandium_Runs,event = event,err = err
;print,'woofy1'
;apply the same filtering as before
widget_control,self.DetectorBankTypesGroup,get_value = DBT
IF (DBT EQ 1) OR (DBT EQ 5) THEN BEGIN
self->subtract_bad_detectors,event = event,err = err,/PREVIOUS
cnts=*self.dataPtr
ENDIF ELSE BEGIN
cnts=*self.dataPtr
cnts=cnts[*,*self.good_det1DPtr]
ENDELSE
;help,cnts
;get the data
mcnts=*self.Mon_tcPtr
;cnts=*self.dataPtr
;apply the same filtering as before
;cnts=cnts[*,*self.good_det1DPtr]
;sorting isn't necessary as we are going to sum
tof=*self.xvalsPtr
;print,'instrument_details.fermispeed',instrument_details.fermispeed

Fermi_period=60000000.0/(2.0*(instrument_details.fermispeed))
;
;
;print,'Fermi_period = ',Fermi_period
;
;Extract distances
MONtoDET=instrument_details.MONtoDET
FCtoDET=instrument_details.FCtoDET
;
;Define Plank's constant
h=6.6260755e-34
mn=1.67495e-27
;
;print,'Vanadium'
;help,cnts
;
;   sum the detectors
cnts=total(cnts,2)
;
;omit unwanted peaks
;mcnts-=50.0 ;converted to float
;whereltzero=where(mcnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    mcnts[whereltzero]=0.0
;
;endif
;
;whereltzero=where(cnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    cnts[whereltzero]=0.0
;endif
;
;
coeff=[max(cnts),(tof[where(cnts eq max(cnts))])[0],70.0,0,0,0]
dummy=gaussfit(tof,cnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,p[i]
;endfor
det_time=p[1]
;print,'det time = ',det_time
;
;
coeff=[max(mcnts),(tof[where(mcnts eq max(mcnts))])[0],70.0,0,0,0]
;print,''
dummy=gaussfit(tof,mcnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,p[i]
;endfor
;
mon_time=p[1]-Fermi_period
While mon_time-Fermi_period gt 0 do begin
mon_time-=Fermi_period
endwhile

;print,'mon_time = ',mon_time

t=(det_time-mon_time)*1e-6
;print,'t = ',t
v=montodet/t
lambdaTOF=(h/(v*mn))*1e10
;print,'lambda =',lambda
;print,'instrument_details.lambda',instrument_details.lambda
; next calculate the tof shift
;   First calculate the time from FC to detector based upon new wavelength (velocity)
t=(FCtoDET/v)*1e6
;compare to det_time
tof_shift=t-det_time
;print, 'tof_shift = ',tof_shift
;tof should be added to the time bins
;print,tof
;print, 'tof = ',tof
;print,''
;print, 'tof = ',tof
;print,*self.xvalsPtr
;
;print, 'Elastic Line From Vanadium'
treat = 'Elastic Line Calculated From Vanadium File, TOF data'
*self.treatmentPtr = [*self.treatmentPtr,treat]


;Restore All the data
;
 *self.dataPtr=sigData
 *self.errorPtr=sigError
 *self.xvalsPtr=sigx
 *self.yvalsPtr=sigy
 *self.tempPtr=sigTemp
 *self.Mon_cumPtr=sigMon_cum
 *self.Mon_tcPtr=sigMon_tc
self.ndet=signdet
*self.InstrumentPtr=Sample_instrument_details

endif else begin
elasticgroup=1


widget_control,self.elasticGroup,set_value = elasticgroup
endelse
endif
;
if elasticGroup[0] eq 1 or elasticGroup[0] eq 2 then begin   ;   Elastic Line From Sample

;print, 'Elastic Line From Sample'
if elasticGroup[0] eq 1 then treat = 'Elastic Line Calculated From Sample File(s), TOF data'
if elasticGroup[0] eq 2 then treat = 'Elastic Line Calculated From Sample File(s), Monochromator'
*self.treatmentPtr = [*self.treatmentPtr,treat]

;get the data
mcnts=*self.Mon_tcPtr
cnts=*self.dataPtr
tof=*self.xvalsPtr
;print,'instrument_details.fermispeed',instrument_details.fermispeed
;print,'Sample'
;help,cnts

Fermi_period=60000000.0/(2.0*(instrument_details.fermispeed))
;
;
;print,'Fermi_period = ',Fermi_period
;
;Extract distances
MONtoDET=instrument_details.MONtoDET
FCtoDET=instrument_details.FCtoDET
;
;Define Plank's constant and neutron mass
h=6.6260755e-34
mn=1.67495e-27
;
;
;
;   sum the detectors
cnts=total(cnts,2)
;
;omit unwanted peaks
;mcnts-=50.0 ;converted to float
;whereltzero=where(mcnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    mcnts[whereltzero]=0.0
;endif
;
;whereltzero=where(cnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    cnts[whereltzero]=0.0
;endif
;
;
coeff=[max(cnts),(tof[where(cnts eq max(cnts))])[0],70.0,0,0,0]
;print,'coeff =',coeff
dummy=gaussfit(tof,cnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,'p[i] =',p[i]
;endfor
;
det_time=p[1]
;print,'det time = ',det_time
;
;
coeff=[max(mcnts),(tof[where(mcnts eq max(mcnts))])[0],70.0,0,0,0]
;print,'tof[where(mcnts eq max(mcnts))]',tof[where(mcnts eq max(mcnts))]
;help,tof
;help,mcnts
dummy=gaussfit(tof,mcnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,'p[i] =',p[i]
;endfor
;
mon_time=p[1]-Fermi_period
While mon_time-Fermi_period gt 0 do begin
mon_time-=Fermi_period
endwhile

;print,'mon_time = ',mon_time
t=(det_time-mon_time)*1e-6
;print,'t = ',t
v=montodet/t
lambdaTOF=(h/(v*mn))*1e10
;print,'lambda =',lambda
;print,'instrument_details.lambda',instrument_details.lambda
; next calculate the tof shift
;   First calculate the time from FC to detector based upon new wavelength (velocity)
t=(FCtoDET/v)*1e6
;compare to det_time
tof_shift=t-det_time
;print, 'tof_shift = ',tof_shift
;tof should be added to the time bins
;print,tof
;print, 'tof = ',tof
;print,''
;tof+=tof_shift[0]
;print, 'tof = ',tof
;print,*self.xvalsPtr
endif
if elasticGroup[0] eq 2 then begin   ;   Elastic Line From Monochromator
lambda=instrument_details.lambda
tof_shift=0.0
;treat = 'Elastic Line Calculated From Monochromator Value'
;*self.treatmentPtr = [*self.treatmentPtr,treat]
endif
if elasticGroup[0] eq 3 then begin   ;   Elastic Line From Input Value
treat = 'Elastic Line Calculated From Input Value'
*self.treatmentPtr = [*self.treatmentPtr,treat]
widget_control,self.lambda_own_value,get_value = lambda
tof_shift=0.0
endif
;
;
if elasticGroup[0] eq 0 or elasticGroup[0] eq 1 then begin
tof_corr_structure={tof_corr_structure,tof_shift:tof_shift[0],lambdatof:lambdaTOF[0]}
*self.tof_corr_structurePtr=tof_corr_structure
endif else begin
tof_corr_structure={tof_corr_structure,tof_shift:tof_shift[0],lambdatof:lambda[0]}
*self.tof_corr_structurePtr=tof_corr_structure
endelse
;
widget_control,(*self.lambda_fieldPtr).lambda_monochromator,set_value = string(instrument_details.lambda)
if elasticgroup lt 3 then begin
widget_control,(*self.lambda_fieldPtr).lambda_tof,set_value = string(lambdaTOF[0])
endif else begin
widget_control,(*self.lambda_fieldPtr).lambda_tof,set_value = ''
endelse
;
;
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::TOF_corr_oldfile,event=event

CATCH, Error_status
if Error_status ne 0 then begin
  catch, /cancel
  msg=strarr(5)
  msg[0]='Unable to find elastic peak for the purpose of wavelength calibration.'
  msg[1]='This error is extremely rare and is rather worrying.'
  msg[2]='If you are summing runs together, make sure they were collected under the same conditions'
  msg[3]='Error Message from IDL: '+!ERROR_STATE.MSG
  msg[4]='The wavelength will now be derived from the monochrometer
  void=dialog_message(dialog_parent=event.top,/error,msg)
  widget_control,self.elasticGroup,set_value = 2
  treat = 'Elastic Line Calculated From Sample File(s), Monochromator'
  *self.treatmentPtr = [*self.treatmentPtr,treat]
  lambda=instrument_details.lambda
  tof_shift=0.0
  tof_corr_structure={tof_corr_structure,tof_shift:tof_shift[0],lambdatof:lambda[0]}
  *self.tof_corr_structurePtr=tof_corr_structure
  widget_control,(*self.lambda_fieldPtr).lambda_monochromator,set_value = string(instrument_details.lambda)
  widget_control,(*self.lambda_fieldPtr).lambda_tof,set_value = ''
  return
endif
;
;
;print,'TOF_corr_oldfile'
;
widget_control,self.elasticGroup,get_value = elasticGroup
instrument_details=*self.InstrumentPtr
;
if elasticGroup[0] eq 0 then begin
;
if n_elements(*self.VanFilePtr) ne 0 then begin

;Store All the data Locally
;
sigData = *self.dataPtr
sigError = *self.errorPtr
sigx = *self.xvalsPtr
sigy = *self.yvalsPtr
sigTemp = *self.tempPtr
sigMon_cum = *self.Mon_cumPtr
sigMon_tc = *self.Mon_tcPtr
signdet=self.ndet
Sample_instrument_details=*self.InstrumentPtr


;apply the same filtering as before
widget_control,self.DetectorBankTypesGroup,get_value = DBT
IF (DBT EQ 1) OR (DBT EQ 5) THEN BEGIN
self->subtract_bad_detectors,event = event,err = err,/PREVIOUS
cnts=*self.dataPtr
ENDIF ELSE BEGIN
cnts=*self.dataPtr
cnts=cnts[*,*self.good_det1DPtr]
ENDELSE
;
;sorting isn't necessary as we are going to sum
tof=*self.xvalsPtr
;print,'instrument_details.fermispeed',instrument_details.fermispeed

Fermi_period=60000000.0/(2.0*(instrument_details.fermispeed))
;
;
;print,'Fermi_period = ',Fermi_period
;
;Extract distances
;MONtoDET=instrument_details.MONtoDET
FCtoDET=instrument_details.FCtoDET
;
;Define Plank's constant
h=6.6260755e-34
mn=1.67495e-27
;
;
;
;   sum the detectors
cnts=total(cnts,2)
;
;omit unwanted peaks
;mcnts-=50.0 ;converted to float
;whereltzero=where(mcnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    mcnts[whereltzero]=0.0
;
;endif
;
;whereltzero=where(cnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    cnts[whereltzero]=0.0
;endif
;
;
coeff=[max(cnts),(tof[where(cnts eq max(cnts))])[0],70.0,0,0,0]
dummy=gaussfit(tof,cnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,p[i]
;endfor
det_time=p[1]
;print,'det time = ',det_time
;
;
;coeff=[max(mcnts),(tof[where(mcnts eq max(mcnts))])[0],70.0,0,0,0]
;print,''
;dummy=gaussfit(tof,mcnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,p[i]
;endfor
;
;mon_time=p[1]-Fermi_period
;While mon_time-Fermi_period gt 0 do begin
;mon_time-=Fermi_period
;endwhile

;print,'mon_time = ',mon_time

;t=(det_time-mon_time)*1e-6
t=det_time*1e-6
;print,'t = ',t
;v=montodet/t
v=FCtoDET/t

lambdaTOF=(h/(v*mn))*1e10
;print,'lambda =',lambda
;print,'instrument_details.lambda',instrument_details.lambda
; next calculate the tof shift
;   First calculate the time from FC to detector based upon new wavelength (velocity)
;t=(FCtoDET/v)*1e6
;compare to det_time
;tof_shift=t-det_time
tof_shift=0.0
;print, 'tof_shift = ',tof_shift
;tof should be added to the time bins
;print,tof
;print, 'tof = ',tof
;print,''
;print, 'tof = ',tof
;print,*self.xvalsPtr
;
;print, 'Elastic Line From Vanadium'
treat = 'Elastic Line Calculated From Vanadium File, TOF data'
*self.treatmentPtr = [*self.treatmentPtr,treat]


;Restore All the data
;
 *self.dataPtr=sigData
 *self.errorPtr=sigError
 *self.xvalsPtr=sigx
 *self.yvalsPtr=sigy
 *self.tempPtr=sigTemp
 *self.Mon_cumPtr=sigMon_cum
 *self.Mon_tcPtr=sigMon_tc
self.ndet=signdet
*self.InstrumentPtr=Sample_instrument_details
endif else begin
elasticgroup=1


widget_control,self.elasticGroup,set_value = elasticgroup
endelse
endif
;
if elasticGroup[0] eq 1 or elasticGroup[0] eq 2 then begin   ;   Elastic Line From Sample

;print, 'Elastic Line From Sample'
if elasticGroup[0] eq 1 then treat = 'Elastic Line Calculated From Sample File(s), TOF data'
if elasticGroup[0] eq 2 then treat = 'Elastic Line Calculated From Sample File(s), Monochromator'
*self.treatmentPtr = [*self.treatmentPtr,treat]

;get the data
;mcnts=*self.Mon_tcPtr
cnts=*self.dataPtr
tof=*self.xvalsPtr
;print,'instrument_details.fermispeed',instrument_details.fermispeed

Fermi_period=60000000.0/(2.0*(instrument_details.fermispeed))
;
;
;print,'Fermi_period = ',Fermi_period
;
;Extract distances
;MONtoDET=instrument_details.MONtoDET
FCtoDET=instrument_details.FCtoDET
;
;Define Plank's constant and neutron mass
h=6.6260755e-34
mn=1.67495e-27
;
;
;
;   sum the detectors
cnts=total(cnts,2)
;
;omit unwanted peaks
;mcnts-=50.0 ;converted to float
;whereltzero=where(mcnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    mcnts[whereltzero]=0.0
;endif
;
;whereltzero=where(cnts lt 0.0,thisnum)
;if thisnum gt 0 then begin
;    cnts[whereltzero]=0.0
;endif
;
;
coeff=[max(cnts),(tof[where(cnts eq max(cnts))])[0],70.0,0,0,0]
;print,'coeff =',coeff
dummy=gaussfit(tof,cnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,'p[i] =',p[i]
;endfor
;
det_time=p[1]
;print,'det time = ',det_time
;
;
;coeff=[max(mcnts),(tof[where(mcnts eq max(mcnts))])[0],70.0,0,0,0]
;print,'tof[where(mcnts eq max(mcnts))]',tof[where(mcnts eq max(mcnts))]
;dummy=gaussfit(tof,mcnts,p,estimates=coeff,nterms=6)
;for i=0,5 do begin
;print,'p[i] =',p[i]
;endfor
;
;mon_time=p[1]-Fermi_period
;While mon_time-Fermi_period gt 0 do begin
;mon_time-=Fermi_period
;endwhile

;print,'mon_time = ',mon_time

;t=(det_time-mon_time)*1e-6
t=det_time*1e-6
;print,'t = ',t
;v=montodet/t
v=FCtoDET/t
;
lambdaTOF=(h/(v*mn))*1e10
;print,'lambda =',lambda
;print,'instrument_details.lambda',instrument_details.lambda
; next calculate the tof shift
;   First calculate the time from FC to detector based upon new wavelength (velocity)
;t=(FCtoDET/v)*1e6
;compare to det_time
tof_shift=0.0
;tof_shift=t-det_time
;print, 'tof_shift = ',tof_shift
;tof should be added to the time bins
;print,tof
;print, 'tof = ',tof
;print,''
;tof+=tof_shift[0]
;print, 'tof = ',tof
;print,*self.xvalsPtr
endif
if elasticGroup[0] eq 2 then begin   ;   Elastic Line From Monochromator
lambda=instrument_details.lambda
tof_shift=0.0
;treat = 'Elastic Line Calculated From Monochromator Value'
;*self.treatmentPtr = [*self.treatmentPtr,treat]
endif
if elasticGroup[0] eq 3 then begin   ;   Elastic Line From Input Value
treat = 'Elastic Line Calculated From Input Value'
*self.treatmentPtr = [*self.treatmentPtr,treat]
widget_control,self.lambda_own_value,get_value = lambda
tof_shift=0.0
endif
;
;
if elasticGroup[0] eq 0 or elasticGroup[0] eq 1 then begin
tof_corr_structure={tof_corr_structure,tof_shift:tof_shift[0],lambdatof:lambdaTOF[0]}
*self.tof_corr_structurePtr=tof_corr_structure
endif else begin
tof_corr_structure={tof_corr_structure,tof_shift:tof_shift[0],lambdatof:lambda[0]}
*self.tof_corr_structurePtr=tof_corr_structure
endelse
;
widget_control,(*self.lambda_fieldPtr).lambda_monochromator,set_value = string(instrument_details.lambda)
if elasticgroup lt 3 then begin
widget_control,(*self.lambda_fieldPtr).lambda_tof,set_value = string(lambdaTOF[0])
endif else begin
widget_control,(*self.lambda_fieldPtr).lambda_tof,set_value = ''
endelse
;
;
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::subtract_bad_detectors,event = event,err = err,previous = previous
; this routine determines which detectors are to be remove, by
; a variety of different methods.  The detectors from the conventional banks are
; purged and grouped.
;extract data
widget_control,self.DetectorBankTypesGroup,get_value = DBT
widget_control,self.FormatTypesGroup,get_value = FormatType

data1d = *self.data1DPtr
Data2d = *self.data2dPtr
dimensions=size(data2d)
if dimensions[0] ne 0 then begin
ydim=dimensions[2]
xdim=dimensions[3]
endif else begin
    if (DBT eq 1) or (DBT eq 5) then begin
    DBT = 0
    widget_control,self.DetectorBankTypesGroup,set_value = DBT
    endif
ydim=1
xdim=1
endelse
tof2d = *self.xvals2dPtr
Error2d = *self.error2dPtr
detarr1d=0
detarr2d=0
widget_control,self.Det2d_Spikes,get_value = SpikeFactor
SpikeFactor=float(SpikeFactor[0])
error1D = *self.error1DPtr
detnum = *self.yvalsPtr
x = *self.xvalsPtr
ndet=self.ndet
file='BadDetectors.sav'
   fileOut = filepath(file,root_dir = self.workDir)


widget_control,self.Bad_DetectorGroup,get_value = treat
if n_elements(previous) eq 1 then treat = 3
;Bad_DetectorTypes = ['Automatic',$
;              'Graphical Masking', $
;              'Scroll Spectra Masking',$
;              'Previous Selection',  $
;              'Use All Detectors']
;print,'treat =',treat
CASE treat OF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; AUTOMATIC
0:  begin       ;automatic

IF DBT ne 5 then begin

; AUTOMATIC MASKING FOR THE 1D DETECTOR
; only take those detectors that have at least 1 count
; (i.e. ommit all dead detectors)

  good_det1D = where(total(data1d,1) ge 1.0) ; criterion: >0 cnts
  detarr1d=intarr(n_elements(detnum))
  detarr1d[good_det1D]=1 ;an array with all used detectors flagged with 1 (used for 'BadDetector.sav')
  *self.good_det1DPtr=good_det1D
  data1d=data1d[*,good_det1D]
  error1D=sqrt(data1d)
  detnum=detnum[good_det1D]

ENDIF ; IF DBT ne 5

; now for the 2d detector remove spikes
;print,'SpikeFactor: ',SpikeFactor

IF (DBT EQ 1) OR (DBT EQ 5) THEN BEGIN
detarr2d=intarr(ydim,xdim)+1
;can't think of a nicer way to do it
temp=fltarr(4)
;timestart=systime(1,/seconds)
for i = 0, ydim-1 do begin
    for j = 0, xdim- 1 do begin
       if i eq 0 then temp[0]=-1
       if i eq (ydim-1) then temp[1]=-1
       if j eq 0 then temp[2]=-1
       if j eq (xdim-1) then temp[3]=-1
if temp[0] ne -1 then temp[0] = total(data2d[*,i-1,j])
if temp[1] ne -1 then temp[1] = total(data2d[*,i+1,j])
if temp[2] ne -1 then temp[2] = total(data2d[*,i,j-1])
if temp[3] ne -1 then temp[3] = total(data2d[*,i,j+1])
newtemp=temp[where(temp ne -1)]
av=(moment(newtemp))[0]
;if av gt 1700.0 then begin
;help,newtemp
;print,'av: ',av
;print,'total(data2d[*,i,j]): ',total(data2d[*,i,j])
;endif
if av lt 0.0 then av = 1.0
if total(data2d[*,i,j]) gt av*SpikeFactor then detarr2d[i,j] = 0
temp[*]=0.0
    endfor
endfor
;timeend=systime(1,/seconds)
;print,'time to complete routine: ',timeend-timestart
;wherezero=where(detarr2d eq 0,count)
;print,'count: ',count
;print,'wherezero: ',wherezero

ENDIF ; IF (DBT EQ 1) OR IF (DBT EQ 5)

;help,detarr2d
detarr={detarr1d:detarr1d,detarr2d:detarr2d}
save, filename=fileout, detarr
;print, detarr1d
end ;treat EQ 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GRAPHICAL MASKING
1:  begin   ;graphical masking
;sort, remove degeneracies and then

detarr=Graphical_Masking(data1d,data2d,detnum,(*self.InstrumentPtr).lambda, SpikeFactor, $
       group_leader = event.top,WorkDir=self.workdir)
detarr1d=detarr.detarr1d
detarr2d=detarr.detarr2d
;print, detarr1d
whereone=where(detarr1d eq 1,count)
if count ne 0 then begin
data1d=data1d[*,whereone]
error1D=error1D[*,whereone]
detnum=detnum[whereone]
*self.good_det1DPtr=whereone
omitted=where(detarr1d eq 0)+1

;endif else begin
;  void = dialog_message(dialog_parent = event.top, $
;   'All Detectors Have Been Marked for Omission!  The Reduction Shall Now Proceed Employing All Detectors ')
;return
;endelse
endif
;help,data1d
;help,error1D
;help,detnum
save, filename=fileout, detarr
widget_control,self.Bad_DetectorGroup,set_value = 3
end ; treat eq 1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SCROLL SPECTRA MASKING
2:  begin   ;scroll spectra masking
detarr=Scroll_Spectra_Masking(data1d,error1D,detnum,x,data2d,Error2d,tof2d,SpikeFactor, $
                            group_leader = event.top,WorkDir=self.workdir)
detarr1d=detarr.detarr1d
detarr2d=detarr.detarr2d
whereone=where(detarr1d eq 1,count)
if count ne 0 then begin
data1d=data1d[*,whereone]
error1D=error1D[*,whereone]
detnum=detnum[whereone]
*self.good_det1DPtr=whereone
omitted=where(detarr1d eq 0)+1

;endif else begin
;  void = dialog_message(dialog_parent = event.top, $
;   'All Detectors Have Been Marked for Omission!  The Reduction Shall Now Proceed Employing All Detectors ')
;return
;endelse
endif
;help,data1d
;help,error1D
;help,detnum
save, filename=fileout, detarr
widget_control,self.Bad_DetectorGroup,set_value = 3
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; USE PREVIOUS
3:  begin  ;use previous
; first check if file is there
    if file_test(fileout) eq 0 then begin
      void = dialog_message(dialog_parent = event.top,/information, $
        'The file: '+fileout+' has not been found!  Switching to Graphical Masking Tool ')
      widget_control,self.Bad_DetectorGroup,set_value = 1
      detarr=Graphical_Masking(data1d,data2d,detnum,(*self.InstrumentPtr).lambda,SpikeFactor, $
        group_leader = event.top,WorkDir=self.workdir)
      detarr1d=detarr.detarr1d
      detarr2d=detarr.detarr2d
      whereone=where(detarr1d eq 1,count)
      if count ne 0 then begin
        data1d=data1d[*,whereone]
        error1D=error1D[*,whereone]
        detnum=detnum[whereone]
        *self.good_det1DPtr=whereone
        omitted=where(detarr1d eq 0)+1
        widget_control,self.qbin_group1,set_value = 0
      endif
      save, filename=fileout, detarr
      widget_control,self.Bad_DetectorGroup,set_value = 3
    endif else begin

    restore, fileout
    detarr1d=detarr.detarr1d
    detarr2d=detarr.detarr2d
    n=n_elements(detarr1d)
    if n eq ndet then begin
     whereone=where(detarr1d eq 1,count)
       if count ne 0 then begin
       data1d=data1d[*,whereone]
       error1D=error1D[*,whereone]
       detnum=detnum[whereone]
       *self.good_det1DPtr=whereone
       omitted=where(detarr1d eq 0)+1
       endif
    endif else begin
      void = dialog_message(dialog_parent = event.top,/information, $
   'Incompatible Array Dimensions.  Switching to Graphical Masking Tool ')
widget_control,self.Bad_DetectorGroup,set_value = 1
detarr=Graphical_Masking(data1d,data2d,detnum,(*self.InstrumentPtr).lambda,SpikeFactor, $
       group_leader = event.top,WorkDir=self.workdir)
    detarr1d=detarr.detarr1d
    detarr2d=detarr.detarr2d
whereone=where(detarr1d eq 1,count)
if count ne 0 then begin
data1d=data1d[*,whereone]
error1D=error1D[*,whereone]
detnum=detnum[whereone]
*self.good_det1DPtr=whereone
omitted=where(detarr1d eq 0)+1
widget_control,self.qbin_group1,set_value = 0
widget_control,self.Bad_DetectorGroup,set_value = 3
endif
save, filename=fileout, detarr
    endelse
    endelse
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; NO BAD DETECTOR REMOVAL
4:  begin ;no bad detector removal
;just write the file
detarr1d=1+intarr(n_elements(detnum))
detarr2d=intarr(ydim,xdim) + 1
detarr={detarr1d:detarr1d,detarr2d:detarr2d}
save, filename=fileout, detarr
*self.good_det1DPtr=indgen(ndet)
end
else:
endcase

if (FormatType eq 3) then begin
*self.AzimutalAnglePtr=(*self.AzimutalAnglePtr)[*self.good_det1DPtr]
*self.data1DPtr=data1d
*self.error1DPtr=error1D
*self.dataPtr=data1d
*self.errorPtr=error1D
*self.yvalsPtr=detnum
self.ndet=n_elements(detnum)


;print,omitted
totaldet=n_elements(*self.yvalsPtr)
remaining=n_elements(detnum)
removed=totaldet-remaining

n_omitted=n_elements(omitted)
;print,n_omitted
if n_omitted gt 0 then begin
    for i = 0, n_omitted-1 do begin
    if i eq 0 then begin
    omit_string =strtrim(string(omitted[0]),2)
    endif else begin
    omit_string =omit_string+','+strtrim(string(omitted[i]),2)
    endelse
    endfor
    omit_string='Excluded Detectors from the Conventional Banks: '+omit_string
    treat = ['Total Number of Detectors From the Conventional Banks Read From File: '+strtrim(string(totaldet),2)+'; ', $
       'Number of Detectors Excluded in the Reduction: '+strtrim(string(removed),2)+'; ', $
       omit_string+'; ', $
       strtrim(string(remaining),2)+' Detectors Reduced to '+strtrim(string(self.ndet),2)+ $
       ' With Unique Two Theta Angles'+'. ']
endif else begin
treat = ['Total Number of Detectors From the Conventional Banks Read From File: '+strtrim(string(totaldet),2)+'; ', $
       'Number of Detectors Excluded in the Reduction: '+strtrim(string(removed),2)+'; ', $
       strtrim(string(remaining),2)+' Detectors Reduced to '+strtrim(string(self.ndet),2)+ $
       ' With Unique Two Theta Angles'+'. ']
endelse

if n_elements(previous) eq 0 then begin ;only once
*self.treatmentPtr = [*self.treatmentPtr,treat]
endif
return
endif

IF DBT NE 5 THEN BEGIN  ;data include conventional bank


totaldet=n_elements(*self.yvalsPtr)
remaining=n_elements(detnum)
removed=totaldet-remaining
;
;print,'detnum =',detnum
;print,'good_det1D =',good_det1D
;print,'n_elements(good_det1D) =',n_elements(good_det1D)
;sort the data in ascending order of detnum
;
sortorder=sort(detnum)
detnum=detnum[sortorder]
data1d=data1d[*,sortorder]
;print,detnum
;
;
pnewdata=ptr_new(fltarr((size(data1d))[1],(size(data1d))[2]))
pnewdetnum=ptr_new(fltarr((size(detnum))[1]))
;remove degeneracies
;
(*pnewdetnum)[0]=detnum[0]
(*pnewdata)[*,0]=data1d[*,0]
j=0
for i=1,n_elements(detnum)-1 do begin
    if detnum[i] ne detnum[i-1] then begin
j+=1
(*pnewdetnum)[j]=detnum[i]
(*pnewdata)[*,j]=data1d[*,i]
endif else begin
(*pnewdata)[*,j]+=data1d[*,i]
endelse
endfor
data1d=(*pnewdata)[*,0:j]
error1D=sqrt(data1d)
detnum=(*pnewdetnum)[0:j]
ptr_free,pnewdata
ptr_free,pnewdetnum
;
*self.data1DPtr=data1d
*self.error1DPtr=error1D
*self.dataPtr=data1d
*self.errorPtr=error1D
*self.yvalsPtr=detnum
self.ndet=n_elements(detnum)


;print,omitted
n_omitted=n_elements(omitted)
;print,n_omitted
if n_omitted gt 0 then begin
    for i = 0, n_omitted-1 do begin
    if i eq 0 then begin
    omit_string =strtrim(string(omitted[0]),2)
    endif else begin
    omit_string =omit_string+','+strtrim(string(omitted[i]),2)
    endelse
    endfor
    omit_string='Excluded Detectors from the Conventional Banks: '+omit_string
    treat = ['Total Number of Detectors From the Conventional Banks Read From File: '+strtrim(string(totaldet),2)+'; ', $
       'Number of Detectors Excluded in the Reduction: '+strtrim(string(removed),2)+'; ', $
       omit_string+'; ', $
       strtrim(string(remaining),2)+' Detectors Reduced to '+strtrim(string(self.ndet),2)+ $
       ' With Unique Two Theta Angles'+'. ']
endif else begin
treat = ['Total Number of Detectors From the Conventional Banks Read From File: '+strtrim(string(totaldet),2)+'; ', $
       'Number of Detectors Excluded in the Reduction: '+strtrim(string(removed),2)+'; ', $
       strtrim(string(remaining),2)+' Detectors Reduced to '+strtrim(string(self.ndet),2)+ $
       ' With Unique Two Theta Angles'+'. ']
endelse

if n_elements(previous) eq 0 then begin ;only once
*self.treatmentPtr = [*self.treatmentPtr,treat]
endif

ENDIF ;IF DBT NE 5



IF (DBT NE 1) AND (DBT NE 5) then return
;now for the 2d detectors
*self.good_det2DPtr=where(detarr2d eq 1)
;first define dummy data pointers that willbe  required in all runs
;
N_tof2d=n_elements(tof2d)
dummydataPtr=ptr_new(intarr(N_tof2d,ydim,xdim))
dummyerrorPtr=ptr_new(intarr(N_tof2d,ydim,xdim))
;
;The distance and time binning are required only once
;
if n_elements(previous) eq 0 then begin

;time mapping, a complicated section of code.
;first bin the distances

widget_control,self.Det2d_DistanceBins,get_value = DB
DB=fix(DB[0])
    if (DB lt 10) or (DB gt 1000) then begin
    DB = 200
    widget_control,self.Det2d_DistanceBins,set_value = DB
    endif

MinDist=min(*self.distance2d,max = MaxDist)
step=(MaxDist-MinDist)/(DB+1)
GenDist=MinDist+step*(indgen(DB)+1)
N_GenDist=n_elements(GenDist)

for i = 0 , ydim-1 do begin
    for j = 0 , xdim-1 do begin
    OldDistance=(*self.distance2d)[i,j]
    diff=abs(GenDist-OldDistance)
    void=min(diff,index)
    (*self.distance2d)[i,j]=GenDist[index]
    endfor
endfor
;print,'MinDist: ',MinDist
;print,'MaxDist: ',MaxDist

;print,'GenDist: ',GenDist
;print,'N_GenDist: ',N_GenDist

;
totaldim=xdim*ydim
distancesPtr=ptr_new(fltarr(totaldim))
newdistancesPtr=ptr_new(fltarr(totaldim))
k=0
for i = 0 , ydim-1 do begin
    for j = 0 , xdim-1 do begin
(*distancesPtr)[k]=(*self.distance2d)[i,j]
k+=1
    endfor
endfor
(*newdistancesPtr)[0]=(*distancesPtr)[0]
j=0
for i=1,totaldim-1 do begin
    found=where((*distancesPtr)[i] eq *newdistancesPtr)
    if found eq -1 then begin
    j+=1
    (*newdistancesPtr)[j]=(*distancesPtr)[i]
    endif
endfor
ptr_free,distancesPtr
*newdistancesPtr=(*newdistancesPtr)[0:j]
;print,'totaldim: ',totaldim
;print,'n_elements(*newdistancesPtr): ',n_elements(*newdistancesPtr)
TotalUniqueDistances=n_elements(*newdistancesPtr)
DistancePtr=ptr_new(intarr(ydim,xdim))
for i = 0 , ydim-1 do begin
    for j = 0 , xdim-1 do begin
index=where(*newdistancesPtr eq (*self.distance2d)[i,j])
(*DistancePtr)[i,j]=index
    endfor
endfor

;print,'(*DistancePtr)[0,0]: ',(*DistancePtr)[0,0]
;print,'(*DistancePtr)[40,*]: ', (*DistancePtr)[40,*]
;print,'min(*newdistancesPtr): ', min(*newdistancesPtr)
;print,'max(*newdistancesPtr): ', max(*newdistancesPtr)

timecor=2500.0/*newdistancesPtr
ProjTimeArrayPtr=ptr_new(fltarr(N_tof2d,TotalUniqueDistances))
;we need only do the distance and time biining once.  The relevant
;information is stored in the pointer *self.Data2dIndexPtr
*self.Data2dIndexPtr=intarr(N_tof2d,ydim,xdim)
for i = 0 , TotalUniqueDistances-1 do begin
(*ProjTimeArrayPtr)[*,i]=tof2d*timecor[i]
endfor
u_tof2d=bytarr(n_elements(tof2d))+1
;project tof2d onto dummytime
;tof2d#u_tof2d creates n_elements(tof2d) rows of tof2d
;u_tof2d#reform((*ProjTimeArrayPtr)[*,0,0]); creates n_elements(tof2d) columns of (*ProjTimeArrayPtr)[*,0,0]
starttimei=systime(/seconds)
for i = 0 , TotalUniqueDistances-1 do begin
       wherei=where(*DistancePtr eq i)
       xcoord=wherei/ydim
       ycoord=wherei-xcoord*ydim
;       if i eq 0 then begin
;        print,'i: ',i
;       print,'wherei: ',wherei
;       endif
;       print,''

;diff=abs(u_tof2d#tof2d-reform((*ProjTimeArrayPtr)[*,i])#u_tof2d)
diff=abs(u_tof2d#reform((*ProjTimeArrayPtr)[*,i])-tof2d#u_tof2d)
;starttimek=systime(1,/seconds)
       for k = 0, N_tof2d-1 do begin
       void=min(diff[k,*],ind)
 ;      print,'void: ',void
;    if (ind eq 0) then begin
;    if (i eq 0) and (k lt 5) then begin
;    print,'(*newdistancesPtr)[i] : ',(*newdistancesPtr)[i]
;    print,'reform((*ProjTimeArrayPtr)[0,i]) : ',reform((*ProjTimeArrayPtr)[0,i])
;    print,'reform((*ProjTimeArrayPtr)[1,i]) : ',reform((*ProjTimeArrayPtr)[1,i])
;    print,'i : ',i
;    print,'k : ',k
;    print,'ind : ',ind
;    endif
       (*dummydataPtr)[k,ycoord,xcoord]=data2d[ind,ycoord,xcoord]
       (*dummyerrorPtr)[k,ycoord,xcoord]=Error2d[ind,ycoord,xcoord]
       (*self.Data2dIndexPtr)[k,ycoord,xcoord]=ind ; to be used in subsequent runs
;       if k eq 500 and ycoord eq 20 and xcoord eq 20 then print,'ind = ',ind
;       if k eq 500 and ycoord eq 20 and xcoord eq 20 then print,'ind = ',ind
       endfor
;endtimek=systime(1,/seconds)
;print,'time to complete middle loop: ',endtimek-starttimek
endfor
endtimei=systime(/seconds)
;print,'time to complete loops: ',endtimei-starttimei
widget_control,self.Det2d_TimeToMap,set_value = endtimei-starttimei
endtimes=(*ProjTimeArrayPtr)[N_tof2d-1,*]
void=min(abs(tof2d-min(endtimes)),TerminateIndex)
self.TerminateIndex=TerminateIndex
ptr_free,newdistancesPtr,DistancePtr,ProjTimeArrayPtr
;print,'total((*dummydataPtr)): ',total((*dummydataPtr))
;print,'total(data2d): ',total(data2d)
;print,'total((*dummydataPtr)[*,1,0]): ',total((*dummydataPtr)[*,1,0])
;print,'total(data2d[*,1,0]): ',total(data2d[*,1,0])
;print,'(*dummydataPtr)[*,0,0]: ',(*dummydataPtr)[*,0,0]
;print,'(data2d[*,0,0]: ',data2d[*,0,0]

totaldets=xdim*ydim
wherezero=where(detarr2d eq 0,removed)
remaining=totaldets-removed
omitted=strarr(removed+1)
omitted[0]='Detectors to be omitted {x,y}'
if removed ne 0 then begin
for k = 1, removed do begin
xcoord=wherezero[k-1]/ydim
ycoord=wherezero[k-1]-xcoord*ydim
omitted[k]='{'+strtrim(string(xcoord),2)+','+strtrim(string(ycoord),2)+'}'
endfor
endif
n_omitted=n_elements(omitted)

treat=strarr(10+n_omitted)
treat[0]='Total Number of 2d Pixels Read From File: '+strtrim(string(totaldets),2)+'; '
treat[1]='Y dimension: '+strtrim(string(ydim),2)+'; '+'X dimension: '+strtrim(string(xdim),2)+'; '
treat[2]='Number of Detectors Excluded in the Reduction: '+strtrim(string(removed),2)+'; '
treat[3]='Co-ordinates of 2d detectors removed: '
treat[4:4+n_omitted-1]=omitted
treat[n_omitted-1+5]='Number of Pixels Grouped to '+strtrim(string(TotalUniqueDistances),2)+' in the distance binning routine'
*self.treatmentPtr = [*self.treatmentPtr,treat[where(treat ne '')]]


endif else begin  ;if n_elements(previous) eq 0 then begin
for i = 0 , ydim-1 do begin
    for j = 0 , xdim-1 do begin
       ind=(*self.Data2dIndexPtr)[*,i,j] ;eliminate the third loop
        (*dummydataPtr)[*,i,j]=data2d[ind,i,j]
        (*dummyerrorPtr)[*,i,j]=Error2d[ind,i,j]
    endfor
endfor
;print,'total((*dummydataPtr)[*,1,0]): ',total((*dummydataPtr)[*,1,0])
;print,'total(data2d[*,1,0]): ',total(data2d[*,1,0])
;
;*dummydataPtr=data2d[*self.Data2dIndexPtr]
;*dummyerrorPtr=Error2d[*self.Data2dIndexPtr]
TerminateIndex=self.TerminateIndex
;print,'total(*dummydataPtr): ',total(*dummydataPtr)
;print,'total(data2d): ',total(data2d)
endelse  ;if n_elements(previous) eq 0 then begin
;theta bin
starttimei=systime(/seconds)
;print,'TerminateIndex: ',TerminateIndex
;print,'data2d[*,0,0]: ',data2d[*,0,0]
;print,''
data2d=(*dummydataPtr)[0:TerminateIndex,*,*]
error2d=(*dummyerrorPtr)[0:TerminateIndex,*,*]
tof2d=tof2d[0:TerminateIndex]
;print,'data2d[*,0,0]: ',data2d[*,0,0]
ptr_free,dummydataPtr,dummyerrorPtr

;the theta binning does not take much time so it is little problem to do it again

;help,data2d
;bin in theta


;*self.theta2d
widget_control,self.Det2d_ThetaBins,get_value = TB
TB=fix(TB[0])
    if (TB lt 2) or (TB gt 100) then begin
    TB = 20
    widget_control,self.Det2d_ThetaBins,set_value = TB
    endif


MinTheta=min(*self.theta2d,max = MaxTheta)
step=(MaxTheta-MinTheta)/(TB+1)
GenTheta=MinTheta+step*(indgen(TB)+1)
N_GenTheta=n_elements(GenTheta)

newdata2d=fltarr((TerminateIndex+1),N_GenTheta)
newerror2d=fltarr((TerminateIndex+1),N_GenTheta)

;print,'GenTheta:',GenTheta
;return
  x_in = reform(*self.theta2d)
  x_in = x_in[where(detarr2d eq 1)]
sortorder=sort(x_in)
  x_in = x_in[sortorder]
;print,'x_in :',x_in

z_in=fltarr(TerminateIndex+1,n_elements(x_in))
dz_in=fltarr(TerminateIndex+1,n_elements(x_in))

for i = 0 , TerminateIndex do begin
  temp = reform(data2d[i,*,*])
  temp=temp[where(detarr2d eq 1)]
  z_in[i,*]=reform(temp)
  temp = reform(error2d[i,*,*])
  temp=temp[where(detarr2d eq 1)]
  dz_in[i,*]=reform(temp)
endfor
z_in=z_in[*,sortorder]
dz_in=dz_in[*,sortorder]
;
;we must remove degeneracies before binning
;
pnewz_in=ptr_new(fltarr((size(z_in))[1],(size(z_in))[2]))
pnewdz_in=ptr_new(fltarr((size(dz_in))[1],(size(dz_in))[2]))
pnewx_in=ptr_new(fltarr((size(x_in))[1]))
;remove degeneracies
;
(*pnewx_in)[0]=x_in[0]
(*pnewz_in)[*,0]=z_in[*,0]
(*pnewdz_in)[*,0]=dz_in[*,0]
j=0
for i=1,n_elements(x_in)-1 do begin
    if x_in[i] ne x_in[i-1] then begin
j+=1
(*pnewx_in)[j]=x_in[i]
(*pnewz_in)[*,j]=z_in[*,i]
(*pnewdz_in)[*,j]=dz_in[*,i]
endif else begin
(*pnewz_in)[*,j]+=z_in[*,i]
(*pnewdz_in)[*,j]=sqrt((*pnewdz_in)[*,j]^2+dz_in[*,i]^2)
endelse
endfor
z_in=(*pnewz_in)[*,0:j]
dz_in=(*pnewdz_in)[*,0:j]
x_in=(*pnewx_in)[0:j]
ptr_free,pnewz_in
ptr_free,pnewdz_in
ptr_free,pnewx_in


for i = 0 , TerminateIndex do begin
  zin = reform(z_in[i,*])
  dzin=reform(dz_in[i,*])
  drebin,x_in,zin,dzin,GenTheta,z_out,dz_out,/points,/to_points, $
     err = err,emsg = emsg
newdata2d[i,*] = z_out
newerror2d[i,*] = dz_out
endfor
print,'err: ',err
print, 'emsg: ',emsg
endtimei=systime(/seconds)
widget_control,self.Det2d_TimeThetaBins,set_value = endtimei-starttimei
;print,'newdata2d[*,0] : ',newdata2d[*,0]
;help,newdata2d
;help,newerror2d

treat='Number of Pixels further Reduced to '+strtrim(string(N_GenTheta),2)+' in the theta binning routine'
;what do we do with the data

;phew

if DBT eq 1 then begin ; merge all

y=[GenTheta,detnum]
self.ndet=n_elements(y)

;the time bins must be the same in order to concatenate

;print,'x[0] ',x[0]
;print,'tof2d[0] ',tof2d[0]

wherele=where(x le tof2d,count)
;print,'wherele:',wherele
x=x[wherele]
*self.xvalsPtr=x
*self.Mon_tcPtr=(*self.Mon_tcPtr)[wherele]
data1d=data1d[wherele,*]
error1d=error1d[wherele,*]

z=fltarr(count,self.ndet)
dz=fltarr(count,self.ndet)

z[*,0:N_GenTheta-1]=newdata2d
dz[*,0:N_GenTheta-1]=newerror2d
z[*,N_GenTheta:*]=data1d
dz[*,N_GenTheta:*]=error1d


;remove degeneracies and sort
sortorder=sort(y)
  y = y[sortorder]


pnewz=ptr_new(fltarr((size(z))[1],(size(z))[2]))
pnewdz=ptr_new(fltarr((size(dz))[1],(size(dz))[2]))
pnewy=ptr_new(fltarr((size(y))[1]))
;remove degeneracies
;
(*pnewy)[0]=y[0]
(*pnewz)[*,0]=z[*,0]
(*pnewdz)[*,0]=dz[*,0]
j=0
for i=1,n_elements(y)-1 do begin
    if y[i] ne y[i-1] then begin
j+=1
(*pnewy)[j]=y[i]
(*pnewz)[*,j]=z[*,i]
(*pnewdz)[*,j]=dz[*,i]
endif else begin
(*pnewz)[*,j]+=z[*,i]
(*pnewdz)[*,j]=sqrt((*pnewdz)[*,j]^2+dz[*,i]^2)
endelse
endfor
*self.dataPtr=(*pnewz)[*,0:j]
*self.errorPtr=(*pnewdz)[*,0:j]
*self.yvalsPtr=(*pnewy)[0:j]
self.ndet=n_elements(*self.yvalsPtr)
ptr_free,pnewz
ptr_free,pnewdz
ptr_free,pnewy
treat=[treat,'Data from the conventional banks and the 2d detector have been merged']
treat=[treat,'Number of Unique detector angles: '+strtrim(string(self.ndet),2)]
endif

if DBT[0] eq 5 then begin ; just the 2d

wherele=where(x le tof2d,count)
*self.Mon_tcPtr=(*self.Mon_tcPtr)[wherele]
*self.yvalsPtr=GenTheta
self.ndet=N_GenTheta
*self.xvalsPtr=tof2d
*self.dataPtr=newdata2d
*self.errorPtr=newerror2d


endif

if n_elements(previous) eq 0 then begin ;only once
*self.treatmentPtr = [*self.treatmentPtr,treat]
endif



return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Sum_Vandium_Runs,event = event,err = err

err = 0
if n_elements(*self.vanFilePtr) eq 0 then begin
  err = -1
  return
endif

files = *self.vanFilePtr
nfiles = n_elements(files)
;print,'nfiles = ',nfiles
treat = 'Files used in vanadium calibration:: '
for i = 0,nfiles-1 do begin
  treat = [treat,files[i]]
  self->Nexus_read_raw_focus,files[i],event = event,err = err
  if err eq 1 then return
  if i eq 0 then begin
    data1d = *self.data1dPtr
    data2d = *self.data2dPtr
    temperature = *self.tempPtr
    Mon_cum = *self.Mon_cumPtr
    Mon_tc = *self.Mon_tcPtr
  endif else begin
  ;print,'data[544,17] = ',data[544,17]
    data1d = data1d+*self.data1dPtr
    data2d = data2d+*self.data2dPtr
      ;print,'data[544,17] = ',data[544,17]
    temperature = [temperature,*self.tempPtr]
    Mon_cum = [Mon_cum,*self.Mon_cumPtr]
    ;Mon_tc = [Mon_tc,*self.Mon_tcPtr]
    ;Mon_cum += *self.Mon_cumPtr
    Mon_tc += *self.Mon_tcPtr

  endelse
endfor

*self.treatmentPtr = [*self.treatmentPtr,treat]
error1d = sqrt(data1d)
error2d = sqrt(data2d)
where_zero = where(data1d eq 0,count_zero)
if count_zero gt 0 then error1d[where_zero] = 1.0
where_zero = where(data2d eq 0,count_zero)
if count_zero gt 0 then error2d[where_zero] = 1.0
*self.data1dPtr = data1d
*self.error1dPtr = error1d
*self.data2dPtr = data2d
*self.error2dPtr = error2d
*self.Mon_cumPtr = Mon_cum
*self.Mon_tcPtr = Mon_tc
*self.tempPtr = temperature

return

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::sum_runs,event = event,err = err
err = 0
if n_elements(*self.sigFilePtr) eq 0 then begin
  err = -1
  return
endif

files = *self.sigFilePtr
nfiles = n_elements(files)
;print,'nfiles = ',nfiles
treat = 'Files used in sum: '
for i = 0,nfiles-1 do begin
  treat = [treat,files[i]]
  self->Nexus_read_raw_focus,files[i],event = event,err = err
  if err eq 1 then return
  if i eq 0 then begin
    data1d = *self.data1dPtr
    data2d = *self.data2dPtr
    temperature = *self.tempPtr
    Mon_cum = *self.Mon_cumPtr
    Mon_tc = *self.Mon_tcPtr
  endif else begin
  ;print,'data[544,17] = ',data[544,17]
    data1d = data1d+*self.data1dPtr
    data2d = data2d+*self.data2dPtr
      ;print,'data[544,17] = ',data[544,17]
    temperature = [temperature,*self.tempPtr]
    Mon_cum = [Mon_cum,*self.Mon_cumPtr]
    ;Mon_tc = [Mon_tc,*self.Mon_tcPtr]
    ;Mon_cum += *self.Mon_cumPtr
    Mon_tc += *self.Mon_tcPtr

  endelse
endfor

*self.treatmentPtr = [*self.treatmentPtr,treat]
error1d = sqrt(data1d)
error2d = sqrt(data2d)
where_zero = where(data1d eq 0,count_zero)
if count_zero gt 0 then error1d[where_zero] = 1.0
where_zero = where(data2d eq 0,count_zero)
if count_zero gt 0 then error2d[where_zero] = 1.0
*self.data1dPtr = data1d
*self.error1dPtr = error1d
*self.data2dPtr = data2d
*self.error2dPtr = error2d
*self.Mon_cumPtr = Mon_cum
*self.Mon_tcPtr = Mon_tc
*self.tempPtr = temperature

return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::subtract_background,event = event, zerobgrd = zerobgrd
;
; This routine takes care of backgroudn subtraction and
; self-shielding corrections (if requested)
; in order to perform self-shielding correction w/o background
; this routine must be called even if no background has been specified
; in this case keyword 'zerobgrd' is set by call from 'reduce'
;
; In order to subtract the background we must do a few things first.....
;
; 1.  Pull out the signal data and store it in local variables.  We are assuming
;     that the data has been converted to energy.
; 2.  Read in and sum up all of the background files.
; 3   Remove bad detectors, sort, and remove degeneracies the same way as applied for the signal data
; 4.  Convert to energy and normalize to the monitor.
; 5.  Rebin the background onto the same energy grid as the signal file.
; 6.  Perform the subtraction scaling the background up to the signal file.
; 7.  Correct for self-shielding of the sample and background if requested
;

if n_elements(*self.dataPtr) eq 0 then return

CATCH, Error_status
if Error_status ne 0 then begin
  catch, /cancel
  message=strarr(3)
  message[0]='Unable to subtract background and/or perform self-shielding corrections.'
  message[1]='Check to see whether your SAF/SSF file is correct.'
  message[2]='Error Message from IDL: '+!ERROR_STATE.MSG
  void=dialog_message(dialog_parent=event.top,/error,message)
  return
endif
;
; Store the signal data locally while determining the background signal --------

sigData = *self.dataPtr
sigError = *self.errorPtr
sigx = *self.xvalsPtr
sigy = *self.yvalsPtr
sigTemp = *self.tempPtr
sigMon_cum = *self.Mon_cumPtr
sigMon_tc = *self.Mon_tcPtr
signdet=self.ndet
Sample_instrument_details=*self.InstrumentPtr

; in case we have no bgrd then set bgrd to zero --------------------------------

if keyword_set(zerobgrd) then begin
  bgData=sigData*0.
  bgError=sigError*0.
  sf=0.
endif else begin

; we have a background to treat-------------------------------------------------

nbgFiles = n_elements(*self.bgFilePtr)
bgFiles = *self.bgFilePtr

treat = 'Background file(s) used in subtraction:'
; Sum the background files if there are more than one
for i = 0,nbgfiles-1 do begin
  treat = [treat,bgfiles[i]]
    self->Nexus_read_raw_focus,bgfiles[i],event = event
  if i eq 0 then begin
    bgtemperature = *self.tempPtr
    bgMon_cum = *self.Mon_cumPtr
    bgMon_tc = *self.Mon_tcPtr
    bgdata1d = *self.data1dPtr
    bgdata2d = *self.data2dPtr
  endif else begin
    bgdata1d = bgdata1d+*self.data1dPtr
    bgdata2d = bgdata2d+*self.data2dPtr
    bgtemperature = [bgtemperature,*self.tempPtr]
    bgMon_cum = [bgMon_cum,*self.Mon_cumPtr]
    ;bgMon_tc = [bgMon_tc,*self.Mon_tcPtr]
    bgMon_tc += *self.Mon_tcPtr
  endelse
endfor
*self.data1dPtr=bgdata1d
*self.data2dPtr=bgdata2d
*self.treatmentPtr = [*self.treatmentPtr,treat]
*self.tempPtr = bgtemperature
*self.Mon_cumPtr = bgMon_cum
*self.Mon_tcPtr = bgMon_tc

widget_control,self.DetectorBankTypesGroup,get_value = DBT
widget_control,self.FormatTypesGroup,get_value = FormatType

if (DBT EQ 1) OR (DBT EQ 5) OR (FormatType EQ 3) then begin
  self->subtract_bad_detectors,event = event,err = err,/PREVIOUS
  detnum=*self.yvalsPtr
endif else begin
  detnum=*self.yvalsPtr
  good_det1D=*self.good_det1DPtr
  bgData=bgData1d[*,good_det1D]
  detnum=detnum[good_det1D]
  ;sort the data in ascending order of detnum
  sortorder=sort(detnum)
  detnum=detnum[sortorder]
  bgdata=bgdata[*,sortorder]
  pnewdata=ptr_new(fltarr((size(bgdata))(1),(size(bgdata))(2)))
  pnewdetnum=ptr_new(fltarr((size(detnum))(1)))
  ;remove degeneracies
  (*pnewdetnum)[0]=detnum[0]
  (*pnewdata)[*,0]=bgdata[*,0]
  j=0
  for i=1,n_elements(detnum)-1 do begin
    if detnum(i) ne detnum(i-1) then begin
      j+=1
      (*pnewdetnum)[j]=detnum[i]
      (*pnewdata)[*,j]=bgdata[*,i]
    endif else begin
     (*pnewdata)[*,j]+=bgdata[*,i]
    endelse
  endfor
  bgData=(*pnewdata)[*,0:j]
  detnum=(*pnewdetnum)[0:j]
  ptr_free,pnewdata
  ptr_free,pnewdetnum
  *self.dataPtr = bgData
  bgError = sqrt(bgData)
  *self.errorPtr = bgError
  *self.yvalsPtr = detnum
endelse
widget_control,self.BackgroundSubtractionField,get_value = ScaleFactor
ScaleFactor=float(ScaleFactor[0])
;convert to energy unless the desired quantity is S(theta,t)
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
if DataOutput ne 2 then self->convert_to_energy,event = event
bgx = *self.xvalsPtr
bgData = *self.dataPtr
bgError = *self.errorPtr
sigMon = total(sigMon_cum)
bgMon = total(bgMon_cum)
sf = (ScaleFactor*sigMon/bgMon)

endelse

; now subtract and perform the self-shielding correction -----------------------

newData = sigData
newError = sigError

datSize = size(sigData)
nchan = datSize[1]
ndet = datSize[2]
detnum=sigy

; do we correct for self-shielding?
if (self.SelfShieldFilename eq '') then begin
  saf=fltarr(ndet)+1.0  ; no correction SAF=SSF=1
  ssf=saf
endif else begin
  ; read in 3 column ascii file (TTH,SAF,SSF)
  if query_ascii(self.SelfShieldFilename) ne 1 then message,'invalid SAF/SSF file.'
  data=read_ascii(self.SelfShieldFilename)
  dims=size(data.field1,/dim)
  if (dims[0] ne 3) or (dims[1] lt 2) then message,'invalid SAF/SSF file.'
  xs=data.field1[0,*]
  ys1=data.field1[1,*]
  ys2=data.field1[2,*]
  ; interpolate linearily for given two-theta of detectors
  tth=detnum
  if (min(xs) gt min(tth)) or (max(xs) lt max(tth)) then message,'supplied SAF/SSF not within two-theta range of detectors [',min(tth),',',max(tth),'].'
  saf=interpol(ys1,xs,tth)
  ssf=interpol(ys2,xs,tth)
  *self.treatmentPtr = [*self.treatmentPtr,'Self-shielding taken into account, SAF/SSF file: ',self.SelfShieldFilename]
endelse
saf=(fltarr(nchan)+1.)#saf  ; for all time channels
ssf=(fltarr(nchan)+1.)#ssf  ; for all time channels

; the actual subtraction and self-shielding correction -------------------------
newData = (sigData - saf*(sf*bgData))/ssf
newError = sqrt(sigError^2/ssf + saf*(sf*bgError)^2/ssf)

; store the resulting data -----------------------------------------------------
*self.xvalsPtr = sigx
*self.dataPtr = newData
*self.errorPtr = newError
*self.tempPtr = sigTemp;[sigTemp,bgtemperature]
;*self.Mon_cumPtr = [sigMon_cum,bgMon_cum]
;*self.Mon_tcPtr = [sigMon_tc,bgMon_tc]
*self.Mon_cumPtr = sigMon_cum
*self.Mon_tcPtr = sigMon_tc
self.ndet=signdet
*self.InstrumentPtr=Sample_instrument_details
return
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::flat_baseline,event = event
widget_control,self.flat_baseline_range,get_value = range

; Store the signal data locally
z = *self.dataPtr
;dz = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
nx=n_elements(x)
ny=n_elements(y)

; get the range value from the GUI, set to default if undetermined
if range lt 2 or range gt nx then begin
  range = 100
  widget_control,self.flat_baseline_range,set_value = range
endif
range=fix(range[0])

; algorithm: 
;   for each detector individually:
;     split the TOF channels into groups of 'range' channels
;     get mean intensity value of each group
;     determine minimum of these mean values
;     subtract this minimum (flat baseline) from all TOF channels
for i=0,ny-1 do begin  ; for all detectors
  minrangemean = max(z[*,i])
  for j=0,(nx-range)-1,range do begin  ; for all channels
    rangemean = mean(z[j:j+range-1,i])  ; mean over range (to the right)
    minrangemean = minrangemean < rangemean  ; take min
  endfor
  ;print," det:",i,"  -> minrangemin = ",minrangemean
  z[*,i]-=minrangemean
endfor
    
; old code by Philip / Fanni
;for i=0,ny-1 do begin
;  print,'initial min =',min(z[*,i])
;  j=0
;  mean=0.0
;  tempmean=(moment(z[j:(j+range-1),i]))[0] 
;  mean=tempmean
;  j+=range
;  while (j+range-1) le nx-1 do begin
;    tempmean=(moment(z[j:(j+range-1),i]))[0]
;    if tempmean lt mean then mean = tempmean
;    j+=range
;  endwhile
;  if j le nx-1 then begin
;    tempmean=(moment(z[j:*,i]))[0]
;    if tempmean lt mean then mean = tempmean
;    z[*,i]-=mean
;    print,'mean =',mean
;  endif
;  print,'final min =',min(z[*,i])
;endfor

; store the corrected intensities
; we assume no error in the subtracted flat bgrd, i.e. errors remain unchanged
treat = ['Flat Baseline Correction Has Been Applied to the Data.  Number of Channels: '+strtrim(string(range),2)]
    *self.treatmentPtr = [*self.treatmentPtr,treat]
*self.dataPtr=z
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::convert_to_energy,event = event, not4=not4

;return
;
; Store the relevant signal data locally
sigData = *self.dataPtr
sigError = *self.errorPtr
sigx = *self.xvalsPtr
sigy = *self.yvalsPtr
ny=n_elements(sigy)
nx=n_elements(sigx)
instrument_details = *self.InstrumentPtr
tof_corr_structure=*self.tof_corr_structurePtr
;Define Plank's constant and neutron mass
h=6.6260755e-34
mn=1.67495e-27
;joules to meV conversion factor
jtomeV=6.241504661e21
;Extract lambda zero
lambda0=tof_corr_structure.lambdatof
;Extract TOF shift
tof_shift=tof_corr_structure.tof_shift
;Add to tof values
;print, 'lambda0 =',lambda0
;help,lambda0

;print, 'sigx =',sigx
;help,sigx

sigx+=tof_shift
;print, 'sigxcorr =',sigx
;help,sigx
;Extract Distances
FCtoSAM=instrument_details.FCtoSAM
FCtoDET=instrument_details.FCtoDET
SAMtoDET=instrument_details.SAMtoDET
;print,'instrument_Details =',instrument_details
;
;Calculate t0, the time for all neutrons to travel from the FC to the Sample
t0=FCtoSAM/(h*1e10/(lambda0*mn))
;help,t0
;subtract this value from sigx to get tf (flight time in the secondary instrument)
;convert to seconds
sigx/=1e6
tf=sigx-t0
;help,tf
nx = n_elements(tf)
;print,'nx =',nx
;  calculate v0, k0 and E0
;print,'lambda0 =',lambda0
;
v0=(h*1e10/(lambda0*mn))
;print,'v0 =',v0
k0=2.0*!dpi*1e10/lambda0
;print,'k0 =',k0
E0=mn*v0^2/2.0
;that should give E0 in joules, now convert to meV
E0*=jtomeV
vf=SAMtoDET/tf
lambdaf=(h/(vf*mn))*1e10
kf=2.0*!dpi*1e10/lambdaf
Ef=mn*vf^2/2.0
Ef*=jtomeV
E_trans=E0-Ef

;t^4 correction of intensity, unless not required, e.g. for V-calibration
if not(keyword_set(not4)) then begin
  norm=(total(tf^4))/nx
  for i = 0, (size(sigdata))[2]-1 do begin
    sigdata[*,i] = sigData[*,i]*(tf^4)/norm
    sigerror[*,i] = sigerror[*,i]*(tf^4)/norm
  endfor
endif

;whereltzero=where(sigdata lt 0,count1)
;IF count1 ne 0 then begin
;for i=0,ny-1 do begin
;whereltzero=where(sigdata[*,i] lt 0,count)
;if count ne 0 then begin
;;print,'wooooof',count,n_elements(sigdata)
;minz=min(sigdata[*,i])
;;print,minz
;sigdata[*,i]-=minz
;endif
;endfor
;ENDIF
wherezero=where(sigerror eq 0,count)
if count ne 0 then begin
mindz=min(sigerror)
sigerror[wherezero]=mindz
endif
;   Is Detailed balance requested:
widget_control,self.Misc1Group,get_value = val
if val[1] eq 1 then begin
;print,E_trans
c=2.0*instrument_details.temp[0]*0.08617385692

for i = 0, nx-1 do begin
sigdata[i,*]*=exp(-E_trans[i]/c)
sigerror[i,*]*=exp(-E_trans[i]/c)
endfor

treat = ['Detailed Balance Correction Has Been Applied to the Data.']
*self.treatmentPtr = [*self.treatmentPtr,treat]


endif

;help,sigdata
*self.dataPtr=sigdata
*self.errorPtr=sigerror
*self.xvalsPtr=E_trans
return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

pro focusreduction::detefficiencyE,event=event

;corrects for energy dependent detector efficiency
; I = I0 * a * exp[-eta1/sqrt[E]]*(1-exp[-eta2/sqrt[E]])
; values for conventional 1D detector tubes of FOCUS see below
a = 0.985
eta1 = 0.017
eta2 = 5.818

;store the relevant signal data locally
sigData = *self.dataPtr
sigError = *self.errorPtr
sigx = *self.xvalsPtr
sigy = *self.yvalsPtr
ny=n_elements(sigy)
nx=n_elements(sigx)
tof_corr_structure=*self.tof_corr_structurePtr

;calculate correction factor (as a function of energy at the detector)
lambda0=tof_corr_structure.lambdatof  ; incoming wavelength
e0=81.80320651d/lambda0^2  ; incoming energy (<-> elastic line)
EE=e0-sigx  ; total energy (transfer + incoming -> energy at detector)
f = a*exp(-eta1/sqrt(EE))*(1.0-exp(-eta2/sqrt(EE)))

;cast onto dimension of count arrays (channel:detector)
f = f # make_array(ny,/float,value=1.0)
sigData /= f
sigError /=f

;write down changes
treat = ['Energy dependent detector effeciency taken into account.']
*self.treatmentPtr = [*self.treatmentPtr,treat]
*self.dataPtr = sigData
*self.errorPtr = sigError

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

pro focusreduction::normalize_to_monitor,event=event,normalize_mode=normalize_mode

  ;normalizes to monitor or unity
  
  treat='The data have been normalized to '
  if normalize_mode eq 0 then begin
    f=total(*self.Mon_cumPtr)
    treat=treat+'monitor'
  endif else begin
    f=max(*self.dataPtr)
    treat=treat+'unity'
  endelse
  *self.dataPtr/=f
  *self.errorPtr/=f
  self.NormFactor=f
  *self.treatmentPtr = [*self.treatmentPtr,treat]
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::display,event = event
; This method plots the data (if present) to a pixmap then to the screen.
wset,self.winPix
self->plotData,event = event
wset,self.winVis
device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.winPix]
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::resize,event = event
; This method allows the user to resize the application interface while changing
; the size of the plot window accordingly.

ctrlgeom = widget_info(self.ctrlbase,/geometry)
tlbgeom = widget_info(self.tlb,/geometry)
xsize = event.x
ysize = event.y

; New data window dimensions
newxsize = xsize-ctrlgeom.xsize
newysize = ysize > ctrlgeom.ysize

widget_control,self.win,draw_xsize = newxsize, $
               draw_ysize = newysize
wdelete,self.winPix
window,/free,/pixmap,xsize = newxsize,ysize = newysize
self.winPix = !d.window
self->display,event = event
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::treatmentHandler,event = event
; This method responds to changes in the state of the
; treatment control by sensitizing or desensitizing appropriate
; buttons as necessary.
widget_control,self.treatGroup,get_value = vals
widget_control,self.van_Base,sensitive = vals[0]
widget_control,self.Bg_Base,sensitive = vals[1]
;
widget_control,self.DiffONGroup,get_value = DiffON
widget_control,self.Diffraction_Base1,sensitive = vals[0]
if vals[0] eq 0 then widget_control,self.Diffraction_Base2,sensitive = vals[0]
if vals[0] eq 1 and DiffON eq 1 then widget_control,self.Diffraction_Base2,sensitive = vals[0]
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::LambdaHandler,event = event
; This method responds to changes in the state of the
; lambda own field by sensitizing or desensitizing according to whether
;   the own value button is selected
widget_control,self.elasticGroup,get_value = val
if val eq 0 then widget_control,self.elastic_base_sensitive,sensitive = 0
if val eq 1 then widget_control,self.elastic_base_sensitive,sensitive = 0
if val eq 2 then widget_control,self.elastic_base_sensitive,sensitive = 0
if val eq 3 then widget_control,self.elastic_base_sensitive,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::E_TOF_handler,event = event
; This method responds to changes in the state of the
; lambda own field by sensitizing or desensitizing according to whether
;   the own value button is selected
widget_control,self.ebin_group,get_value = val
if val eq 0 then widget_control,self.E_TOF_base1,sensitive = 0
if val eq 1 then widget_control,self.E_TOF_base1,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::q_theta_handler,event = event
widget_control,self.qbin_group,get_value = val
if val eq 0 then widget_control,self.q_theta_base1,sensitive = 0
if val eq 1 then widget_control,self.q_theta_base1,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::OutputName_handler,event = event
widget_control,self.Output_nameGroup,get_value = val
if val eq 0 then begin
widget_control,self.Output_name_subbase_sensitive1,sensitive = 0
widget_control,self.Output_name_subbase_sensitive2,sensitive = 0
widget_control,self.stem2,set_value=''
if n_elements(*self.sigFilePtr) eq 0 then return
files = *self.sigFilePtr
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)
  widget_control, self.runGroup, get_value=runGroup
      if runGroup eq 1 then filename+='++'   ;set to 'sum runs'
widget_control, self.stem1, set_value=filename
endif
if val eq 1 then begin
;widget_control,self.Output_name_subbase_sensitive1,sensitive = 1
widget_control,self.Output_name_subbase_sensitive2,sensitive = 0
widget_control,self.stem2,set_value=''
endif
if val eq 2 then begin
;widget_control,self.Output_name_subbase_sensitive1,sensitive = 0
widget_control,self.Output_name_subbase_sensitive2,sensitive = 1
endif
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::rungrouphandler,event = event
widget_control,self.runGroup,get_value = rungroup
if rungroup eq 1 and n_elements(*self.sigFilePtr) eq 1 then begin
rungroup=0
  widget_control, self.runGroup, set_value=runGroup
endif
widget_control,self.stem1,get_value = stem1
stem1_length=strlen(stem1)
if stem1_length eq 0 then return
stem1_end=strmid(stem1,(stem1_length-2),2)
;print,stem1_end
if rungroup eq 1 and stem1_end ne '++' then stem1+='++'
if rungroup eq 0 and stem1_end eq '++' then stem1=strmid(stem1,0,(stem1_length-2))


widget_control,self.stem1,set_value = stem1
widget_control,self.diffstem1,set_value = stem1

;stem1_length
;print,'woof'



;if val eq 0 then widget_control,self.Output_name_subbase_sensitive2,sensitive = 0
;if val eq 1 then widget_control,self.Output_name_subbase_sensitive2,sensitive = 0
;if val eq 2 then widget_control,self.Output_name_subbase_sensitive2,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Misc1Handler,event = event
widget_control,self.Misc1Group,get_value = val
;print,'val =',val
if val[1] eq 1 then widget_control,self.DataOutputTypesGroup,set_value = 0
if val[2] eq 0 then widget_control,self.Misc_Base2,sensitive = 0
if val[2] eq 1 then widget_control,self.Misc_Base2,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Misc2Handler,event = event
widget_control,self.Misc2Group,get_value = val
;print,'val =',val
if val eq 0 then widget_control,self.Misc3Group_subbase,sensitive = 0
if val eq 1 then widget_control,self.Misc3Group_subbase,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::MiscXHandler,event = event
widget_control,self.MiscXGroup,get_value = val
if val eq 0 then begin
  widget_control,self.Misc_BaseX,sensitive = 0
  self.SelfShieldFilename=''
endif
if val eq 1 then begin
  widget_control,self.Misc_BaseX,sensitive = 1
  res=dialog_pickfile(/read,/must_exist,title='Choose 3column Ascii-File',path=self.workDir);
  self.SelfShieldFilename=res
  widget_control,self.SelfShieldField,set_value=file_basename(res)
endif
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Data_Output_Handler,event = event
widget_control,self.DataOutputTypesGroup,get_value = val
widget_control,self.FormatTypesGroup,get_value = format
;print,'val =',val
if format eq 3 then widget_control,self.DataOutputTypesGroup,set_value=1
;
widget_control,self.Misc1Group,get_value = Misc1Group
if Misc1Group[1] eq 1 then widget_control,self.DataOutputTypesGroup,set_value=0
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::qbin_Types1_handler,event = event
widget_control,self.qbin_group1,get_value = val
;print,'val =',val
if val eq 1 then widget_control,self.Bad_DetectorGroup,set_value=3
if val eq 2 then widget_control,self.Bad_DetectorGroup,set_value=3
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Bad_DetectorGroup_Handler,event = event
widget_control,self.Bad_DetectorGroup,get_value=val
;print,'val =',val
if val ne 3 then widget_control,self.qbin_group1,set_value = 0
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::FormatTypes,event = event
widget_control,self.FormatTypesGroup,get_value = vals
if vals eq 0 then text='dyn.dave'
if vals eq 1 then text='.itx'
if vals eq 2 then text='.txt'
if vals eq 3 then text='.spe'
widget_control, self.stem3, set_value=text
if vals eq 3 then widget_control,self.DataOutputTypesGroup,set_value = 1
;
;
;
;if vals[0] eq 0 then begin
;vals[0] = 1
;widget_control,self.FormatTypesGroup,set_value = vals
;endif
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::DiffONHandler,event = event
widget_control,self.DiffONGroup,get_value=val
;print,'val =',val
if val eq 0 then widget_control,self.Diffraction_Base2,sensitive = 0
if val eq 1 then widget_control,self.Diffraction_Base2,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::DiffractionCalcHandler,event = event
widget_control,self.DiffractionCalcGroup,get_value=val
;print,'val =',val
if val eq 0 then widget_control,self.Diffraction_Base3,sensitive = 0
if val eq 1 then widget_control,self.Diffraction_Base3,sensitive = 1
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::DiffOutputName_handler,event = event
widget_control,self.DiffOutput_nameGroup,get_value = val
if val eq 0 then begin
widget_control,self.DiffOutput_name_subbase_sensitive1,sensitive = 0
widget_control,self.DiffOutput_name_subbase_sensitive2,sensitive = 0
widget_control,self.Diffstem2,set_value=''
if n_elements(*self.sigFilePtr) eq 0 then return
files = *self.sigFilePtr
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)
  widget_control, self.runGroup, get_value=runGroup
      if runGroup eq 1 then filename+='++'   ;set to 'sum runs'
widget_control, self.Diffstem1, set_value=filename
endif
if val eq 1 then begin
;widget_control,self.DiffOutput_name_subbase_sensitive1,sensitive = 1
widget_control,self.DiffOutput_name_subbase_sensitive2,sensitive = 0
;widget_control,self.Diffstem2,set_value='Enter Filename on Prompt'
endif
if val eq 2 then begin
;widget_control,self.DiffOutput_name_subbase_sensitive1,sensitive = 0
widget_control,self.DiffOutput_name_subbase_sensitive2,sensitive = 1
endif
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::flashMessage_create,msg,tlb
; This method simply flashes a widget with a message that remains present
; until the flashMessage_destroy method is invoked.
;
; Center it.
geom = widget_info(self.tlb, /geometry)
xpos = geom.xoffset + geom.xsize/2 - 100
ypos = geom.yoffset + geom.ysize/2 - 50

tlb = widget_base(title='Reduction status:',/row,xoffset=xpos,yoffset=ypos, $
      tlb_frame_attr = 3)
;help,msg
;print,msg[0]
void = widget_text(tlb,value = msg,xsize = strlen(msg),/editable)
widget_control,tlb,/realize
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::flashMessage_destroy,tlb
widget_control,tlb,/destroy
return
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::reduce,event = event
;
;CATCH, Error_status
;if Error_status ne 0 then begin
;  catch, /cancel
;  msg=strarr(3)
;  msg[0]='Unable to perform data reduction.'
;  msg[1]='Please report the following bug:'
;  msg[2]='Error Message from IDL: '+!ERROR_STATE.MSG
;  void=dialog_message(dialog_parent=event.top,/error,msg)
;  return
;endif
;
if n_elements(*self.sigFilePtr) eq 0 then begin
  msg=strarr(2)
  msg[0]='You have specified no signal run(s).'
  msg[1]='Make sure you complete all your inputs by pressing ENTER.'
  void=dialog_message(dialog_parent=event.top,msg)
  return
endif

files = *self.sigFilePtr
if n_elements(*self.treatmentPtr) ne 0 then begin
  ptr_free,self.treatmentPtr
  self.treatmentPtr = ptr_new(/allocate_heap)
;*self.treatmentPtr = 'Data reduction/treatment details:'
endif
; How do we treat the data?
widget_control,self.treatGroup,get_value = treatVal
;What is the output format of the data?
widget_control,self.FormatTypesGroup,get_value = FormatType
;which banks shall we include?
widget_control,self.DetectorBankTypesGroup,get_value = DBT

if (FormatType eq 3) and ((DBT eq 1) or (DBT eq 5)) then begin
void = dialog_message(dialog_parent = event.top,/information, $
'It is not currently possible to create a matlab file that includes data from the 2d Detector')
return
endif
;

; Do we treat these individually or sum them?
widget_control,self.runGroup,get_value = thisValue
;
;   What quantity do we wish to calculate?
;
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
;
; if DataOutput eq 2 then S(theta,t)
;
;   Do we specify a file name(1) or is the file name automatically assigned(0)
widget_control,self.Output_nameGroup,get_value = Output_name
;
;   No Output option, detailed balance and flat baseline options are stored in  Misc1Group
    widget_control,self.Misc1Group,get_value = Misc1Group
;
;
;   Is the diffraction pattern requested?
    widget_control,self.DiffONGroup,get_value = DiffONGroup
;
;
;
if FormatType eq 0    then begin
filter = ['*.dave']
title = 'DAVE output filename'
endif
;
if FormatType eq 1    then begin
filter = ['*.itx']
title = 'IGOR output filename'
endif
;
if FormatType eq 2    then begin
filter = ['*.txt']
title = 'ASCII output filename'
endif
;
if FormatType eq 3    then begin
filter = ['*.spe']
title = 'MATLAB output filename'
endif
;
;
;
;
;
;
    if thisValue[0] eq 0 then begin   ; treat individually
self.NormFactor=1.0

  nfiles = n_elements(files)

  for i = 0,nfiles-1 do begin


   *self.treatmentPtr = 'Data reduction/treatment details:'
   msg = 'Reading in a raw focus file'
   self->flashMessage_create,msg,tlb
   self->Nexus_read_raw_focus,files[i],event = event,err = err ; always
   self->flashMessage_destroy,tlb
   if err eq 1 then return
;
Sample_Name={sample_name,  $
         ftime:(*self.InstrumentPtr).ftime,  $
         sample:(*self.InstrumentPtr).sample,  $
         foriname:(*self.InstrumentPtr).foriname,  $
         title:(*self.InstrumentPtr).title}

*self.Sample_NamePtr=Sample_Name



   msg = 'Subtracting Bad Detectors and Grouping'
   self->flashMessage_create,msg,tlb
   self->subtract_bad_detectors,event = event    ; always
   self->flashMessage_destroy,tlb
;
;
;
;
   msg = 'Calculating Wavelength '
   self->flashMessage_create,msg,tlb
   self->TOF_corr,event=event   ;always
   self->flashMessage_destroy,tlb
;
;   We now have all we need to calculate the diffraction pattern
    if DiffONGroup eq 1 then begin
       msg = 'Calculating Diffraction Pattern '
   self->flashMessage_create,msg,tlb
   self->Diffraction,event=event
   self->flashMessage_destroy,tlb
    endif
;
;

     if Misc1Group[2] eq 1 then begin  ; subtract flat baseline
     if (n_elements(*self.bgFilePtr) eq 0) or (treatVal[1] eq 0) then begin
    msg = 'Flat Baseline Routine    '
    self->flashMessage_create,msg,tlb
    self->flat_baseline,event = event
    self->flashMessage_destroy,tlb
    endif
    endif

; CONVERSION TO ENERGY (if applicable)
if DataOutput ne 2 then begin
  msg = 'Converting to Energy'
  self->flashMessage_create,msg,tlb
  self->convert_to_energy,event = event
  self->flashMessage_destroy,tlb
endif else begin
  self.xlabel = 'Time / usec'
endelse

msg = 'Subtracting Background File(s)'
self->flashMessage_create,msg,tlb
if (treatVal[1] eq 1) then self->subtract_background,event = event $
else self->subtract_background,event = event, /zerobgrd
self->flashMessage_destroy,tlb

;print,'treatVal[0]: ',treatVal[0]
    if treatVal[0] eq 1 then begin
     msg = 'Normalising to Vanadium Run'
     self->flashMessage_create,msg,tlb
     self->normalize_to_vanadium,event = event   ; normalize to vanadium
     self->flashMessage_destroy,tlb
    endif

    ; Do the rebinning at this point
   msg = 'Energy/TOF Rebinning    '
   self->flashMessage_create,msg,tlb
   self->ebinning,event=event
   self->flashMessage_destroy,tlb

   msg = 'Q/Theta Rebinning     '
   self->flashMessage_create,msg,tlb
   self->qbinning,event=event
   self->flashMessage_destroy,tlb

; ENERGY DEPENDENT DETECTOR EFFICIENCY (if applicable)
widget_control,self.MiscDetEffGroup,get_value = flag_detefficiencyE
print,'E-dep detector efficiency flag -> ',flag_detefficiencyE
if flag_detefficiencyE eq 1 then begin
  if DataOutput eq 2 then begin
    msg=strarr(3)
    msg[0]='Correction for energy dependent detector efficiency'
    msg[1]='is ONLY implemented in energy mode [you aksed for S(tth,TOF)].'
    msg[2]='CORRECTION WILL NOT BE PERFORMED!'
    void=dialog_message(dialog_parent=event.top,msg)
  endif else begin
    msg = 'Correction for energy dependent detector efficiency'
    self->flashMessage_create,msg,tlb
    self->detefficiencyE,event = event
    self->flashMessage_destroy,tlb
  endelse
endif

; NORMALIZE TO MONITOR OR UNITY
widget_control,self.Misc2Group,get_value = Misc2Group
if Misc2Group eq 1 then begin
  widget_control,self.Misc3Group,get_value = normalize
  msg = 'Normalizing to Monitor/Unity'
  self->flashMessage_create,msg,tlb
  self->normalize_to_monitor,event=event,normalize_mode=normalize
  self->flashMessage_destroy,tlb
endif  

;
;
;
;;
IF Misc1Group[0] EQ 0 THEN BEGIN

    if  Output_name eq 0 then begin
  filename_result = strsplit(files[i],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)


   fileOut = filepath(filename,root_dir = self.workDir)
   endif


       if Output_name eq 1 then begin
;
; First extract the filename
  filename_result = strsplit(files[i],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)
  ;extPos = strpos(files[0],'.focus')
  ;filename = strmid(files[0],extPos-11,11)

  fileExample = filename
  fileOut = dialog_pickfile(dialog_parent = event.top,/write, $
  ;                          file = filename, $
                            file = filename, $ ; following IGOR
                            filter = filter,$
                            title = title,$
                            path = self.workDir)
;   fileOut = filepath(filename+'++',root_dir = self.workDir)


       endif

       if  Output_name eq 2 then begin
  filename_result = strsplit(files[i],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)

   fileOut = filepath(filename,root_dir = self.workDir)
   widget_control, self.stem2, get_value=stem_add
    if strlen(stem_add) gt 0 then    fileOut+=stem_add

   endif

IF fileOut NE '' THEN BEGIN


    ;print,fileout
FilePar=fileout+'.par'
FilePhx=fileout+'.phx'

;
if FormatType eq 0    then begin
fileOut+= 'dyn.dave' ;Dave File
  msg = 'Writing to a DAVE file...'
  self->flashMessage_create,msg,tlb
  self->writeDave,event = event,fileout = fileout,FilePar = FilePar
  self->flashMessage_destroy,tlb
endif
;
if FormatType eq 1    then begin
fileOut+= '.itx' ; IGOR Text File
  msg = 'Writing to an IGOR Text file...'
  self->flashMessage_create,msg,tlb
  self->writeIGOR,event = event,fileout = fileout,FilePar = FilePar
  self->flashMessage_destroy,tlb
endif
;
if FormatType eq 2  then begin
fileOut+= '.txt' ; ASCII File
  msg = 'Writing to an ASCII file...'
  self->flashMessage_create,msg,tlb
  self->writeASCII,event = event,fileout = fileout,FilePar = FilePar
  self->flashMessage_destroy,tlb
endif
;
if FormatType eq 3  then begin
fileOut+= '.spe' ; Matlab File
  msg = 'Writing to a Matlab file...'
  self->flashMessage_create,msg,tlb
  self->writeMatlab,event = event,fileout = fileout,FilePar = FilePar,FilePhx = FilePhx
  self->flashMessage_destroy,tlb
endif

ENDIF


   treat = 'Filename: '+strtrim(files[i],2)
   *self.treatmentPtr = [*self.treatmentPtr,treat]

  ENDIF ; is output required endif


   if n_elements(*self.treatmentPtr) ne 0 then begin
      ptr_free,self.treatmentPtr
      self.treatmentPtr = ptr_new(/allocate_heap)
   endif


  endfor

    endif else begin         ; sum runs together
self.NormFactor=1.0
*self.treatmentPtr = 'Data reduction/treatment details:'
   msg = 'Reading in files to sum'
   self->flashMessage_create,msg,tlb
   self->sum_runs, event = event, err = err
   self->flashMessage_destroy,tlb
   if err eq 1 then return
;
Sample_Name={sample_name,  $
         ftime:(*self.InstrumentPtr).ftime,  $
         sample:(*self.InstrumentPtr).sample,  $
         foriname:(*self.InstrumentPtr).foriname,  $
         title:(*self.InstrumentPtr).title}

*self.Sample_NamePtr=Sample_Name


   msg = 'Subtracting Bad Detectors and Grouping'
   self->flashMessage_create,msg,tlb
   self->subtract_bad_detectors,event = event    ; always
   self->flashMessage_destroy,tlb
;
;
;
   msg = 'Calculating Wavelength '
   self->flashMessage_create,msg,tlb
   self->TOF_corr,event=event   ;always
   self->flashMessage_destroy,tlb
;
;   We now have all we need to calculate the diffraction pattern
    if DiffONGroup eq 1 then begin
       msg = 'Calculating Diffraction Pattern '
   self->flashMessage_create,msg,tlb
   self->Diffraction,event=event
   self->flashMessage_destroy,tlb
    endif
;
;
     if Misc1Group[2] eq 1 then begin  ; subtract flat baseline
     if (n_elements(*self.bgFilePtr) eq 0) or (treatVal[1] eq 0) then begin
    msg = 'Flat Baseline Routine    '
    self->flashMessage_create,msg,tlb
    self->flat_baseline,event = event
    self->flashMessage_destroy,tlb
    endif
    endif


; CONVERSION TO ENERGY (if applicable)
if DataOutput ne 2 then begin
  msg = 'Converting to Energy'
  self->flashMessage_create,msg,tlb
  self->convert_to_energy,event = event
  self->flashMessage_destroy,tlb
endif else begin
  self.xlabel = 'Time / usec'
endelse

msg = 'Subtracting Background File(s)'
self->flashMessage_create,msg,tlb
if (treatVal[1] eq 1) then self->subtract_background,event = event $
else self->subtract_background,event = event, /zerobgrd
self->flashMessage_destroy,tlb

;
  if treatVal[0] eq 1 then begin
   msg = 'Normalising to Vanadium Run'
   self->flashMessage_create,msg,tlb
   self->normalize_to_vanadium,event = event    ; normalize to vanadium
   self->flashMessage_destroy,tlb
  endif


    ; Do the rebinning at this point
   msg = 'Energy/TOF Rebinning    '
   self->flashMessage_create,msg,tlb
   self->ebinning,event=event
   self->flashMessage_destroy,tlb

   msg = 'Q/Theta Rebinning         '
   self->flashMessage_create,msg,tlb
   self->qbinning,event=event
   self->flashMessage_destroy,tlb

; ENERGY DEPENDENT DETECTOR EFFICIENCY (if applicable)
widget_control,self.MiscDetEffGroup,get_value = flag_detefficiencyE
if flag_detefficiencyE eq 1 then begin
  if DataOutput eq 2 then begin
    msg=strarr(3)
    msg[0]='Correction for energy dependent detector efficiency'
    msg[1]='is ONLY implemented in energy mode [you aksed for S(tth,TOF)].'
    msg[2]='CORRECTION WILL NOT BE PERFORMED!'
    void=dialog_message(dialog_parent=event.top,msg)
  endif else begin
    msg = 'Correction for energy dependent detector efficiency'
    self->flashMessage_create,msg,tlb
    self->detefficiencyE,event = event
    self->flashMessage_destroy,tlb
  endelse
endif

; NORMALIZE TO MONITOR OR UNITY
widget_control,self.Misc2Group,get_value = Misc2Group
if Misc2Group eq 1 then begin
  widget_control,self.Misc3Group,get_value = normalize
  msg = 'Normalizing to Monitor/Unity'
  self->flashMessage_create,msg,tlb
  self->normalize_to_monitor,event=event,normalize_mode=normalize
  self->flashMessage_destroy,tlb
endif 

;
;
;
if Misc1Group[0] eq 1 then return


   if  Output_name eq 0 then begin
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)


   fileOut = filepath(filename,root_dir = self.workDir)
   fileout+='++'
   endif



       if  Output_name eq 1 then begin
;
; First extract the filename
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)
  ;extPos = strpos(files[0],'.focus')
  ;filename = strmid(files[0],extPos-11,11)

  fileExample = filename
  fileOut = dialog_pickfile(dialog_parent = event.top,/write, $
  ;                          file = filename, $
                            file = filename+'++', $ ; following IGOR
                            filter = filter,$
                            title = title,$
                            path = self.workDir)
;   fileOut = filepath(filename+'++',root_dir = self.workDir)

  endif
  ;
  ;
       if  Output_name eq 2 then begin
  filename_result = strsplit(files[0],path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)

   fileOut = filepath(filename,root_dir = self.workDir)
      fileout+='++'
   widget_control, self.stem2, get_value=stem_add
    if strlen(stem_add) gt 0 then    fileOut+=stem_add
   endif

IF fileOut NE '' THEN BEGIN

;
FilePar=fileout+'.par'
FilePhx=fileout+'.phx'

if FormatType eq 0    then begin
fileOut+= 'dyn.dave' ;Dave File
  msg = 'Writing to a DAVE file...'
  self->flashMessage_create,msg,tlb
  self->writeDave,event = event,fileout = fileout,FilePar = FilePar
  self->flashMessage_destroy,tlb
endif
;
if FormatType eq 1    then begin
fileOut+= '.itx' ; IGOR Text File
  msg = 'Writing to an IGOR Text file...'
  self->flashMessage_create,msg,tlb
  self->writeIGOR,event = event,fileout = fileout,FilePar = FilePar
  self->flashMessage_destroy,tlb
endif
;
if FormatType eq 2  then begin
fileOut+= '.txt' ; ASCII File
  msg = 'Writing to an ASCII file...'
  self->flashMessage_create,msg,tlb
  self->writeASCII,event = event,fileout = fileout,FilePar = FilePar
  self->flashMessage_destroy,tlb
endif

if FormatType eq 3  then begin
fileOut+= '.spe' ; Matlab File
  msg = 'Writing to a Matlab file...'
  self->flashMessage_create,msg,tlb
  self->writeMatlab,event = event,fileout = fileout,FilePar = FilePar,FilePhx = FilePhx
  self->flashMessage_destroy,tlb
endif

ENDIF
    ;print,fileout
;

    endelse



self->display,event = event
return
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::writeDave,event = event,fileout = fileout,FilePar = FilePar
; This method populates the DAVE pointer in memory and saves the data into
; a "*.DAVE" file.
treat = 'Converted to DAVE format'
*self.treatmentPtr = [*self.treatmentPtr,treat]

n = n_elements(*self.treatmentPtr)
;for i = 0,n-1 do print,(*self.treatmentPtr)[i]
davePtr = self.davePtr

data = *self.dataPtr
error = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
;print,'Number of groups:',self.ndet
; Ok, start filling up the dave pointer...
; First, fill up the data...



;help,data
datSize = size(data)
nchan = datSize[1]
if datSize[0] eq 2 then begin
ndet = datSize[2]
endif else begin
ndet=1
endelse
Sample_Name=*self.Sample_NamePtr

Instrument_Details=*self.InstrumentPtr

;Sample_Name={sample_name,  $
;         ftime:(*self.InstrumentPtr).ftime,  $
;         sample:(*self.InstrumentPtr).sample,  $
;         foriname:(*self.InstrumentPtr).foriname,  $
;         title:(*self.InstrumentPtr).title}
Instrument_Details.ftime=Sample_Name.ftime
Instrument_Details.sample=Sample_Name.sample
Instrument_Details.foriname=Sample_Name.foriname
Instrument_Details.title=Sample_Name.title



header=*self.headerPtr
nh = n_elements(*self.headerPtr)
detSize = (size(data))[2]
temperature=*self.tempPtr
;
specific = {nchan:nchan,$
            ndet:ndet,$
            header:header, $
            phi:*self.detPtr,$
            instrument:'focus',$
            wavelength:(*self.tof_corr_structurePtr).lambdatof,$
            date:systime(),$
            temp_sample:temperature,$
            sumMon_tc:total(*self.Mon_tcPtr),$
            sumMon_cum:total(*self.Mon_cumPtr),$
            Instrument_details:Instrument_Details $
            }


;print,'lambda =',(*self.tof_corr_structurePtr).lambdatof

;*(*(*davePtr).dataStrPtr).specificPtr = specific

hbar_omega = '!6!sh!r!e/!n !7x!6'
xlabel=hbar_omega
if self.units eq 4 then xlabel = 'T'
if self.units eq 5 then xlabel = 't'
;if self.units ne 5 then begin
;xlabel = hbar_omega
;endif else begin
;xlabel = 't'
;endelse
;xlabel=self.xlabel

if self.units eq 0 then xunits = 'Energy / meV'
if self.units eq 1 then xunits = 'Energy / Wavenumbers'
if self.units eq 2 then xunits = 'Energy / GHz'
if self.units eq 3 then xunits = 'Energy /  THz'
if self.units eq 4 then xunits = 'Energy / K'
if self.units eq 5 then xunits = 'Time / Microseconds'
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
if DataOutput[0] eq 0 then begin
yunits = 'wavevector:A-1'
ylabel = 'Q '
endif
if DataOutput[0] eq 1 or DataOutput[0] eq 2 then begin
yunits = 'Phi:degrees'
ylabel = 'Phi '
endif

histlabel = 'I (arbitrary units)'
histunits = ''

Mon_cumTreat = 'Total incident beam monitor counts: '+ $
           strtrim(string(total(*self.Mon_cumPtr)),2)
*self.treatmentPtr = [*self.treatmentPtr,Mon_cumTreat]
msg = 'Number of channels: '+strtrim(string(nchan),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]
msg = 'Number of groups: '+strtrim(string(ndet),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]

;*(*(*davePtr).dataStrPtr).commonStr.treatmentPtr = *self.treatmentPtr
if n_elements(temperature) gt 1 then temperature = (moment(temperature))[0]
retval = create_dave_pointer(self.davePtr,   $
     qty = data,   $
     err = error,    $
     xvals = x,            $
     yvals = y,      $
     specificstr = specific,      $
     instrument = 'FOCUS',      $
     xtype = 'POINTS',        $
     ytype = 'POINTS',        $
     xlabel = xlabel,         $
     ylabel = ylabel,         $
     qtlabel = histlabel,      $
     xunits = xunits,         $
     yunits = yunits,         $
     qtunits = histunits,      $
     dname = 'T',          $
     dunits = 'temperature:K',     $
     dlegend = 'Temperature',    $
     dqty = temperature,         $
     derr = 0.0,            $
     treatment = *self.treatmentptr,   $
     ermsg = ermsg           )



if n_elements(fileout) eq 0 then return
if (*self.daveFiles)[0] eq '' then begin
  *self.daveFiles = fileOut
endif else begin
  *self.daveFiles = [*self.daveFiles,fileOut]
endelse
save, davePtr, filename = fileout

openw,lun,FilePar,/get_lun
printf,lun, 'Instrument: FOCUS'
printf,lun, 'Sample: '+strtrim(string(Sample_Name.sample),2)
printf,lun, 'Original File Name: '+strtrim(string(Sample_Name.foriname),2)
printf,lun, 'Title: '+strtrim(string(Sample_Name.title),2)
printf,lun, 'User: '+strtrim(string(Instrument_Details.owner),2)
printf,lun, 'Temperature / K: '+strtrim(string(temperature),2)
printf,lun, 'XType: Points'
printf,lun, 'Group Type: Points'
printf,lun, 'X Units: '+strtrim(string(xunits),2)
printf,lun, 'Y Units: '+strtrim(string(histlabel),2)
printf,lun, 'Group Units: '+strtrim(string(yunits),2)
printf,lun, 'Group Label: '+strtrim(string(ylabel),2)
printf,lun, 'Number of Channels: '+strtrim(string(nchan),2)
printf,lun, 'Number of Groups: '+strtrim(string(ndet),2)
printf,lun, 'Wavelength / A: '+strtrim(string((*self.tof_corr_structurePtr).lambdatof),2)
printf,lun, 'Date Data File Created: '+strtrim(string(Sample_Name.ftime),2)
printf,lun, 'Date This File Created: '+strtrim(string(systime()),2)
printf,lun, 'Fermispeed: '+strtrim(string(Instrument_Details.fermispeed),2)
printf,lun, 'Fermiphase: '+strtrim(string(Instrument_Details.fermiphase),2)
printf,lun, 'Diskspeed: '+strtrim(string(Instrument_Details.diskspeed),2)
printf,lun, *self.treatmentPtr
free_lun,lun,/force

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::writeIGOR,event = event,fileout = fileout,FilePar = FilePar
;
if n_elements(fileout) eq 0 then return
;
treat = 'Converted to IGOR Text format'
*self.treatmentPtr = [*self.treatmentPtr,treat]

n = n_elements(*self.treatmentPtr)
;for i = 0,n-1 do print,(*self.treatmentPtr)[i]

data = *self.dataPtr
error = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
;print,'Number of groups:',self.ndet

;help,data
datSize = size(data)
nchan = datSize[1]
if datSize[0] eq 2 then begin
ndet = datSize[2]
endif else begin
ndet=1
endelse

header=*self.headerPtr
nh = n_elements(*self.headerPtr)
detSize = (size(data))[2]
temperature=*self.tempPtr
Instrument_Details=*self.InstrumentPtr

;Sample_Name={sample_name,  $
;         ftime:(*self.InstrumentPtr).ftime,  $
;         sample:(*self.InstrumentPtr).sample,  $
;         foriname:(*self.InstrumentPtr).foriname,  $
;         title:(*self.InstrumentPtr).title}

Sample_Name=*self.Sample_NamePtr


;hbar_omega = '!6!sh!r!e/!n !7x!6'
;xlabel=hbar_omega
xlabel='Energy'
if self.units eq 4 then xlabel = 'T'
if self.units eq 5 then xlabel = 't'
;if self.units ne 5 then begin
;xlabel = hbar_omega
;endif else begin
;xlabel = 't'
;endelse
;xlabel=self.xlabel

if self.units eq 0 then xunits = 'Energy / meV'
if self.units eq 1 then xunits = 'Energy / Wavenumbers'
if self.units eq 2 then xunits = 'Energy / GHz'
if self.units eq 3 then xunits = 'Energy /  THz'
if self.units eq 4 then xunits = 'Energy / K'
if self.units eq 5 then xunits = 'Time / Microseconds'
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
if DataOutput[0] eq 0 then begin
yunits = 'wavevector:A-1'
ylabel = 'Q '
endif
if DataOutput[0] eq 1 or DataOutput[0] eq 2 then begin
yunits = 'Phi:degrees'
ylabel = 'Phi '
endif

histlabel = 'I (arbitrary units)'
histunits = ''

Mon_cumTreat = 'Total incident beam monitor counts: '+ $
           strtrim(string(total(*self.Mon_cumPtr)),2)
*self.treatmentPtr = [*self.treatmentPtr,Mon_cumTreat]
msg = 'Number of channels: '+strtrim(string(nchan),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]
msg = 'Number of groups: '+strtrim(string(ndet),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]

;*(*(*davePtr).dataStrPtr).commonStr.treatmentPtr = *self.treatmentPtr
if n_elements(temperature) gt 1 then temperature = (moment(temperature))[0]


openw,lun,fileout,/get_lun
printf,lun, 'IGOR'
for i = 0, ndet-1 do begin
;printf,lun, '|Group Number: '+strtrim(string(i+1),2)
;printf,lun, '|Group Value: '+strtrim(string(y[i]),2)
xval='''XValue_'+strtrim(string(y[i]),2)+''''+'  '
yval='''Intensity_'+strtrim(string(y[i]),2)+''''+'  '
yval_err='''dIntensity_'+strtrim(string(y[i]),2)+''''+'  '
printf,lun, 'WAVES/D ',xval,yval,yval_err
printf,lun, 'Begin'
z=reform(data[*,i])
dz=reform(error[*,i])
newx=x
count = nchan
purged=where(z ne (-1.0/self.NormFactor),count)
if count ne 0 then begin
z=z[purged]
dz=dz[purged]
newx=newx[purged]
endif

    for j = 0, count-1 do begin
printf,lun, strtrim(string(newx[j]),1)+'  ',strtrim(string(z[j]),1)+'  ',strtrim(string(dz[j]),1)
        endfor
printf,lun, 'End'
printf, lun, 'X SetScale d 0,0,'+'"'+strtrim(string(xunits),2)+'"'+', ' +strtrim(string(xval),2)
printf, lun, 'X SetScale d 0,0,'+'"'+strtrim(string(histlabel),2)+' '+strtrim(string(ylabel),2)+  $
          ' '+strtrim(string(yunits),2)+  $
                   ' '+strtrim(string(y[i]),2)+' '+'"'+', '+strtrim(string(yval),2)
endfor

free_lun,lun,/force


openw,lun,FilePar,/get_lun
printf,lun, 'Instrument: FOCUS'
printf,lun, 'Sample: '+strtrim(string(Sample_Name.sample),2)
printf,lun, 'Original File Name: '+strtrim(string(Sample_Name.foriname),2)
printf,lun, 'Title: '+strtrim(string(Sample_Name.title),2)
printf,lun, 'User: '+strtrim(string(Instrument_Details.owner),2)
printf,lun, 'Temperature / K: '+strtrim(string(temperature),2)
printf,lun, 'XType: Points'
printf,lun, 'Group Type: Points'
printf,lun, 'X Units: '+strtrim(string(xunits),2)
printf,lun, 'Y Units: '+strtrim(string(histlabel),2)
printf,lun, 'Group Units: '+strtrim(string(yunits),2)
printf,lun, 'Group Label: '+strtrim(string(ylabel),2)
printf,lun, 'Number of Channels: '+strtrim(string(nchan),2)
printf,lun, 'Number of Groups: '+strtrim(string(ndet),2)
printf,lun, 'Wavelength / A: '+strtrim(string((*self.tof_corr_structurePtr).lambdatof),2)
printf,lun, 'Date Data File Created: '+strtrim(string(Sample_Name.ftime),2)
printf,lun, 'Date This File Created: '+strtrim(string(systime()),2)
printf,lun, 'Fermispeed: '+strtrim(string(Instrument_Details.fermispeed),2)
printf,lun, 'Fermiphase: '+strtrim(string(Instrument_Details.fermiphase),2)
printf,lun, 'Diskspeed: '+strtrim(string(Instrument_Details.diskspeed),2)
printf,lun, *self.treatmentPtr
free_lun,lun,/force


end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::writeASCII,event = event,fileout = fileout,FilePar = FilePar
;
if n_elements(fileout) eq 0 then return
;
treat = 'Converted to ASCII format'
*self.treatmentPtr = [*self.treatmentPtr,treat]

n = n_elements(*self.treatmentPtr)
;for i = 0,n-1 do print,(*self.treatmentPtr)[i]

data = *self.dataPtr
error = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
;print,'Number of groups:',self.ndet

;help,data
datSize = size(data)
nchan = datSize[1]
if datSize[0] eq 2 then begin
ndet = datSize[2]
endif else begin
ndet=1
endelse

header=*self.headerPtr
nh = n_elements(*self.headerPtr)
detSize = (size(data))[2]
temperature=*self.tempPtr
Instrument_Details=*self.InstrumentPtr

;Sample_Name={sample_name,  $
;         ftime:(*self.InstrumentPtr).ftime,  $
;         sample:(*self.InstrumentPtr).sample,  $
;         foriname:(*self.InstrumentPtr).foriname,  $
;         title:(*self.InstrumentPtr).title}

Sample_Name=*self.Sample_NamePtr


;hbar_omega = '!6!sh!r!e/!n !7x!6'
;xlabel=hbar_omega
xlabel='Energy'
if self.units eq 4 then xlabel = 'T'
if self.units eq 5 then xlabel = 't'
;if self.units ne 5 then begin
;xlabel = hbar_omega
;endif else begin
;xlabel = 't'
;endelse
;xlabel=self.xlabel


if self.units eq 0 then xunits = 'Energy / meV'
if self.units eq 1 then xunits = 'Energy / Wavenumbers'
if self.units eq 2 then xunits = 'Energy / GHz'
if self.units eq 3 then xunits = 'Energy /  THz'
if self.units eq 4 then xunits = 'Energy / K'
if self.units eq 5 then xunits = 'Time / Microseconds'
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
if DataOutput[0] eq 0 then begin
yunits = 'wavevector:A-1'
ylabel = 'Q '
endif
if DataOutput[0] eq 1 or DataOutput[0] eq 2 then begin
yunits = 'Phi:degrees'
ylabel = 'Phi '
endif

histlabel = 'I (arbitrary units)'
histunits = ''

Mon_cumTreat = 'Total incident beam monitor counts: '+ $
           strtrim(string(total(*self.Mon_cumPtr)),2)
*self.treatmentPtr = [*self.treatmentPtr,Mon_cumTreat]
msg = 'Number of channels: '+strtrim(string(nchan),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]
msg = 'Number of groups: '+strtrim(string(ndet),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]

;*(*(*davePtr).dataStrPtr).commonStr.treatmentPtr = *self.treatmentPtr
if n_elements(temperature) gt 1 then temperature = (moment(temperature))[0]


openw,lun,fileout,/get_lun
printf,lun, '#DAVE ASCII OUTPUT'
printf,lun, '#Instrument: FOCUS'
printf,lun, '#Sample: '+strtrim(string(Sample_Name.sample),2)
printf,lun, '#Original File Name: '+strtrim(string(Sample_Name.foriname),2)
printf,lun, '#Title: '+strtrim(string(Sample_Name.title),2)
printf,lun, '#User: '+strtrim(string(Instrument_Details.owner),2)
printf,lun, '#Temperature / K: '+strtrim(string(temperature),2)
printf,lun, '#XType: Points'
printf,lun, '#Group Type: Points'
printf,lun, '#X Units: '+strtrim(string(xunits),2)
printf,lun, '#Y Units: '+strtrim(string(histlabel),2)
printf,lun, '#Group Units: '+strtrim(string(yunits),2)
printf,lun, '#Group Label: '+strtrim(string(ylabel),2)
printf,lun, '#Number of Channels: '+strtrim(string(nchan),2)
printf,lun, '#Number of Groups: '+strtrim(string(ndet),2)
printf,lun, '#Wavelength / A: '+strtrim(string((*self.tof_corr_structurePtr).lambdatof),2)
printf,lun, '#Date Data File Created: '+strtrim(string(Sample_Name.ftime),2)
printf,lun, '#Date This File Created: '+strtrim(string(systime()),2)
printf,lun, '#Fermispeed: '+strtrim(string(Instrument_Details.fermispeed),2)
printf,lun, '#Fermiphase: '+strtrim(string(Instrument_Details.fermiphase),2)
printf,lun, '#Diskspeed: '+strtrim(string(Instrument_Details.diskspeed),2)
for i = 0,n-1 do printf,lun,'#'+(*self.treatmentPtr)[i]
printf,lun, '#Begin'
for i = 0, ndet-1 do begin
printf,lun, '#Group Number: '+strtrim(string(i+1),2)
printf,lun, '#Group Value: '+strtrim(string(y[i]),2)
printf,lun, '#X Value    ','Intensity ','dIntensity'
z=reform(data[*,i])
dz=reform(error[*,i])
newx=x
count = nchan
purged=where(z ne (-1.0/self.NormFactor),count)
if count ne 0 then begin
z=z[purged]
dz=dz[purged]
newx=newx[purged]
endif

    for j = 0, count-1 do begin
printf,lun, strtrim(string(newx[j]),1)+'  ',strtrim(string(z[j]),1)+'  ',strtrim(string(dz[j]),1)
        endfor
endfor
printf,lun, '#end'
free_lun,lun,/force
;
;openw,lun,FilePar,/get_lun
;printf,lun, 'Instrument: FOCUS'
;printf,lun, 'Sample: '+strtrim(string(Sample_Name.sample),2)
;printf,lun, 'Original File Name: '+strtrim(string(Sample_Name.foriname),2)
;printf,lun, 'Title: '+strtrim(string(Sample_Name.title),2)
;printf,lun, 'User: '+strtrim(string(Instrument_Details.owner),2)
;printf,lun, 'Temperature / K: '+strtrim(string(temperature),2)
;printf,lun, 'XType: Points'
;printf,lun, 'Group Type: Points'
;printf,lun, 'X Units: '+strtrim(string(xunits),2)
;printf,lun, 'Y Units: '+strtrim(string(histlabel),2)
;printf,lun, 'Group Units: '+strtrim(string(yunits),2)
;printf,lun, 'Group Label: '+strtrim(string(ylabel),2)
;printf,lun, 'Number of Channels: '+strtrim(string(nchan),2)
;printf,lun, 'Number of Groups: '+strtrim(string(ndet),2)
;printf,lun, 'Wavelength / A: '+strtrim(string((*self.tof_corr_structurePtr).lambdatof),2)
;printf,lun, 'Date Data File Created: '+strtrim(string(Sample_Name.ftime),2)
;printf,lun, 'Date This File Created: '+strtrim(string(systime()),2)
;printf,lun, 'Fermispeed: '+strtrim(string(Instrument_Details.fermispeed),2)
;printf,lun, 'Fermiphase: '+strtrim(string(Instrument_Details.fermiphase),2)
;printf,lun, 'Diskspeed: '+strtrim(string(Instrument_Details.diskspeed),2)
;printf,lun, *self.treatmentPtr
;free_lun,lun,/force

;
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::writeMatlab,event = event,fileout = fileout,FilePar = FilePar,FilePhx = FilePhx
;
if n_elements(fileout) eq 0 then return
;

widget_control,self.DataOutputTypesGroup,get_value = DataOutput

if DataOutput eq 0 then output='S(Q,w)'
if DataOutput eq 1 then output='S(phi,w)'
if DataOutput eq 2 then output='S(phi,t)'

treat = 'Converted to Matlab Format'
*self.treatmentPtr = [*self.treatmentPtr,treat]

n = n_elements(*self.treatmentPtr)
;for i = 0,n-1 do print,(*self.treatmentPtr)[i]

data = *self.dataPtr
error = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
;print,'Number of groups:',self.ndet

;help,data
datSize = size(data)
nchan = datSize[1]
if datSize[0] eq 2 then begin
ndet = datSize[2]
endif else begin
ndet=1
endelse

header=*self.headerPtr
nh = n_elements(*self.headerPtr)
detSize = (size(data))[2]
temperature=*self.tempPtr
Instrument_Details=*self.InstrumentPtr

;Sample_Name={sample_name,  $
;         ftime:(*self.InstrumentPtr).ftime,  $
;         sample:(*self.InstrumentPtr).sample,  $
;         foriname:(*self.InstrumentPtr).foriname,  $
;         title:(*self.InstrumentPtr).title}

Sample_Name=*self.Sample_NamePtr


;hbar_omega = '!6!sh!r!e/!n !7x!6'
;xlabel=hbar_omega
xlabel='Energy'
if self.units eq 4 then xlabel = 'T'
if self.units eq 5 then xlabel = 't'
;if self.units ne 5 then begin
;xlabel = hbar_omega
;endif else begin
;xlabel = 't'
;endelse
;xlabel=self.xlabel


if self.units eq 0 then xunits = 'Energy / meV'
if self.units eq 1 then xunits = 'Energy / Wavenumbers'
if self.units eq 2 then xunits = 'Energy / GHz'
if self.units eq 3 then xunits = 'Energy /  THz'
if self.units eq 4 then xunits = 'Energy / K'
if self.units eq 5 then xunits = 'Time / Microseconds'
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
if DataOutput[0] eq 0 then begin
yunits = 'Wavevector:A-1'
ylabel = 'Q '
endif
if DataOutput[0] eq 1 or DataOutput[0] eq 2 then begin
yunits = 'Phi:degrees'
ylabel = 'Phi '
endif

histlabel = 'I (arbitrary units)'
histunits = ''

Mon_cumTreat = 'Total incident beam monitor counts: '+ $
           strtrim(string(total(*self.Mon_cumPtr)),2)
*self.treatmentPtr = [*self.treatmentPtr,Mon_cumTreat]
msg = 'Number of channels: '+strtrim(string(nchan),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]
msg = 'Number of groups: '+strtrim(string(ndet),2)
*self.treatmentPtr = [*self.treatmentPtr,msg]

;*(*(*davePtr).dataStrPtr).commonStr.treatmentPtr = *self.treatmentPtr
if n_elements(temperature) gt 1 then temperature = (moment(temperature))[0]

thisformat='(8(f10.5))'
thisformat2='(8(e10.3))'
openw,lun,fileout,/get_lun
printf,lun, ndet,nchan
;write phi values
printf,lun, '###  '+ylabel+' '+yunits
printf,lun, y,Format=thisformat
;write energy values (convert from mid-points to histogram start/end)
nx=n_elements(x)
x1=[x[0]-(x[1]-x[0]),x]
x2=[x,x[nx-1]+(x[nx-1]-x[nx-2])]
x=(x1+x2)/2.
printf,lun, '###  '+xunits
printf,lun, x,Format=thisformat
for i = 0, ndet-1 do begin
printf,lun, '###  '+output
printf,lun, data[*,i],Format=thisformat2
printf,lun, '###  error'
printf,lun,error[*,i],Format=thisformat2
endfor
free_lun,lun,/force
;
openw,lun,FilePar,/get_lun
printf,lun, 'Instrument: FOCUS'
printf,lun, 'Sample: '+strtrim(string(Sample_Name.sample),2)
printf,lun, 'Original File Name: '+strtrim(string(Sample_Name.foriname),2)
printf,lun, 'Title: '+strtrim(string(Sample_Name.title),2)
printf,lun, 'User: '+strtrim(string(Instrument_Details.owner),2)
printf,lun, 'Temperature / K: '+strtrim(string(temperature),2)
printf,lun, 'XType: Points'
printf,lun, 'Group Type: Points'
printf,lun, 'X Units: '+strtrim(string(xunits),2)
printf,lun, 'Y Units: '+strtrim(string(histlabel),2)
printf,lun, 'Group Units: '+strtrim(string(yunits),2)
printf,lun, 'Group Label: '+strtrim(string(ylabel),2)
printf,lun, 'Number of Channels: '+strtrim(string(nchan),2)
printf,lun, 'Number of Groups: '+strtrim(string(ndet),2)
printf,lun, 'Wavelength / A: '+strtrim(string((*self.tof_corr_structurePtr).lambdatof),2)
printf,lun, 'Date Data File Created: '+strtrim(string(Sample_Name.ftime),2)
printf,lun, 'Date This File Created: '+strtrim(string(systime()),2)
printf,lun, 'Fermispeed: '+strtrim(string(Instrument_Details.fermispeed),2)
printf,lun, 'Fermiphase: '+strtrim(string(Instrument_Details.fermiphase),2)
printf,lun, 'Diskspeed: '+strtrim(string(Instrument_Details.diskspeed),2)
printf,lun, *self.treatmentPtr
free_lun,lun,/force
;
form='(8(f10.2))'
;
help,y
openw,lun, FilePhx,/get_lun
printf,lun, ndet
for i = 0, ndet-1 do begin
printf,lun, 10.0,0.0,-y[i],(*self.AzimutalAnglePtr)[i],0.688,9.17,1,format=form
endfor
free_lun,lun,/force

;
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::Diffraction,event=event
files = *self.sigFilePtr
files=files[0]
if n_elements(*self.vanFilePtr) eq 0 then return
data = *self.dataPtr
error = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
ndet=self.ndet
lambda=(*self.tof_corr_structurePtr).lambdatof
ErrorMsg=0
widget_control,self.DiffractionCalcGroup,get_value = DiffractionCalc ; 0 sum all time channels; 1 sum over range
;
IF DiffractionCalc eq 0 then begin
DiffInt=total(data,1)
self->DiffVanCal,DiffInt,event = event,ErrorMsg = ErrorMsg
;help,ErrorMsg
if ErrorMsg[0] eq 1 then return
DiffInt_error=sqrt(DiffInt)
void=PlotDiffractionData(DiffInt,DiffInt_error,y,lambda,group_leader = event.top)
treat=['Diffraction Pattern Calculated From Sum Over All Time Channels.']
ENDIF
;
IF DiffractionCalc eq 1 then begin
widget_control,self.DiffMin,get_value = DiffMin
widget_control,self.DiffMax,get_value = DiffMax
DiffMin = float(DiffMin[0])
DiffMax = float(DiffMax[0])
xrangesubs1=where(x ge DiffMin,count)
if count eq 0 then return
x_1stcull=x[xrangesubs1]
xrangesubs2=where(x_1stcull le DiffMax,count)
if count eq 0 then return
xrangesubs=xrangesubs1[0]+xrangesubs2
;print,''
;print,x[xrangesubs]
;help,data
data=data[xrangesubs,*]
;help,data
DiffInt=total(data,1)
self->DiffVanCal,DiffInt,event = event,ErrorMsg = ErrorMsg
if ErrorMsg[0] eq 1 then return
DiffInt_error=sqrt(DiffInt)
void=PlotDiffractionData(DiffInt,DiffInt_error,y,lambda,group_leader = event.top)
treat=['Diffraction Pattern Calculated from Time Channels in the Range: ' $
       +strtrim(string(DiffMin),2)+' to '+strtrim(string(DiffMax),2)+' Microseconds.']
ENDIF
*self.treatmentPtr = [*self.treatmentPtr,treat]
;
sintholam=sin((!dtor*y/2.0)/lambda)
;
; what is the filename?
widget_control,self.runGroup,get_value = rungroup
rungroup=rungroup[0]
widget_control,self.DiffOutput_nameGroup,get_value = DiffOutput_name
DiffOutput_name=DiffOutput_name[0]
;
    if  DiffOutput_name eq 0 then begin
  filename_result = strsplit(files,path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)


   fileOut = filepath(filename,root_dir = self.workDir)
    if rungroup eq 1 then  fileout+='++'
endif


       if DiffOutput_name eq 1 then begin
;
; First extract the filename
  filename_result = strsplit(files,path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)
  ;extPos = strpos(files[0],'.focus')
  ;filename = strmid(files[0],extPos-11,11)

  fileExample = filename
  fileOut = dialog_pickfile(dialog_parent = event.top,/write, $
  ;                          file = filename, $
                            file = filename, $ ; following IGOR
                          ;  if rungroup eq 1 then  file+='++', $
                          filter = ['*diff.dat'],$
                            title = 'Diffraction Output Filename',$
                            path = self.workDir)
;   fileOut = filepath(filename+'++',root_dir = self.workDir)
;
       endif

       if  DiffOutput_name eq 2 then begin
  filename_result = strsplit(files,path_sep(),/extract)
  n_comp = n_elements(filename_result)
  filename = filename_result[n_comp-1] ; filename with .hdf attached
  extPos = strpos(filename,'.hdf')
  filename = strmid(filename,0,extPos)

   fileOut = filepath(filename,root_dir = self.workDir)
    if rungroup eq 1 then  fileout+='++'
  widget_control, self.Diffstem2, get_value=stem_add
    if strlen(stem_add) gt 0 then    fileOut+=stem_add

   endif
   fileout+='diff.dat'

;print the data to a file
;
thisformat='(4(f15.6,2x))'
openw,lun,fileout,/get_lun
printf,lun, *self.treatmentPtr
printf,lun, 'Wavelength / A: '+strtrim(string((*self.tof_corr_structurePtr).lambdatof),2)
printf,lun, ''
printf,lun, '      Two Theta    Sin(Theta)/lambda   Intensity          Error'
printf,lun, 'Begin'
for i = 0, ndet-1 do begin
printf,lun, y[i],sintholam[i],DiffInt[i],DiffInt_Error[i],Format=thisformat
endfor
free_lun,lun,/force


end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::DiffVanCal,DiffInt,event = event,ErrorMsg=ErrorMsg

CATCH, Error_status
if Error_status ne 0 then begin
  catch, /cancel
  message=strarr(3)
  message[0]='Unable to Normalise to Vanadium.'
  message[1]='Check to see whether you have removed any dead detectors'
  message[2]='Error Message from IDL: '+!ERROR_STATE.MSG
  void=dialog_message(dialog_parent=event.top,/error,message)
  return
endif

; First pull out the current data values
sigData = *self.dataPtr
sigError = *self.errorPtr
sigX = *self.xvalsPtr
sigY = *self.yvalsPtr
sigMon_tc = *self.Mon_tcPtr
sigMon_cum = *self.Mon_cumPtr
sigTemp = *self.tempPtr
signdet=self.ndet
tof_corr_structure=*self.tof_corr_structurePtr
self->Sum_Vandium_Runs,event = event,err = err
vtemperature = *self.tempPtr
vtemperature = vtemperature[0]
if vtemperature eq 0 then vtemperature = 298.0
widget_control,self.DetectorBankTypesGroup,get_value = DBT
widget_control,self.FormatTypesGroup,get_value = FormatType

IF (DBT EQ 1) OR (DBT EQ 5) OR (FormatType EQ 3) THEN BEGIN
self->subtract_bad_detectors,event = event,err = err,/PREVIOUS
vandata = *self.dataPtr
detnum=*self.yvalsPtr
ENDIF ELSE BEGIN

vdata = *self.data1dPtr
;help,vdata
;help,vtemperature
;print,'vtemperature =',vtemperature
detnum=*self.yvalsPtr
;print,'*self.xvalsPtr =',*self.xvalsPtr
;
;Apply the same detector filtering as before
;
;
good_det1D=*self.good_det1DPtr
pnewdata=ptr_new(fltarr((size(vdata))[1],n_elements(good_det1D)))
pnewdetnum=ptr_new(fltarr(n_elements(good_det1D)))
;
*pnewdata=vdata(*,good_det1D)
*pnewdetnum=detnum(good_det1D)
vData=*pnewdata
detnum=*pnewdetnum
ptr_free,pnewdata
ptr_free,pnewdetnum
;
;print,'detnum =',detnum
;print,'good_det1D =',good_det1D
;print,'n_elements(good_det1D) =',n_elements(good_det1D)


;sort the data in ascending order of detnum
;
sortorder=sort(detnum)
detnum=detnum[sortorder]
vdata=vdata[*,sortorder]
;print,detnum
;
dimensions=size(vdata)
pnewdata=ptr_new(fltarr(dimensions[1],dimensions[2]))
pnewdetnum=ptr_new(fltarr((size(detnum))[1]))
;remove degeneracies
;
(*pnewdetnum)[0]=detnum[0]
(*pnewdata)[*,0]=vdata[*,0]
j=0
for i=1,n_elements(detnum)-1 do begin
    if detnum[i] ne detnum[i-1] then begin
j+=1
(*pnewdetnum)[j]=detnum[i]
(*pnewdata)[*,j]=vdata[*,i]
endif else begin
(*pnewdata)[*,j]+=vdata[*,i]
endelse
endfor
vanData=(*pnewdata)[*,0:j]
detnum=(*pnewdetnum)[0:j]
ptr_free,pnewdata
ptr_free,pnewdetnum


ENDELSE


;*self.treatmentPtr = [*self.treatmentPtr,treat]
;*self.dataPtr = vData
;vError = sqrt(vData)
;*self.errorPtr = vError
;*self.yvalsPtr = detnum
;
;

vanx = *self.xvalsPtr
;print,total(vandata)
;print,'*self.xvalsPtr =',*self.xvalsPtr
;
;print,'vanData(*,1) =',vanData(*,1)
;print,''
for i = 0,n_elements(detnum)-1 do begin
   ; Get a good estimate of the starting parameters for the fits


  y = reform(vanData[*,i])
 zeropos=(vanx[where(y eq max(y))])[0]
  coeff=[max(y),zeropos,70.0,0]
  region = where((vanX ge zeropos-200.0) and (vanX le zeropos+200.0))
x=vanX[region]
;print,'x = ',x
 y = reform(vanData[region,i])

 ;print,'y = ',y

 ;print,'coeff =',coeff
;print,i
;print,vanx
  ; Fit it...
  result = gaussfit(x,y,p,chisq=gof,estimates = coeff,nterms = 4)
  ; the next line should be the area
  ;print, 'Chisq =',gof
  ;print, 'fwhh =',p[2]
  ;print, 'max(y) =',p[0]
  ;print, 'x position =',p[1]
  ;print,''
  a = p[0]*sqrt(2.0*!pi*p[2]^2)
  if i eq 0 then area = a else area = [area,a]
endfor
whereneg=where(area lt 0, count1)
wherebig=where(abs(area) gt 1e6, count2)
wheresmall=where(abs(area) lt 1, count3)
if (count1 ne 0) or (count2 ne 0) or (count3 ne 0) then begin
Faulty=[whereneg,wherebig,wheresmall]
Faulty=Faulty[where(Faulty ne -1)]
Faultystring='detectors: '
for i = 0, n_elements(Faulty) - 1 do begin
if i eq 0 then begin
Faultystring+=strtrim(string(Faulty[i]),2)
endif else begin
Faultystring+=','+strtrim(string(Faulty[i]),2)
endelse
endfor
msg=strarr(3)
msg[0]='CALIBRATION OF DETECTORS FROM VANADIUM RUN HAS FAILED!'
msg[1]='Unable to obtain a reasonable fit of the elastic line'
msg[2]='from '+Faultystring+'.'
    void=dialog_message(dialog_parent=event.top,/error,msg)
;restore data
*self.dataPtr = sigData
*self.errorPtr = sigError
*self.xvalsPtr = sigX
*self.yvalsPtr = sigY
*self.Mon_tcPtr = sigMon_tc
*self.Mon_cumPtr = sigMon_cum
*self.tempPtr = sigTemp
self.ndet=signdet
treat = ['Unable to normalise to vanadium file(s): '+strtrim(string(*self.vanFilePtr),2), $
       'for the purpose of calculating the diffraction pattern']
*self.treatmentPtr = [*self.treatmentPtr,treat]
return
endif

;print, 'vanx =',vanx
stats = moment(area[0:n_elements(detnum)-1])
;stats[0] is then the mean average area.  Now divide each area by the mean average
area = temporary(area)/stats[0]
;ux = 1+bytarr(n_elements(sigX))
lambda0=tof_corr_structure.lambdatof
q = (4.0*!pi/lambda0)*sin(0.5*!dtor*detnum)
dwf = (exp(-0.0067*vtemperature/300.0*q^2))  ; Debye-Waller factor for vanadium
DiffInt = DiffInt*dwf/area
;restore the data
*self.dataPtr = sigData
*self.errorPtr = sigError
*self.xvalsPtr = sigX
*self.yvalsPtr = sigY
*self.Mon_tcPtr = sigMon_tc
*self.Mon_cumPtr = sigMon_cum
*self.tempPtr = sigTemp
self.ndet=signdet
;print,'v ndet =',self.ndet
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::zoomEvents,event = event
if n_elements(*self.dataPtr) eq 0 then return
case event.type of
0: begin    ; button press
     self.mouse = event.press
     if self.mouse eq 4 then begin
       self.autoscale = 1
        self->display,event = event
     endif
     if self.mouse eq 1 then begin
       self.xbox[0] = event.x
       self.ybox[0] = event.y
        self->display,event = event
       empty
       self.autoscale = 0
       widget_control,self.win,/draw_motion_events
     endif
   end
1: begin ; button release
    if self.mouse eq 1 then begin
     xll = self.xbox[0] < self.xbox[1]
     yll = self.ybox[0] < self.ybox[1]
     w = abs(self.xbox[1] - self.xbox[0])
     h = abs(self.ybox[1] - self.ybox[0])
     xur = xll + w
     yur = yll + h
     ll = convert_coord(xll,yll,/device,/to_data)
     ur = convert_coord(xur,yur,/device,/to_data)
     self.xrange = [ll[0],ur[0]]
     self.yrange = [ll[1],ur[1]]
      self->display,event = event
     self.mouse = 0B
     widget_control,self.win,draw_motion_events = 0
    endif
    if self.mouse eq 4 then begin
     self->display,event = event
     self.mouse = 0B
     widget_control,self.win,draw_motion_events = 0
    endif
   end
2: begin ; mouse motion
     if self.mouse eq 1 then begin
        self.xbox[1] = event.x
        self.ybox[1] = event.y
        xc = [self.xbox[0],event.x,event.x,$
              self.xbox[0],$
              self.xbox[0]]
        yc = [self.ybox[0],self.ybox[0],$
              event.y,event.y,$
              self.ybox[0]]
        wset,self.winVis
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.winPix]
        plots,xc,yc,/device
        empty
     endif
   end
else:
endcase
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::reduce_help,event = event
;pdf_file = file_which('focus_data_reduction.pdf',/include_current_dir)
delim=path_sep()
pdf_file = !DAVE_AUXILIARY_DIR+delim+'PSI'+delim+'FOCUS'+delim+'focus_data_reduction.pdf'
;pdf_file = !DAVE_AUXILIARY_DIR+'\PSI\FOCUS\focus_data_reduction.pdf'
void = launch_help(pdf_file,tlb = event.top)
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction::createwidgets
; Widget definition method
if n_elements(*self.pgroup_leader) eq 0 then begin
  tlb = widget_base(/row, $
        title = 'Focus Data Reduction',mbar = bar,/tlb_size_events);, $
;         /scroll,Y_SCROLL_SIZE=752,X_SCROLL_SIZE=1102)
endif else begin
  tlb = widget_base(group_leader = *self.pgroup_leader,/row, $
        title = 'Focus Data Reduction',mbar = bar,/tlb_size_events);, $
;         /scroll,Y_SCROLL_SIZE=752,X_SCROLL_SIZE=1102)
endelse
self.tlb = tlb
self.ctrlBase = widget_base(self.tlb,/row)
master_button_base = widget_base(self.ctrlbase,/col,/frame)

ubase_master = widget_base(master_button_base,/col)
void=widget_label(ubase_master,/sunken_frame,value='BASIC INPUT')
ubase = widget_base(ubase_master,/row)
lbase = widget_base(master_button_base,/col)
void=widget_label(lbase,/sunken_frame,value='ADVANCED OPTIONS')
lubase_col = widget_base(ubase,/col)
rubase_col = widget_base(ubase,/col)


treatTypes = ['Vanadium Normalisation',$
              'Background Subtraction'];, $
;              'Energy binning']
treatGroup = cw_bgroup(lubase_col,treatTypes,/col,/nonexclusive,$
           set_value = [0,0],/return_index, /frame,$
           uvalue = {object:self,method:'treatmentHandler'})
self.treatGroup = treatGroup
;help,runGroup
;print,runGroup
;
sigfile_base=widget_base(lubase_col,/col,/frame)
;

self.signal_runs = cw_field(sigfile_base,/row,uvalue = {object:self,method:'selSigRuns'},$
                 title = 'Signal Run(s)',/return_events)


void = widget_button(sigfile_base,value = 'Browse for Signal File(s)', $
      uvalue = {object:self,method:'selSigFiles'})


self.van_Base=widget_base(lubase_col,/col,/frame,sensitive=0)

self.vanadium_run = cw_field(self.van_Base,/row,uvalue = {object:self,method:'selVanRun'},$
                 title = 'Van. Run(s)',/return_events)


void = widget_button(self.van_Base,value = 'Browse for Vanadium File(s)', $
               uvalue = {object:self,method:'selVanFile'})

self.Bg_Base=widget_base(lubase_col,/col,/frame,sensitive=0)

self.Background_runs = cw_field(self.Bg_Base,/row,uvalue = {object:self,method:'selEmptyRuns'},$
                 title = 'Empty Run(s)',/return_events)


void = widget_button(self.Bg_Base,value = 'Browse for Background File(s)', $
               uvalue = {object:self,method:'selBgFiles'})


runTypes = ['Single Sample Runs','Sum All Runs']
runGroup = cw_bgroup(rubase_col,runTypes,/col,/exclusive,$
           /no_release,set_value = 1,/return_index, /frame,$
           uvalue = {object:self,method:'rungroupHandler'})
self.runGroup = runGroup


void = widget_label(rubase_col,value = 'Signal Run(s)')
xtextSize = 18
self.fileText = widget_text(rubase_col,ysize = 5,xsize = xtextSize,/scroll)
void = widget_label(rubase_col,value = 'Vanadium Run(s)')
self.vanText = widget_text(rubase_col,xsize = xtextSize,/scroll)
void = widget_label(rubase_col,value = 'Background Run(s)')
self.bgText = widget_text(rubase_col,xsize = xtextSize,ysize = 4,/scroll)
void = widget_button(lubase_col,value = '?Help?', $
               uvalue = {object:self,method:'reduce_help'})
void = widget_button(lubase_col,value = 'Quit', $
       uvalue = {object:self,method:'quit'})
void = widget_button(lubase_col,value = 'REDUCE DATA', $
               uvalue = {object:self,method:'reduce'})

Opt_Tab=widget_Tab(lbase,uvalue={object:self,method:'doNothing'})
Output_master = widget_base(Opt_Tab,/row,title='Output')
Bin_master = widget_base(Opt_Tab,/row,title='Binning')
ElasticLine_master = widget_base(Opt_Tab,/row,title='Elastic Line')
Detector_master = widget_base(Opt_Tab,/row,title='Detector')
Diffraction_master = widget_base(Opt_Tab,/row,title='Diffraction')
TwoD_master = widget_base(Opt_Tab,/row,title='2d Det.')
Misc_master = widget_base(Opt_Tab,/row,title='Misc.')

Output_name_Lbase=widget_base(Output_master,/col)

Output_name_base=widget_base(Output_name_Lbase,/col)
void=widget_label(Output_name_base,value='Output File Name')
Output_name_subbase=widget_base(Output_name_base,/col,/frame)

Output_nameTypes= ['Automatically Assigned',  $
          'Specify Output File Name on Prompt', $
              'Add to Stem:']

Output_nameGroup = cw_bgroup(Output_name_subbase,Output_nameTypes,/col,/exclusive, $
           /no_release,set_value = 0,/return_index, $
           uvalue = {object:self,method:'OutputName_handler'})
self.Output_nameGroup = Output_nameGroup

self.Output_name_subbase_sensitive=widget_base(Output_name_subbase,/row)

self.Output_name_subbase_sensitive1=widget_base(self.Output_name_subbase_sensitive,sensitive=0)
self.stem1 = cw_field(self.Output_name_subbase_sensitive1,title='', $
              uvalue = {object:self,method:'doNothing'},/row,value = '')

self.Output_name_subbase_sensitive2=widget_base(self.Output_name_subbase_sensitive,sensitive=0)
self.stem2 = cw_field(self.Output_name_subbase_sensitive2,title='', xsize=5, $
              uvalue = {object:self,method:'doNothing'},/row,value = '')

self.Output_name_subbase_sensitive3=widget_base(self.Output_name_subbase_sensitive,sensitive=0)
self.stem3 = cw_field(self.Output_name_subbase_sensitive3,title='', xsize=8, $
          uvalue = {object:self,method:'doNothing'},/row,value = 'dyn.dave',/noedit)

Output_name_Ubase=widget_base(Output_name_Lbase,/row)

FormatTypes = ['Dave',$
              'IGOR Text', $
              'ASCII',  $
              'Matlab/MSlice']
FormatTypesGroup = cw_bgroup(Output_name_Ubase,FormatTypes,row=2,/exclusive,label_top='Output Formats',$
           set_value = 0,/return_index, /frame,$
           uvalue = {object:self,method:'FormatTypes'})
self.FormatTypesGroup = FormatTypesGroup



;Output_name_Rbase=widget_base(Output_master,/col)


DataOutputTypes = ['S(Q,w)',$
              'S(Q,w)_phi', $
              'S(Phi,t)']

DataOutputTypesGroup = cw_bgroup(Output_name_Ubase,DataOutputTypes,row=2,/exclusive,label_top='Data Output', $
           set_value = 0,/return_index,/frame, $
           uvalue = {object:self,method:'Data_Output_Handler'})
self.DataOutputTypesGroup = DataOutputTypesGroup


EBin_submaster=widget_base(Bin_master,/col)
void=widget_label(EBin_submaster,value='Energy/TOF Binning')

E_TOF_base=widget_base(EBin_submaster,/col,/frame)


ebin_Types = ['No Binning','Binning and Units']
ebin_Group = cw_bgroup(E_TOF_base,ebin_Types,row=2,/exclusive,$
           /no_release,set_value = 0,/return_index,$
           uvalue = {object:self,method:'E_TOF_handler'})
self.ebin_group = ebin_Group

self.E_TOF_base1=widget_base(E_TOF_base,/col,sensitive=0)

ebin_Types1 = ['Modify Default','Modify Previous','Use Previous']
ebin_Group1 = cw_bgroup(self.E_TOF_base1,ebin_Types1,row=3,/exclusive, $
           /no_release,set_value = 0,/return_index,$
           uvalue = {object:self,method:'doNothing'})
self.ebin_group1 = ebin_Group1



QBin_submaster=widget_base(Bin_master,/col)
void=widget_label(QBin_submaster,value='Q/Phi Binning/Grouping')

Q_Theta_base=widget_base(QBin_submaster,/col,/frame)


Qbin_Types = ['Sum All','Binning/Grouping']
qbin_Group = cw_bgroup(Q_Theta_base,qbin_Types,row=2,/exclusive,$
           /no_release,set_value = 0,/return_index,$
           uvalue = {object:self,method:'Q_Theta_handler'})
self.qbin_group = qbin_Group


self.q_theta_base1=widget_base(q_theta_base,/col,sensitive=0)

qbin_Types1 = ['Modify Default','Modify Previous','Use Previous']
qbin_Group1 = cw_bgroup(self.q_theta_base1,qbin_Types1,row=3,/exclusive, $
           /no_release,set_value = 0,/return_index,$
           uvalue = {object:self,method:'qbin_Types1_handler'})
self.qbin_group1 = qbin_Group1


elasticbase=widget_base(ElasticLine_master,/frame,/col)

elasticTypes = ['Vanadium File, TOF Data',$
          'Sample File(s), TOF Data',$
          'Sample File(s), Monochromator',$
          'Own Value']
elasticGroup = cw_bgroup(elasticbase,elasticTypes,row=4,/exclusive,label_top='Elastic Line From:',$
           /no_release,set_value = 0,/return_index,$
           uvalue = {object:self,method:'LambdaHandler'})
self.elasticGroup = elasticGroup

lambda_tof = cw_field(elasticbase,/row,uvalue = {object:self,method:'doNothing'},$
                 title = 'Lambda TOF',/noedit)

lambda_monochromator = cw_field(elasticbase,/row,uvalue = {object:self,method:'doNothing'},$
                title = 'Lambda Mon.',/noedit)

self.elastic_base_sensitive=widget_base(elasticbase,/col,sensitive=0)
 self.lambda_own_value = cw_field(self.elastic_base_sensitive,/row,uvalue = {object:self,method:'doNothing'},$
                 title = 'Lambda Own')


lambda_field={lambda_field,lambda_monochromator:lambda_monochromator, $
          lambda_tof:lambda_tof}

*self.lambda_fieldPtr=lambda_field
;print,(*self.lambda_fieldPtr).lambda_tof



Bad_DetectorTypes = ['Automatic',$
              'Graphical Masking', $
              'Scroll Spectra Masking',$
              'Previous Selection',  $
              'Use All Detectors']
Bad_DetectorGroup = cw_bgroup(Detector_master,Bad_DetectorTypes,row=5,/exclusive,label_top='Bad Detector Removal',$
           /no_release,set_value = 0,/return_index, /frame,$
           uvalue = {object:self,method:'Bad_DetectorGroup_Handler'})
self.Bad_DetectorGroup = Bad_DetectorGroup

DetectorBankTypes = ['Merge Conventional',$
              'Merge All',$
              'Lower', $
              'Middle', $
              'Upper', $
              '2d']
DetectorBankTypesGroup = cw_bgroup(Detector_master,DetectorBankTypes,/col,/exclusive,label_top='Detector Bank',$
           set_value = 0,/return_index, /frame,$
           uvalue = {object:self,method:'doNothing'})
self.DetectorBankTypesGroup = DetectorBankTypesGroup

;Diffraction Tab
Diffraction_Base_submaster=widget_base(Diffraction_master,/col)

self.Diffraction_Base1=widget_base(Diffraction_Base_submaster,/col,sensitive=0)

DiffONType = ['Generate Diffraction Pattern (Vanadium Run Required)             '] ;adjust the length to make tabs look nice.

DiffONGroup = cw_bgroup(self.Diffraction_Base1,DiffONType,/col,/nonexclusive,$
           set_value = 0,/return_index,$
           uvalue = {object:self,method:'DiffONHandler'})

self.DiffONGroup=DiffONGroup


self.Diffraction_Base2=widget_base(Diffraction_Base_submaster,/col,sensitive=0)


Diffraction_BaseRow=widget_base(self.Diffraction_Base2,/row)

DiffractionCalcTypes = ['Sum Over All Channels',$
                     'Sum Between Channels (us):']

DiffractionCalcGroup = cw_bgroup(Diffraction_BaseRow,DiffractionCalcTypes,/col,/exclusive,$
           set_value = 0,/return_index,$
           uvalue = {object:self,method:'DiffractionCalcHandler'})

self.DiffractionCalcGroup=DiffractionCalcGroup


self.Diffraction_Base3=widget_base(Diffraction_BaseRow,/row,sensitive=0)


self.DiffMin = cw_field(self.Diffraction_Base3,title='Min', xsize=5, $
              uvalue = {object:self,method:'doNothing'},/row,value = '')

self.DiffMax = cw_field(self.Diffraction_Base3,title='Max', xsize=5, $
              uvalue = {object:self,method:'doNothing'},/row,value = '')

DiffOutput_name_base=widget_base(self.Diffraction_Base2,/col)
void=widget_label(DiffOutput_name_base,value='Output File Name')
DiffOutput_name_subbase=widget_base(DiffOutput_name_base,/col,/frame)

DiffOutput_nameTypes= ['Automatically Assigned',  $
          'Specify Output File Name on Prompt', $
              'Add to Stem:']

DiffOutput_nameGroup = cw_bgroup(DiffOutput_name_subbase,DiffOutput_nameTypes,/col,/exclusive, $
           /no_release,set_value = 0,/return_index, $
           uvalue = {object:self,method:'DiffOutputName_handler'})
self.DiffOutput_nameGroup = DiffOutput_nameGroup

self.DiffOutput_name_subbase_sensitive=widget_base(DiffOutput_name_subbase,/row)

self.DiffOutput_name_subbase_sensitive1=widget_base(self.DiffOutput_name_subbase_sensitive,sensitive=0)
self.Diffstem1 = cw_field(self.DiffOutput_name_subbase_sensitive1,title='', $
              uvalue = {object:self,method:'doNothing'},/row,value = '')

self.DiffOutput_name_subbase_sensitive2=widget_base(self.DiffOutput_name_subbase_sensitive,sensitive=0)
self.Diffstem2 = cw_field(self.DiffOutput_name_subbase_sensitive2,title='', xsize=5, $
              uvalue = {object:self,method:'doNothing'},/row,value = '')

self.DiffOutput_name_subbase_sensitive3=widget_base(self.DiffOutput_name_subbase_sensitive,sensitive=0)
self.Diffstem3 = cw_field(self.DiffOutput_name_subbase_sensitive3,title='', xsize=8, $
          uvalue = {object:self,method:'doNothing'},/row,value = 'diff.dat',/noedit)

;2d DetectorTab

;2d detector parameters
Detector2d_base=widget_base(TwoD_master,/col)
void=widget_label(Detector2d_base,value = '2d Detector Parameters')
Detector2d_baseA=widget_base(Detector2d_base,row=3,/frame)
;void=widget_label(Detector2d_base,value = '2d Detector Parameters')

self.Det2d_DistanceBins = cw_field(Detector2d_baseA,title='Number of distance bins', $
          uvalue = {object:self,method:'doNothing'},/col,value = '200')

self.Det2d_TimeToMap = cw_field(Detector2d_baseA,title='Time mapping duration / sec.', $
          uvalue = {object:self,method:'doNothing'},/col,value = '',/noedit)


self.Det2d_ThetaBins = cw_field(Detector2d_baseA,title='Number of theta bins', $
          uvalue = {object:self,method:'doNothing'},/col,value = '20')

self.Det2d_TimeThetaBins = cw_field(Detector2d_baseA,title='Theta binning duration / sec.', $
          uvalue = {object:self,method:'doNothing'},/col,value = '',/noedit)


void=widget_label(Detector2d_baseA,value = 'Spike Removal Intensity Factor')

self.Det2d_Spikes = cw_field(Detector2d_baseA,title='*',$
          uvalue = {object:self,method:'doNothing'},/row,value = '10')


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MISC PANEL
;;

Misc_Base00=widget_base(Misc_master,/col)
Misc_Base0=widget_base(Misc_Base00,/row)

Misc_Base1=widget_base(Misc_Base0,/col,/frame)

; No_Output / Detailed_Balance / Flat_Baseline

Misc1Types = ['No Output', $
          'Detailed Balance',$
              'Flat Baseline']

Misc1Group = cw_bgroup(Misc_Base1,Misc1Types,/col,/nonexclusive,$
           set_value = [0,0,0],/return_index,$
           uvalue = {object:self,method:'Misc1Handler'})

self.Misc1Group=Misc1Group


self.Misc_Base2=widget_base(Misc_Base1,/col,sensitive=0)
self.flat_baseline_range = cw_field(self.Misc_Base2,title='Channels:', $
              uvalue = {object:self,method:'doNothing'},/row,value = '100',xsize=5)

; Normalisation options

Misc_Base3=widget_base(Misc_Base0,/col,/frame)

Misc2Types = ['Normalise']
self.Misc2Group = cw_bgroup(Misc_Base3,Misc2Types,/col,/nonexclusive,$
           set_value = 1,/return_index,$
           uvalue = {object:self,method:'Misc2Handler'})


self.Misc3Group_subbase=widget_base(Misc_Base3,sensitive=1)
Misc3Types = ['To Monitor','To Unity']
self.Misc3Group = cw_bgroup(self.Misc3Group_subbase,Misc3Types,/row,/exclusive,$
           set_value = 0,/return_index, $
           uvalue = {object:self,method:'doNothing'})

; Energy dependent efficiency correction

self.MiscDetEffGroup = cw_bgroup(Misc_Base3,['Energy dependent detector efficiency'],/col,/nonexclusive,$
           set_value = 0,/return_index,$
           uvalue = {object:self,method:'doNothing'})

; Background options

Misc_Base2=widget_base(Misc_Base00,/col,/frame)

self.BackgroundSubtractionField = cw_field(Misc_Base2,title='Background weightening',$
          uvalue = {object:self,method:'doNothing'},/row,value = '1.0',xsize=5)

; Self-shielding options

Misc_BaseX=widget_base(Misc_Base00,/col,/frame)

MiscXGroup = cw_bgroup(Misc_BaseX,['Self-shielding Correction'],/col,/nonexclusive,$
           set_value = 0,/return_index,$
           uvalue = {object:self,method:'MiscXHandler'})
self.MiscXGroup=MiscXGroup
self.Misc_BaseX=widget_base(Misc_BaseX,/col,sensitive=0)

self.SelfShieldField = cw_field(self.Misc_BaseX,title='Input File Name (TTH,SAF,SSF):', $
              uvalue = {object:self,method:'doNothing'},/row,value = '',xsize=25)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

plotBase = widget_base(self.tlb,/col)
winxsize = 400 & winysize = 400
self.win = widget_draw(plotBase,xsize = winxsize,ysize = winysize, $
           /button_events,uvalue = {object:self,method:'zoomEvents'})
self.grpSlider = widget_slider(plotBase,minimum = 1,maximum = 300, $
          uvalue = {object:self,method:'display'})

; Get the vertical size right
cgeom = widget_info(self.ctrlBase,/geometry)
winysize = cgeom.ysize > winysize
winxsize = winysize
widget_control,self.win,ysize = winysize,xsize = winxsize

; Center the widget
geom = widget_info(self.tlb,/geometry)
device,get_screen_size = sz
sx = sz[0] & sy = sz[1]
xoff = fix(0.5*(sx-geom.xsize))
yoff = fix(0.5*(sy-geom.ysize))
widget_control,self.tlb,xoffset = xoff,yoffset = yoff

widget_control,self.tlb,/realize

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

widget_control,tlb,set_uvalue = self
ret = dave_set_focus(self.tlb)
xmanager,'focusreduction::createwidgets',self.tlb, $
         event_handler = 'focusReductionEvents',$
         cleanup = 'focusReductionCleanup', /no_block
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function focusreduction::init, group_leader = group_leader, $
                 notifyId = notifyId, $
                 workDir = workDir, $
                 datDir = datDir

tvlct,r,g,b,/get
self.rPtr = ptr_new(r)
self.gPtr = ptr_new(g)
self.bPtr = ptr_new(b)
loadct,0,/silent

self.notifyIdPtr = ptr_new(/allocate_heap)
self.pgroup_leader = ptr_new(/allocate_heap)

if n_elements(notifyId) ne 0 then $
  *self.notifyIdPtr = notifyId

if n_elements(group_leader) ne 0 then begin
  *self.pgroup_leader = group_leader
  ; Get the DAVE pointer information from group leader
  ; Note that the DAVE pointer is not valid if there is no
  ; group leader specified here!
  widget_control,group_leader,get_uvalue = statePtr
  self.davePtr = (*statePtr).davePtr
  ; DO NOT FREE THE STATEPTR HERE!!!! IT BELONGS TO THE
  ; PARENT (CALLING) WIDGET!!!!
endif

cd,current = curDir
if n_elements(workDir) eq 0 then self.workDir = curDir else self.workDir = workDir
if n_elements(datDir) eq 0 then self.datDir = '' else self.datDir = datDir

self.lambda_fieldPtr = ptr_new(/allocate_heap)

self->createwidgets
self.autoscale = 1
self.xrange = [0.0,1.0]
self.yrange = [0.0,1.0]
self.xbox = self.xrange
self.ybox = self.yrange
self.mouse = 0B

; Initialize all of the pointers
self.dataPtr = ptr_new(/allocate_heap)
self.errorPtr = ptr_new(/allocate_heap)
self.data1DPtr = ptr_new(/allocate_heap)
self.error1DPtr = ptr_new(/allocate_heap)
self.xvalsPtr = ptr_new(/allocate_heap)
self.yvalsPtr = ptr_new(/allocate_heap)
self.odata1DPtr = ptr_new(/allocate_heap)
self.oerror1DPtr = ptr_new(/allocate_heap)
self.oxvals1DPtr = ptr_new(/allocate_heap)
self.oyvals1DPtr = ptr_new(/allocate_heap)
self.sigFilePtr = ptr_new(/allocate_heap)
self.bgFilePtr = ptr_new(/allocate_heap)
self.vanFilePtr = ptr_new(/allocate_heap)
self.Mon_tcPtr = ptr_new(/allocate_heap)
self.Mon_cumPtr = ptr_new(/allocate_heap)
self.tempPtr = ptr_new(/allocate_heap)
self.InstrumentPtr = ptr_new(/allocate_heap)
self.tof_corr_structurePtr = ptr_new(/allocate_heap)
self.treatmentPtr = ptr_new(/allocate_heap)
self.headerPtr = ptr_new(/allocate_heap)
self.daveFiles = ptr_new(/allocate_heap)
self.good_det1DPtr = ptr_new(/allocate_heap)
self.good_det2DPtr = ptr_new(/allocate_heap)
self.selDetPtr = ptr_new(/allocate_heap)
*self.daveFiles = ''
self.Sample_NamePtr=ptr_new(/allocate_heap)
self.data2dPtr = ptr_new(/allocate_heap)
self.xvals2dPtr = ptr_new(/allocate_heap)
self.error2dPtr = ptr_new(/allocate_heap)
self.detarr2d = ptr_new(/allocate_heap)
self.distance2d = ptr_new(/allocate_heap)
self.theta2d = ptr_new(/allocate_heap)
self.Data2dIndexPtr = ptr_new(/allocate_heap)
self.AzimutalAnglePtr = ptr_new(/allocate_heap)



;
self.xlabel = ''
self.ylabel = ''
self.zlabel = ''
self.curFile = ''

self.detPtr = ptr_new(/allocate_heap)

self.titlePtr = ptr_new(/allocate_heap)
unit = !dave_invAngstromSym
titleArray='woof'
*self.titlePtr = titleArray

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro focusreduction__define
define = {focusreduction,      $

          tlb:0L,          $
          ctrlBase:0L,        $
          grpSlider:0L,       $
          runGroup:0L,        $
          elasticGroup:0L,        $
          Bad_DetectorGroup:0L,  $
          treatGroup:0L,      $
          FormatTypesGroup:0L,      $
          DataOutputTypesGroup:0L,      $
          DetectorBankTypesGroup:0L,      $
          van_Base:0L,       $
          lambda_own_value:0L,       $
          elastic_base_sensitive:0L,       $
          Bg_Base:0L,        $
          grpButton:0L,       $
          fileText:0L,        $
          vanText:0L,         $
          bgText:0L,       $
          ebin_group:0L,       $
          ebin_group1:0L,       $
          qbin_group1:0L,       $
          E_TOF_base1:0L,       $
          q_theta_base1:0L,       $
          Qbin_group:0L,       $
          units:0L,       $
          Output_nameGroup:0L,       $
          Output_name_subbase_sensitive:0L,       $
          Output_name_subbase_sensitive1:0L,       $
          Output_name_subbase_sensitive2:0L,       $
          Output_name_subbase_sensitive3:0L,       $
          stem1:0L,       $
          stem2:0L,       $
          stem3:0L,       $
          Misc1Group:0L,       $
          Misc_Base2:0L, $
          flat_baseline_range:0L,   $
          MiscXGroup:0L, $
          Misc_BaseX:0L, $
          SelfShieldField:0L, $
          SelfShieldFilename:'', $
          DiffractionCalcGroup:0L,   $
          Diffraction_Base3:0L,   $
          DiffMin:0L,   $
          DiffMax:0L,   $
          DiffONGroup:0L,   $
          Diffraction_Base2:0L,   $
          DiffOutput_nameGroup:0L,   $
          DiffOutput_name_subbase_sensitive:0L,   $
          DiffOutput_name_subbase_sensitive1:0L,   $
          Diffstem1:0L,   $
          DiffOutput_name_subbase_sensitive2:0L,   $
          Diffstem2:0L,   $
          DiffOutput_name_subbase_sensitive3:0L,   $
          Diffstem3:0L,   $
          Diffraction_Base1:0L,   $
          Signal_Runs:0L,   $
          Background_Runs:0L,   $
          Vanadium_Run:0L,   $
          Det2d_DistanceBins:0L,   $
          Det2d_TimeToMap:0L,   $
          Det2d_TimeThetaBins:0L,   $
          Det2d_ThetaBins:0L,   $
          Det2d_Spikes:0L,   $
          TerminateIndex:0L,   $
          BackgroundSubtractionField:0L,   $
          Misc2Group:0L,   $
          Misc3Group_subbase:0L,   $
          Misc3Group:0L,   $
          MiscDetEffGroup:0L,   $

          ; Window/display variables
          win:0L,          $
          winVis:0L,       $
          winPix:0L,       $
          xrange:fltarr(2),      $
          yrange:fltarr(2),      $
          xbox:fltarr(2),      $
          ybox:fltarr(2),      $
          autoscale:1,        $
          mouse:0B,         $
          xlabel:'',       $
          ylabel:'',       $
          zlabel:'',       $
          titlePtr:ptr_new(),    $
          daveFiles:ptr_new(),     $

         ; NormalisationFactor
          NormFactor:1.0,          $

         ; Directory variables
          workDir:'',         $
          datDir:'',       $
          ; Detector pointer
          selDetPtr:ptr_new(),     $

          ; Raw data file variables
          Mon_tcPtr:ptr_new(),      $
          Mon_cumPtr:ptr_new(),      $
          headerPtr:ptr_new(),     $
          detPtr:ptr_new(),      $
          tempPtr:ptr_new(),   $
          instrumentPtr:ptr_new(),   $
          Sample_NamePtr:ptr_new(),   $
          tof_corr_structurePtr:ptr_new(),   $
          ndet:0,          $
          sf:fltarr(375),      $
          curFile:'',         $

          ; Original data set
          odata1DPtr:ptr_new(),    $
          oerror1DPtr:ptr_new(),     $
          oxvals1DPtr:ptr_new(),     $
          oyvals1DPtr:ptr_new(),     $

       ; Working data set
          dataPtr:ptr_new(),   $
          errorPtr:ptr_new(),    $
          data1DPtr:ptr_new(),   $
          error1DPtr:ptr_new(),    $
          xvalsPtr:ptr_new(),    $
          yvalsPtr:ptr_new(),    $

       ; Pointer to the lambda fields
       lambda_fieldPtr:ptr_new(),  $
       ; Good Detector Pointers
        good_det1DPtr:ptr_new(),   $
        good_det2DPtr:ptr_new(),   $

       ; Pointer to the Azimutal angle, used for the creation of matlab files
        AzimutalAnglePtr:ptr_new(),   $

       ; Colors for restoration upon quitting
          rPtr:ptr_new(),      $
          gPtr:ptr_new(),      $
          bPtr:ptr_new(),      $
          ; Detector pointer
          ; Treatment pointer
          treatmentPtr:ptr_new(),   $

          ; File pointers
          sigFilePtr:ptr_new(),   $
          bgFilePtr:ptr_new(),     $
          vanFilePtr:ptr_new(),   $

          ; Dave pointer
          davePtr:ptr_new(),   $

          ; Info about parent
          notifyIdPtr:ptr_new(), $
          pgroup_leader:ptr_new(),   $
          ; 2d data set
          data2dPtr:ptr_new(),   $
          xvals2dPtr:ptr_new(),    $
          error2dPtr:ptr_new(),    $
          distance2d:ptr_new(),    $
          theta2d:ptr_new(),    $
          detarr2d:ptr_new(),   $
          Data2dIndexPtr:ptr_new()   $
          }


return
end
