;###############################################################################
;
; NAME:
;  OSIRISSIMREDUCTION__DEFINE
;
; PURPOSE:
;  See description below.
;
; CATEGORY:
;  DAVE, OSIRISSIM, 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:
;       OSIRISSIMREDUCTION__DEFINE
;
; PURPOSE:
;
;       This object widget program performs the data reduction steps for
;   data sets collected on the Direct Geometry TOF Spectrometer OSIRISSIM, at SINQ, isis.
;   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('OSIRISSIMreduction')
;
;
; INPUT PARAMETERS:
;
;       NONE
;
; INPUT KEYWORDS:
;
;   GROUP_LEADER   - Parent widget of OSIRISSIMREDUCTION 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_OSIRISSIM_Energy_widget.pro
;   opan_OSIRISSIM_time_rebin_widget.pro
;   OSIRISSIMDetGroupWidget.pro
;   OSIRISSIM_graphical_masking.pro
;   OSIRISSIM_scroll_spectra_masking.pro
;   OSIRISSIM_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, 15 October, 2006.
;-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMReductionCleanup,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
      OSIRISSIMInfo = {OSIRISSIMReductionEvent,$
                            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 = OSIRISSIMInfo
      endif
    endfor
  endif else begin
    ;obj_destroy,self
  endelse
endif
obj_destroy,self
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function OSIRISSIMreduction::GetOSIRISSIMConstants,filename

if file_test(filename) eq 0 then begin
filefound=0
constants={filefound:filefound}
return,constants
endif else begin
filefound=1
constants={filefound:filefound}
endelse

line=''
Constants_str='Constants'
openr,lun,filename,/get_lun
while eof(lun) eq 0 do begin
readf,lun,line
Constants_str=[Constants_str,line]
endwhile
free_lun,lun,/force
Constants_str=Constants_str[1:*]
n=n_elements(Constants_str)
for i = 0,n-1 do begin
ConstantName=strtrim((strsplit(Constants_str[i],'=',/extract))[0],2)
ConstantValue=double(strtrim((strsplit(Constants_str[i],'=',/extract))[1],2))
constants=create_struct(constants,ConstantName,ConstantValue)
endfor
constants=create_struct(constants,name='OSIRISSIMConstants')
return,constants
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function OSIRISSIMreduction::getDaveFiles
return,self.daveFiles
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::cleanup
; First let's restore the colors
tvlct,*self.rPtr,*self.gPtr,*self.bPtr
device,decomposed = self.old_dc
;
; Now free up the pointers
ptr_free,self.odataPtr,self.oerrorPtr
ptr_free,self.oxvalsPtr,self.oyvalsPtr
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.vanFilePtr,self.bgFilePtr
ptr_free,self.tempPtr,self.treatmentPtr,self.lambda_fieldPtr,self.oTOFMonitorPtr
ptr_free,self.TOFMonitorPtr,self.Mon_cumPtr,self.headerPtr,self.instrumentPtr
ptr_free,self.titlePtr,self.gPtr,self.good_detPtr
ptr_free,self.ConstantsPtr,self.oTOFMonitorxvalsPtr,self.TOFMonitorxvalsPtr
ptr_free,self.TOFMonitorErrorPtr,self.oTOFMonitorErrorPtr
;
; Delete any pixmap windows
wdelete,self.winPix
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::quit,event = event
; Widget, destroy thyself
widget_control,self.tlb,/destroy
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::selSigFiles,event = event
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.txt'],$
                               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 OSIRISSIM 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-19),4)) eq 'OSIRISSIM' and $
  length eq 15 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 .txt attached
  extPos = strpos(filename,'.txt')
  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

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::selSigRuns,event = event
  widget_control, self.Signal_runs, get_value=strdets
;print,'strdets =',strdets
dets=opan_selectgroups_OSIRISSIM_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+'.txt')
files=strarr(nfiles)
for i = 0, nfiles-1 do begin
files(i)=file_search(self.datDir,files_short(i))
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 .txt attached
  extPos = strpos(filename,'.txt')
  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

return

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::selBgFiles,event = event
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.txt'],$
                               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 OSIRISSIM 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-19),4)) eq 'OSIRISSIM' and $
  length eq 15 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 OSIRISSIMreduction::selEmptyRuns,event = event
  widget_control, self.Background_runs, get_value=strdets
;print,'strdets =',strdets
dets=opan_selectgroups_OSIRISSIM_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+'.txt')
files=strarr(nfiles)
for i = 0, nfiles-1 do begin
files(i)=file_search(self.datDir,files_short(i))
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 OSIRISSIMreduction::selVanFile,event = event
files = dialog_pickfile(dialog_parent = event.top,/read, $
                               filter = ['*.txt'],$
                               title = 'Select vanadium data file',$
                               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,'The selected file 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 OSIRISSIM 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-19),4)) eq 'OSIRISSIM' and $
  length eq 15 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
return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::selVanRun,event = event
  widget_control, self.Vanadium_run, get_value=strdets

dets=opan_selectgroups_OSIRISSIM_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+'.txt')
files=strarr(nfiles)
for i = 0, nfiles-1 do begin
files(i)=file_search(self.datDir,files_short(i))
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
;
;

return

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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->Read_raw_OSIRISSIM,files[i],event = event,err = err
  if err eq 1 then return
  if i eq 0 then begin
    data = *self.dataPtr
    temperature = *self.tempPtr
    Mon_cum = *self.Mon_cumPtr
    TOFMonitor = *self.TOFMonitorPtr
  endif else begin
    data = data+*self.dataPtr
    temperature = [temperature,*self.tempPtr]
    Mon_cum = [Mon_cum,*self.Mon_cumPtr]
    TOFMonitor+= *self.TOFMonitorPtr
  endelse
endfor

*self.treatmentPtr = [*self.treatmentPtr,treat]
error = sqrt(data)
where_zero = where(data eq 0,count_zero)
if count_zero gt 0 then error[where_zero] = 1.0
*self.errorPtr = error
*self.dataPtr = data
*self.Mon_cumPtr = Mon_cum
*self.TOFMonitorPtr = TOFMonitor
*self.tempPtr = temperature

return

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function OSIRISSIMreduction::getnotifyIds
return,*self.notifyIdPtr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMReductionEvents,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 OSIRISSIMreduction::plotInelasticData,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.headerPtr)[2],2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Inelastic Data: Sum Over All Detectors'
endif else begin
    if DataOutput eq 0 then begin
    title=strtrim((*self.headerPtr)[2],2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Inelastic Data: Q = '+strtrim(string(y),2)
    endif else begin
    title=strtrim((*self.headerPtr)[2],2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Inelastic Data: Phi Group = '+strtrim(string(val),2)
    endelse
endelse


;
purged=where(z ne -1.0,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,color=1,background=12
errplot,xpurge,zpurge-zerrpurge,zpurge+zerrpurge,width = 0.0,color=1
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,color=1,background=12
errplot,x,z-zerr,z+zerr,width = 0.0,color=1
endelse
return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::plotMonitorData,event = event
widget_control,self.grpSlider,get_value = val
if (size(*self.dataPtr))[0] eq 1 then begin
InelasticChannels = 1
endif else begin
InelasticChannels=(size(*self.dataPtr))[2]
endelse

if val gt (InelasticChannels+1) then val = InelasticChannels+1
if val le InelasticChannels then return
val-=InelasticChannels
;


z = *self.TOFMonitorPtr
zerr = *self.TOFMonitorErrorPtr
x = *self.TOFMonitorxvalsPtr
title = strtrim((*self.headerPtr)[2],2)+', T = '+ $
       strtrim(string((*self.InstrumentPtr).temp),2)+' K, Spectrum of Upstream Monitor'

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


plot,x,z,psym = 4,xrange = self.xrange,yrange = self.yrange, $
     xstyle = 1,ystyle = 1,xtitle = self.MonitorsXlabel, ytitle = self.zlabel, title = title,color=6,background=12
errplot,x,z-zerr,z+zerr,width = 0.0,color=6
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::doNothing,event = event
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::Reduction_Information,event = event
msg=strarr(7)
msg[0]='In the Poor Man''s approach, the sample spectrum in the time domain is first divided'
msg[1]='by the monitor spectrum.  When converting from time to energy the intensity
msg[2]='is multiplied by a factor proportional to ''tprim^3'', where tprim'
msg[3]='is the time-of-flight in the primary instrument.  The prescription according'
msg[4]='to Bruno Dorner differs in that the intensity is not multipled by this factor.'
msg[5]='Dorner argues that this Jacobian is already incorportated into the operation of '
msg[6]='dividing the sample spectrum by that of the monitor.'
    void=dialog_message(dialog_parent=event.top,/information,msg)
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::Instrument_Characteristics,event = event
constants=*self.ConstantsPtr
lprim=constants.lprim
D=constants.D
dspace=constants.dspace
if n_elements(*self.InstrumentPtr) eq 0 then begin
msg=strarr(3)
msg[0]='Length of Primary Instrument: '+strtrim(string(lprim),2)
msg[1]='Length of Secondary Instrument: '+strtrim(string(D),2)
msg[2]='Analyser d-spacing: '+strtrim(string(dspace),2)
void=dialog_message(dialog_parent=event.top,/information,msg)
return
endif else begin
instrument_details = *self.InstrumentPtr
theta=instrument_details.AnalysersAngle
lambda=instrument_details.lambda
msg=strarr(5)
msg[0]='Length of Primary Instrument: '+strtrim(string(lprim),2)
msg[1]='Length of Secondary Instrument: '+strtrim(string(D),2)
msg[2]='Analyser d-spacing: '+strtrim(string(dspace),2)
msg[3]='Analyser scattering Angle: '+strtrim(string(theta),2)
msg[4]='Wavelength of Neutrons at Detector: '+strtrim(string(lambda),2)
void=dialog_message(dialog_parent=event.top,/information,msg)
return
endelse
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::ebinning,event = event
widget_control,self.DataOutputTypesGroup,get_value = DataOutputType
; DataOutputType 0 S(Q,w)
; DataOutputType 1 S(Q,w)_phi
; DataOutputType 2 S(theta,t)
;print,'DataOutputType: ',DataOutputType
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
;print,'x: ',x
;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)
minx=min(x, max = maxx)
nb_xlo=minx
nb_xhi=minx
b_xlo=minx
b_xhi=maxx
nb_nbins=0
b_nbins=total_bins
step=(b_xhi-b_xlo)/(b_nbins-1)
ix=x
;    print,'ix1: ',ix
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)
if count ge 1 then begin
ix=[ix[where_int[0]],ix[(where_int+1)]]
i_xlo=min(ix, max = i_xhi)
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_OSIRISSIM_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 = 'OSIRISSIMEbinParameters.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 = 'OSIRISSIMEbinParameters.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_OSIRISSIM_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
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 = 'OSIRISSIMEbinParameters.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+'OSIRISSIMEbinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
;help,message
msg=message
;help,msg
;msg = 'THE FILE "OSIRISSIMEbinParameters.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)
minx=min(x, max = maxx)
nb_xlo=minx
nb_xhi=minx
b_xlo=minx
b_xhi=maxx
nb_nbins=0
b_nbins=total_bins
step=(b_xhi-b_xlo)/(b_nbins-1)
ix=x
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[where_int[0]],ix[(where_int+1)]]
i_xlo=min(ix, max = i_xhi)
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_OSIRISSIM_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 = 'OSIRISSIMEbinParameters.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 = 'OSIRISSIMEbinParameters.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+'OSIRISSIMEbinParameters.txt HAS NOT BEEN FOUND.  REVERTING TO DEFAULT ')
msg=message
;help,msg
;msg = 'THE FILE "OSIRISSIMEbinParameters.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)
minx=min(x, max = maxx)
nb_xlo=minx
nb_xhi=minx
b_xlo=minx
b_xhi=maxx
nb_nbins=0
b_nbins=total_bins
step=(b_xhi-b_xlo)/(b_nbins-1)
ix=x
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[where_int[0]],ix[(where_int+1)]]
i_xlo=min(ix, max = i_xhi)
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_OSIRISSIM_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 = 'OSIRISSIMEbinParameters.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
;
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)
;       temp=x/nb_xhi
;        where_x_lt_nb_xhi=where(temp lt 0.999,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]
;       temp=xnb1/nb_xlo
;       xnb=x[where(temp ge 0.999)]
;       temp=x/nb_xlo
;       nodata_count=where(temp lt 0.999,count)
    ; numerical bug fix
       if fix(nb_xlo) eq fix(min(x)) then begin
       count = -1
       xnb=xnb1
       endif
         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
        xlo = b_xlo & xhi = i_xlo
       nbins = b_nbins-i_nbins
       x_out=x_out[where(x_out ge xlo)]
;       temp=x_out/xhi
;       x_out=x_out[where(temp le 1.001)]
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 has 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]

; 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_OSIRISSIM_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 = 'OSIRISSIMTbinParameters.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 = 'OSIRISSIMTbinParameters.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+'OSIRISSIMTbinParameters.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_OSIRISSIM_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 = 'OSIRISSIMTbinParameters.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 = 'OSIRISSIMTbinParameters.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+'OSIRISSIMTbinParameters.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_OSIRISSIM_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 = 'OSIRISSIMTbinParameters.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 has 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


  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



return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::qbinning,event = event
z = *self.dataPtr
dz = *self.errorPtr
x = *self.xvalsPtr
y = *self.yvalsPtr
instrument_details = *self.InstrumentPtr

;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

lambda0=instrument_details.lambda
;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 = 'OSIRISSIMQbinParameters.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 = 'OSIRISSIMQbinParameters.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+'OSIRISSIMQbinParameters.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 = 'OSIRISSIMQbinParameters.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 = 'OSIRISSIMQbinParameters.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+'OSIRISSIMQbinParameters.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 = 'OSIRISSIMQbinParameters.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
;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='OSIRISSIMPhiBinParameters.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 = OSIRISSIMDetGroupWidget(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 = OSIRISSIMDetGroupWidget(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+'OSIRISSIMPhiBinParameters.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 = OSIRISSIMDetGroupWidget(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+'OSIRISSIMPhiBinParameters.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 = OSIRISSIMDetGroupWidget(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 OSIRISSIMreduction::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
;print,'*self.vanFilePtr: ',*self.vanFilePtr
if n_elements(*self.vanFilePtr) eq 0 then return
instrument_details = *self.InstrumentPtr
lambda=instrument_details.lambda



; First pull out the current data values
sigData = *self.dataPtr
sigError = *self.errorPtr
sigX = *self.xvalsPtr
sigY = *self.yvalsPtr
sigTOFMonitor = *self.TOFMonitorPtr
sigMon_cum = *self.Mon_cumPtr
sigTemp = *self.tempPtr
signdet=self.ndet
header=*self.headerPtr

vanFile = *self.vanFilePtr

self->Sum_Vandium_Runs,event = event,err = err
vdata = *self.dataPtr
vtemperature = *self.tempPtr
vtemperature = vtemperature[0]
if vtemperature eq 0 then vtemperature = 298.0
;help,vtemperature
;print,'vtemperature =',vtemperature
InelasticAngles=*self.yvalsPtr
;print,'*self.xvalsPtr =',*self.xvalsPtr
;
;Apply the same detector filtering as before
;
;
good_det=*self.good_detPtr
vData=vData[*,good_det]
InelasticAngles=InelasticAngles[good_det]

*self.dataPtr = vData
vError = sqrt(vData)
*self.errorPtr = vError
*self.yvalsPtr = InelasticAngles
;
;
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
;convert to energy unless the desired quantity is S(theta,t)
if DataOutput ne 2 then begin
self->convert_to_energy,event = event
endif else begin
self->Time_Bin_Grouping,event = event
endelse
vanData = *self.dataPtr
vanx = *self.xvalsPtr

for i = 0,n_elements(InelasticAngles)-1 do begin
   ; Get a good estimate of the starting parameters for the fits
 y = reform(vanData[*,i])
 x=vanX
 width=max(x)-min(x)
 zeropos=(vanx[where(y eq max(y))])[0]
 coeff=[max(y),zeropos,(width/2.0),0]
  ; Fit
  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.TOFMonitorPtr = sigTOFMonitor
*self.Mon_cumPtr = sigMon_cum
*self.tempPtr = sigTemp
self.ndet=signdet
*self.headerPtr = header
*self.InstrumentPtr = instrument_details


treat = 'Unable to normalise to vanadium file: '+strtrim(string(vanFile),2)
*self.treatmentPtr = [*self.treatmentPtr,treat]
return
endif
stats = moment(area[0:n_elements(InelasticAngles)-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))
q = (4.0*!pi/lambda)*sin(0.5*!dtor*InelasticAngles)
;the next line creates n_elements(sigX) columns of exp(0.066*sigY^2) data
;dwf = ux#(exp(-0.0067^(vtemperature/300.0)*q^2))  ; Debye-Waller factor for vanadium
;dwf = ux#(exp(-0.0067*vtemperature/300.0*q^2))  ; Debye-Waller factor for vanadium
dwf = exp(-0.0067*vtemperature/300.0*q^2)  ; Debye-Waller factor for vanadium
area*=dwf

a = ux#(area/stats[0])

;sigData = sigData*dwf/a
;sigError = sigError*dwf/a
sigData/= a
sigError/= a


*self.dataPtr = sigData
*self.errorPtr = sigError
*self.xvalsPtr = sigX
*self.yvalsPtr = sigY
*self.TOFMonitorPtr = sigTOFMonitor
*self.Mon_cumPtr = sigMon_cum
*self.tempPtr = sigTemp
self.ndet=signdet
*self.headerPtr = header
*self.InstrumentPtr = instrument_details

;print,'v ndet =',self.ndet
treat = 'Normalised to vanadium file: '+strtrim(string(vanFile),2)
*self.treatmentPtr = [*self.treatmentPtr,treat]

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::InvalidFile,msg,event = event
void = dialog_message(dialog_parent = event.top, $
'Invalid File Format. Error Message: '+msg)
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::Read_raw_OSIRISSIM,filename,event = event,err = err
   CATCH, Error_status
if Error_status ne 0 then begin
catch, /cancel
msg=!ERROR_STATE.MSG
self->InvalidFile,msg,event = event
err=1
return
endif
;
err = 0
if n_elements(filename) eq 0 then begin
err=1
return
endif
field=''
line=''
ans=''
;print,'filename=',filename
openr,lun,filename,/get_lun
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
if field ne 'Leftmann' then begin
msg = 'Missing Keyword ''Leftmann'''
self->InvalidFile,msg,event = event
err=1
return
endif
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
ans=strtrim(strsplit(field,'=',/extract),2)
if strlowcase(ans[0]) ne 'sample' then begin
msg = 'Sample input expected on second line'
self->InvalidFile,msg,event = event
err=1
return
endif
SampleName=strtrim(ans[1],2)
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
ans=strtrim(strsplit(field,'=',/extract),2)
if strlowcase(ans[0]) ne 'temperature' then begin
msg = 'Temperature input expected on third line'
self->InvalidFile,msg,event = event
err=1
return
endif
Temperature=float(ans[1])
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
ans=strtrim(strsplit(field,'=',/extract),2)
if strlowcase(ans[0]) ne 'monitortimechannels' then begin
msg = 'Missing keyword ''monitortimechannels'' on fourth line'
self->InvalidFile,msg,event = event
err=1
return
endif
monitortimechannels=long(ans[1])
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
ans=strtrim(strsplit(field,'=',/extract),2)
if strlowcase(ans[0]) ne 'detectortimechannels' then begin
msg = 'Missing keyword ''detectortimechannels'' on fith line'
self->InvalidFile,msg,event = event
err=1
return
endif
detectortimechannels=long(ans[1])
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
ans=strtrim(strsplit(field,'=',/extract),2)
if strlowcase(ans[0]) ne 'detectors' then begin
msg = 'Missing keyword ''detectors'' on fith line'
self->InvalidFile,msg,event = event
err=1
return
endif
ndet=long(ans[1])
;
if ndet lt 2 then begin
msg = 'File must contain data from at least two detectors'
self->InvalidFile,msg,event = event
err=1
return
endif
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
ans=strtrim(strsplit(field,'=',/extract),2)
if strlowcase(ans[0]) ne 'analyserscatteringangle' then begin
msg = 'Missing keyword ''analyserscatteringangle'' on sixth line'
self->InvalidFile,msg,event = event
err=1
return
endif
AnalysersAngle=float(ans[1])
;
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
field=strtrim(field,2)
if strlowcase(field) ne 'monitor' then begin
msg = 'Missing keyword ''monitor'' on seventh line'
self->InvalidFile,msg,event = event
err=1
return
endif
;
MonitorTOF=fltarr(monitortimechannels)
DataMonitor=fltarr(monitortimechannels)
DataMonitorError=fltarr(monitortimechannels)
for i=0,monitortimechannels-1 do begin
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
MonitorTOF[i]=ans[0]
DataMonitor[i]=ans[1]
DataMonitorError[i]=ans[2]
;print,'line=',line
;readf,lun,MonitorTOF[i],DataMonitor[i],DataMonitorError[i]
;print,i,MonitorTOF[i],DataMonitor[i],DataMonitorError[i]
endfor
;
DataInelasticTOF=fltarr(detectortimechannels)
DataInelastic=fltarr(detectortimechannels,ndet)
DataInelasticError=fltarr(detectortimechannels,ndet)
FOR j=0,ndet-1 DO BEGIN
    readf,lun,line
;    print,'line=',line
    ans=strtrim(strsplit(line,/extract),2)
    field=ans[1]
    ans=strtrim((strsplit(field,'=',/extract))[1],2)
    ;rint,'ans=',ans
    if j eq 0 then begin
    DetectorNames=ans
    endif else begin
    DetectorNames=[DetectorNames,ans]
    endelse
    readf,lun,line
    ans=strtrim(strsplit(line,/extract),2)
    field=ans[1]
    ans=strtrim((strsplit(field,'=',/extract))[1],2)
    ;print,'ans=',ans
    if j eq 0 then begin
    InelasticAngles=float(ans)
    endif else begin
    InelasticAngles=[InelasticAngles,float(ans)]
    endelse
       for i=0,detectortimechannels-1 do begin
    readf,lun,line
    ans=strtrim(strsplit(line,/extract),2)
    DataInelasticTOF[i]=ans[0]
    DataInelastic[i,j]=ans[1]
    DataInelasticError[i,j]=ans[2]
;    readf,lun,DataInelasticTOF[i],DataInelastic[i,j],DataInelasticError[i,j]
       endfor
ENDFOR
readf,lun,line
ans=strtrim(strsplit(line,/extract),2)
field=ans[1]
if strlowcase(field) ne 'end' then begin
msg = 'Missing keyword ''end'' at end of file'
self->InvalidFile,msg,event = event
err=1
return
endif


free_lun,lun,/force


constants=*self.ConstantsPtr
TimeOffset=constants.TimeOffset

;err=1

;return


;;convert to point data
;tof+=(tof[1]-tof[0])/2.0
;help,DataInelastic
;help,DataInelasticError
;help,DataInelasticTOF
;help,InelasticAngles
;print,DataInelastic[99,*]
;
*self.odataPtr = DataInelastic
*self.oerrorPtr = DataInelasticError
*self.oxvalsPtr= DataInelasticTOF+TimeOffset
*self.oyvalsPtr = InelasticAngles


;
*self.dataPtr = DataInelastic
*self.errorPtr = DataInelasticError
*self.xvalsPtr = DataInelasticTOF+TimeOffset
*self.yvalsPtr = InelasticAngles
;
*self.Mon_cumPtr=long64(total(DataMonitor))
*self.TOFMonitorPtr=DataMonitor
*self.oTOFMonitorPtr=DataMonitor
*self.TOFMonitorxvalsPtr=MonitorTOF+TimeOffset
*self.oTOFMonitorxvalsPtr=MonitorTOF+TimeOffset
*self.TOFMonitorErrorPtr=DataMonitorError
*self.oTOFMonitorErrorPtr=DataMonitorError


*self.tempPtr=Temperature

self.ylabel = 'Group'
self.zlabel = 'Intensity'
self.ndet = n_elements(InelasticAngles)


;print,'unix_start_time: ',unix_start_time
;print,'systime(1,unix_start_time): ',systime(0,unix_start_time)


;   create structure with instrumental details needed for the data reduction
instrument_details={temp:Temperature, $
              AnalysersAngle:AnalysersAngle}
;
;print,instrument_details.temp

*self.InstrumentPtr=instrument_details
;
;
;   All the information not required for the data reduction are stored in the header

header = strarr(3)

header[0]='Instrument: OSIRIS SIMIMULATION'
header[1]='Sample name: '+strtrim(string(SampleName),2)
header[2]='Simulation of OSIRIS Data'
*self.headerPtr = header

;err=1
;return
;
;
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::subtract_bad_detectors,event = event,err = err
;extract data
ndet=self.ndet
if ndet eq 1 then return
data=*self.dataPtr
for i=0,ndet-1 do begin
height=max(data[*,i])-min(data[*,i])
if i eq 0 then begin
heightdet=height
endif else begin
heightdet=[heightdet,height]
endelse
endfor
avheight=(moment(heightdet))[0]
;print,'avheight =',avheight
;
;Keep only those detectors with intensity greater than 1% of the average
;First identify those detectors
for i=0,ndet-1 do begin
;print,'heightdet[i] =',heightdet[i]
    if heightdet[i] gt (0.01*avheight) then begin
       if n_elements(good_det) eq 0 then begin
       good_det=i
       endif else begin
       good_det=[good_det,i]
       endelse
    endif
endfor
;return
*self.good_detPtr=good_det

IF n_elements(good_det) NE ndet THEN BEGIN

*self.dataPtr=(*self.dataPtr)[*,good_det]
*self.errorPtr=sqrt(*self.dataPtr)
*self.yvalsPtr=(*self.yvalsPtr)[good_det]
self.ndet=n_elements(*self.yvalsPtr)
for i = 0,ndet-1 do begin
wheregood=where(i eq good_det)
    if wheregood eq -1 then begin
       if n_elements(BadDetectorsPtr) eq 0 then begin
              BadDetectorsPtr=ptr_new(i)
       endif else begin
       *BadDetectorsPtr=[*BadDetectorsPtr,i]
       endelse
    endif
endfor

InelasticDetectors=strarr(ndet)
for i = 0, ndet-1 do begin
InelasticDetectors[i]=strtrim(string(i),2)
endfor

;print,'n_elements(*BadDetectorsPtr):',n_elements(*BadDetectorsPtr)
;print,'*BadDetectorsPtr:',*BadDetectorsPtr

for i = 0, n_elements(*BadDetectorsPtr)-1 do begin
    if i eq 0 then begin
    BadDetectorString=InelasticDetectors[(*BadDetectorsPtr)[i]]
    endif else begin
    BadDetectorString=BadDetectorString+', '+InelasticDetectors[(*BadDetectorsPtr)[i]]
    endelse
endfor
ptr_free,BadDetectorsPtr

treat=strarr(2)
treat[0] = 'Due to insufficient counts, the data from the inelastic detectors '
treat[1] = BadDetectorString+' were not processed in the data reduction.'

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

ENDIF
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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->Read_raw_OSIRISSIM,files[i],event = event,err = err
  if err eq 1 then return
  if i eq 0 then begin
    data = *self.dataPtr
    temperature = *self.tempPtr
    Mon_cum = *self.Mon_cumPtr
    TOFMonitor = *self.TOFMonitorPtr
  endif else begin
    data = data+*self.dataPtr
    temperature = [temperature,*self.tempPtr]
    Mon_cum = [Mon_cum,*self.Mon_cumPtr]
    TOFMonitor+= *self.TOFMonitorPtr
  endelse
endfor

*self.treatmentPtr = [*self.treatmentPtr,treat]
error = sqrt(data)
where_zero = where(data eq 0,count_zero)
if count_zero gt 0 then error[where_zero] = 1.0
*self.errorPtr = error
*self.dataPtr = data
*self.Mon_cumPtr = Mon_cum
*self.TOFMonitorPtr = TOFMonitor
*self.tempPtr = temperature

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::subtract_background,event = event
;
; 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.
;
if n_elements(*self.dataPtr) eq 0 then return
;
if n_elements(*self.bgFilePtr) eq 0 then return
nbgFiles = n_elements(*self.bgFilePtr)
bgFiles = *self.bgFilePtr

; 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
sigTOFMonitor = *self.TOFMonitor3tr
signdet=self.ndet
header=*self.headerPtr
instrument_details = *self.InstrumentPtr
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->Read_raw_OSIRISSIM,bgfiles[i],event = event
  if i eq 0 then begin
    bgdata = *self.dataPtr
;    help,bgdata
    bgtemperature = *self.tempPtr
    bgMon_cum = *self.Mon_cumPtr
    bgTOFMonitor = *self.TOFMonitorPtr
  endif else begin
    bgdata = bgdata+*self.dataPtr
    bgtemperature = [bgtemperature,*self.tempPtr]
    bgMon_cum = [bgMon_cum,*self.Mon_cumPtr]
    ;bgTOFMonitor = [bgTOFMonitor,*self.TOFMonitorPtr]
    bgTOFMonitor += *self.TOFMonitorPtr

  endelse
endfor



InelasticAngles=*self.yvalsPtr
good_det=*self.good_detPtr
bgData=bgData[*,good_det]
InelasticAngles=InelasticAngles[good_det]
*self.treatmentPtr = [*self.treatmentPtr,treat]
*self.dataPtr = bgData
bgError = sqrt(bgData)
*self.errorPtr = bgError
*self.yvalsPtr = InelasticAngles
*self.tempPtr = bgtemperature
*self.Mon_cumPtr = bgMon_cum
*self.TOFMonitorPtr = bgTOFMonitor
; Convert the background files to energy
widget_control,self.DataOutputTypesGroup,get_value = DataOutput
;convert to energy unless the desired quqntity is S(theta,t)
widget_control,self.BackgroundSubtractionField,get_value = ScaleFactor
ScaleFactor=float(ScaleFactor[0])

if DataOutput ne 2 then begin
self->convert_to_energy,event = event
endif else begin
self->Time_Bin_Grouping,event = event
endelse
bgx = *self.xvalsPtr
bgData = *self.dataPtr
bgError = *self.errorPtr
sigMon = total(sigMon_cum)
bgMon = total(bgMon_cum)
sf = (ScaleFactor*sigMon/bgMon)
newData = sigData
newError = sigError

;help, newdata
;help,bgdata
; Cast the scale factor into an appropriate form
datSize = size(sigData)
nchan = datSize[1]
ndet = datSize[2]

sfm = (1+bytarr(nchan))#(1+fltarr(ndet))
newData[*,0:(ndet-1)] = 1.0*sigData[*,0:(ndet-1)] - $
                           sf*((bgData[*,0:(ndet-1)])*sfm)
newError[*,0:(ndet-1)] = sqrt(sigError[*,0:(ndet-1)]^2+ $
                                 (sf*(bgError[*,0:(ndet-1)])*sfm)^2)
*self.xvalsPtr = sigx
*self.dataPtr = newData
*self.errorPtr = newError
*self.tempPtr = [sigTemp];[sigTemp,bgtemperature]
*self.Mon_cumPtr = [sigMon_cum,bgMon_cum]
*self.TOFMonitorPtr = sigTOFMonitor
self.ndet=signdet
*self.headerPtr = header
*self.InstrumentPtr = instrument_details
return

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function OSIRISSIMreduction::Bragg,dspace,theta
return, 2.0*dspace*sin(theta*!DTOR)
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::convert_to_energy,event = event
;
;
; Get the data
sigData = *self.dataPtr
sigError = *self.errorPtr
sigx = *self.xvalsPtr
DataMonitor=*self.TOFMonitorPtr
DataMonitorError=*self.TOFMonitorErrorPtr
MonitorTOF=*self.TOFMonitorxvalsPtr
instrument_details = *self.InstrumentPtr
constants=*self.ConstantsPtr
conv=constants.meVtoJoules
D=constants.D
h=constants.h
dspace=constants.dspace
mn=constants.mn
lprim=constants.lprim
;
;calculated wavelength
theta=instrument_details.AnalysersAngle
lambda_analyser=self->Bragg(dspace,theta)
E_analyser=81.80321/(lambda_analyser)^2
v_analyser=sqrt(E_analyser*conv*2.0/mn)
t_analyser=1e6*D/v_analyser
tprim=sigx-t_analyser
vprim=lprim/(tprim/1.0e6)
Eprim_joules=0.5*mn*vprim^2
Eprim_meV=Eprim_joules/conv
Etrans_meV=Eprim_meV-E_analyser
LambdaPrim=(h*1e10)/(mn*vprim)
;print,'E_analyser: ',E_analyser
;TOF Monitor
lTOFMon=constants.lTOFMon
v=lTOFMon/(MonitorTOF/1.0e6)
LambdaMon=(h*1e10)/(mn*v)
ETOFMon_joules=0.5*mn*v^2
ETOFMon_meV=ETOFMon_joules/conv
;
;extract dimension of time channels
channels_mon=n_elements(LambdaMon)
channels_analyser=n_elements(LambdaPrim)
index_map=intarr(2,channels_analyser)
index_map[0,*]=indgen(channels_analyser)
uanalyser=1+bytarr(channels_analyser)
umon=1+bytarr(channels_mon)
diff=abs(LambdaPrim#umon-uanalyser#LambdaMon)
for i=0,channels_analyser-1 do begin
void=min(diff[i,*],ind)
index_map[1,i]=ind
endfor
for i=0,channels_analyser-1 do begin

	if   DataMonitor[index_map[1,i]] ge 100.0 then begin

      sigError[i,*]=(sigData[i,*]/DataMonitor[index_map[1,i]])*sqrt((sigError[i,*]/sigData[i,*])^2 + $
             (DataMonitorError[index_map[1,i]]/DataMonitor[index_map[1,i]])^2)  ; error treatment according to Vladamir

;     sigError[i,*]=(sigError[i,*]/DataMonitor[index_map[1,i]])
      sigData[i,*]/=DataMonitor[index_map[1,i]] ; Correction according to Dorner

	endif else begin
	sigError[i,*]=0.0
	sigData[i,*]=0.0
	endelse


endfor
nx=n_elements(Etrans_meV)


;jacobian for transformation of time to energy
n_MonitorTOF=n_elements(MonitorTOF)
norm=(total(MonitorTOF^3))/n_MonitorTOF
for i = 0, n_MonitorTOF-1 do begin
DataMonitor[i,*]=DataMonitor[i,*]*(MonitorTOF[i]^3)/norm
DataMonitorError[i,*]=DataMonitorError[i,*]*(MonitorTOF[i]^3)/norm
endfor

widget_control,self.Misc_Group2,get_value = ReductionMethod
if ReductionMethod[0] eq 1 then begin
;according to Felix, the intensity should also be multiplied by ti^3 (tprim^3)
norm=(total(tprim^3))/nx
for i = 0, nx-1 do begin
sigData[i,*]=sigData[i,*]*(tprim[i]^3)/norm
sigError[i,*]=sigError[i,*]*(tprim[i]^3)/norm
endfor
endif



;   Is Detailed balance requested:
widget_control,self.Misc_Group1,get_value = val
if val[0] eq 1 then begin
c=2.0*instrument_details.temp[0]*0.08617385692
for i = 0, nx-1 do begin

;if i eq 0 then print,'exp(-Etrans_meV[0]/c): ',exp(-Etrans_meV[0]/c)
;if i eq nx-1 then print,'exp(-Etrans_meV[nx-1]/c): ',exp(-Etrans_meV[nx-1]/c)
;print,'c: ',c
;
sigdata[i,*]*=exp(-Etrans_meV[i]/c)
sigerror[i,*]*=exp(-Etrans_meV[i]/c)
endfor
treat = ['Detailed Balance Correction Has Been Applied to the Data.']
*self.treatmentPtr = [*self.treatmentPtr,treat]
endif
;


*self.dataPtr = reverse(sigData)
*self.errorPtr = reverse(sigError)
*self.xvalsPtr = reverse(Etrans_meV)
*self.TOFMonitorPtr=reverse(DataMonitor)
*self.TOFMonitorErrorPtr=reverse(DataMonitorError)
*self.TOFMonitorxvalsPtr=reverse(ETOFMon_meV)

;
self.MonitorsXlabel='Energy / meV'
instrument_details = create_struct(instrument_details,'lambda',lambda_analyser)
 *self.InstrumentPtr = instrument_details
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::Time_Bin_Grouping,event = event
sigx = *self.xvalsPtr
instrument_details = *self.InstrumentPtr
constants=*self.ConstantsPtr
dspace=constants.dspace

theta=instrument_details.AnalysersAngle
lambda_analyser=self->Bragg(dspace,theta)
instrument_details = create_struct(instrument_details,'lambda',lambda_analyser)
 *self.InstrumentPtr = instrument_details
self.MonitorsXlabel='Time / microseconds'

return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::display,event = event
; This method plots the data (if present) to a pixmap then to the screen.
wset,self.winPix
self->plotInelasticData,event = event
self->plotMonitorData,event = event
wset,self.winVis
device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.winPix]
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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 OSIRISSIMreduction::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]
;
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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 OSIRISSIMreduction::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 OSIRISSIMreduction::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 .txt attached
  extPos = strpos(filename,'.txt')
  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 OSIRISSIMreduction::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

return
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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'
widget_control, self.stem3, set_value=text
;
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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)
void = widget_text(tlb,value = msg,xsize = strlen(msg),/editable)
widget_control,tlb,/realize
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::flashMessage_destroy,tlb
widget_control,tlb,/destroy
return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::reduce,event = event, freebies = freebies
;
   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 return
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

; 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
;
;
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 thisValue[0] eq 0 then begin   ; treat individually
  nfiles = n_elements(files)
  for i = 0,nfiles-1 do begin



   *self.treatmentPtr = 'Data reduction/treatment details:'
   msg = 'Reading in a raw OSIRISSIM file'
   self->flashMessage_create,msg,tlb
   self->Read_raw_OSIRISSIM,files[i],event = event,err = err ; always
   self->flashMessage_destroy,tlb
   if err eq 1 then return
;
;
   msg = 'Subtracting Bad Detectors'
   self->flashMessage_create,msg,tlb
   self->subtract_bad_detectors,event = event    ; always
   self->flashMessage_destroy,tlb
;
;
;
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
   msg = 'Grouping the Time Bins'
   self->flashMessage_create,msg,tlb
   self->Time_Bin_Grouping,event = event
   self->flashMessage_destroy,tlb
endelse

  ;if n_elements(*self.bgFilePtr) ne 0 then begin  ; subtract background
  if (treatVal[1] eq 1)  then begin  ; subtract background
   msg = 'Subtracting Background File(s)'
   self->flashMessage_create,msg,tlb
   self->subtract_background,event = event
   self->flashMessage_destroy,tlb
  endif

;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 = 'Qbinning/Detector Grouping'
   self->flashMessage_create,msg,tlb
   self->qbinning,event=event
   self->flashMessage_destroy,tlb


    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 .txt attached
  extPos = strpos(filename,'.txt')
  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 .txt attached
  extPos = strpos(filename,'.txt')
  filename = strmid(filename,0,extPos)
  ;extPos = strpos(files[0],'.OSIRISSIM')
  ;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 .txt attached
  extPos = strpos(filename,'.txt')
  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 n_elements(freebies) eq 1 then begin
   widget_control, self.freebiestem2, get_value=stem_add
fileout+='_'+wr+stem_add
endif

IF fileOut NE '' THEN BEGIN

    ;print,fileout
FilePar=fileout+'.par'
;
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
;
ENDIF
   treat = 'Filename: '+strtrim(files[i],2)
   *self.treatmentPtr = [*self.treatmentPtr,treat]

   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.treatmentPtr = 'Data reduction/treatment details:'

if n_elements(freebies) eq 0 then begin ; these first two options are skipped if freebies are requested

   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
;


   msg = 'Subtracting Bad Detectors'
   self->flashMessage_create,msg,tlb
   self->subtract_bad_detectors,event = event    ; always
   self->flashMessage_destroy,tlb


endif;
;
;
;
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
   msg = 'Grouping the Time Bins'
   self->flashMessage_create,msg,tlb
   self->Time_Bin_Grouping,event = event
   self->flashMessage_destroy,tlb
endelse


; Ok, we've performed all of the essential reduction treatment.  Now
; let's do any further steps that the user wishes.
 ; if n_elements(*self.bgFilePtr) ne 0 then begin  ; subtract background
  if (treatVal[1] eq 1)  then begin  ; subtract background
   msg = 'Subtracting Background File(s)'
   self->flashMessage_create,msg,tlb
   self->subtract_background,event = event
   self->flashMessage_destroy,tlb
  endif

;
  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 = 'Qbinning/Detector Grouping'
   self->flashMessage_create,msg,tlb
   self->qbinning,event=event
   self->flashMessage_destroy,tlb



   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 .txt attached
  extPos = strpos(filename,'.txt')
  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 .txt attached
  extPos = strpos(filename,'.txt')
  filename = strmid(filename,0,extPos)
  ;extPos = strpos(files[0],'.OSIRISSIM')
  ;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 .txt attached
  extPos = strpos(filename,'.txt')
  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 n_elements(freebies) eq 1 then begin
   widget_control, self.freebiestem2, get_value=stem_add
fileout+='_'+wr+stem_add
endif

IF fileOut NE '' THEN BEGIN

;
FilePar=fileout+'.par'

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

ENDIF
    ;print,fileout
;

    endelse

self->display,event = event
return
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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
header=*self.headerPtr
Instrument_Details=*self.InstrumentPtr


nh = n_elements(*self.headerPtr)
detSize = (size(data))[2]
temperature=*self.tempPtr
;
specific = {header:header, $
            sumTOFMonitor:*self.TOFMonitorPtr,$
            sumTOFMonitor2:*self.Mon_cumPtr,$
            nchan:nchan,$
            ndet:ndet,$
            phi:*self.yvalsPtr,$
            wavelength:(*self.InstrumentPtr).lambda,$
            date:systime(),$
            temp_sample:temperature $
            }


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 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] ne 2 then begin
yunits = 'wavevector:A-1'
ylabel = 'Q '
endif else begin
yunits = 'Phi:degrees'
ylabel = 'Phi '
endelse
;if DataOutput[0] eq 1  then begin
;yunits = 'Phi:degrees'
;ylabel = 'Phi '
;endif

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

Mon_cumTreat = 'Total incident beam monitor counts: '+ $
           strtrim(string(*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]

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 = 'OSIRISSIM',      $
     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
n_header=n_elements(*self.headerPtr)
n_treatment=n_elements(*self.treatmentPtr)
openw,lun,FilePar,/get_lun
for i = 0,n_header-1 do printf,lun,(*self.headerPtr)[i]
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, 'Wavelength / A: '+strtrim(string((*self.InstrumentPtr).lambda),2)
printf,lun, 'Date This File Created: '+strtrim(string(systime()),2)
for i = 0,n_treatment-1 do printf,lun,(*self.treatmentPtr)[i]
free_lun,lun,/force

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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

xlabel='Energy'
if self.units eq 4 then xlabel = 'T'
if self.units eq 5 then xlabel = 't'

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(*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]

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 gt -1.0,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,'+'"'+'Intensity'+'"'+', '+strtrim(string(yval),2)
endfor

free_lun,lun,/force


n_header=n_elements(*self.headerPtr)
n_treatment=n_elements(*self.treatmentPtr)
openw,lun,FilePar,/get_lun
for i = 0,n_header-1 do printf,lun,(*self.headerPtr)[i]
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, 'Wavelength / A: '+strtrim(string((*self.InstrumentPtr).lambda),2)
printf,lun, 'Date This File Created: '+strtrim(string(systime()),2)
for i = 0,n_treatment-1 do printf,lun,(*self.treatmentPtr)[i]
free_lun,lun,/force


end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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


;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'
for i = 0,n_elements(header)-1 do printf,lun,'#'+header[i]
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, 'Wavelength / A: '+strtrim(string((*self.InstrumentPtr).lambda),2)
printf,lun, 'Date This File Created: '+strtrim(string(systime()),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,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
;
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::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,color=4
        empty
     endif
   end
else:
endcase
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::Disclaimer,event = event
msg=strarr(5)
msg[0]='This program was written by Philip Tregenna-Piggott'
msg[1]='for the use of Kim Leftmann and his group, who wish to reduce
msg[2]='simulation data calculated for the OSIRIS instrument at ISIS.'
msg[3]='The program is not intended for the reduction of experimental data'
msg[4]='and has not be approved by the instrument scientists at the ISIS Facility.'
    void=dialog_message(dialog_parent=event.top,/information,msg)
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction::createwidgets
; Widget definition method
if n_elements(*self.pgroup_leader) eq 0 then begin
  tlb = widget_base(/row, $
        title = 'OSIRISSIM Data Reduction',mbar = bar,/tlb_size_events)
endif else begin
  tlb = widget_base(group_leader = *self.pgroup_leader,/row, $
        title = 'OSIRISSIM Data Reduction',mbar = bar,/tlb_size_events)
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 = 2,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 = 1,/scroll)
void = widget_button(lubase_col,value = 'Disclaimer', $
               uvalue = {object:self,method:'Disclaimer'})
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')
Misc_master = widget_base(Opt_Tab,/col,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 for Primary Data')
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']
FormatTypesGroup = cw_bgroup(Output_name_Ubase,FormatTypes,/col,/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,/col,/exclusive,label_top='Data Output', $
           set_value = 0,/return_index,/frame, $
           uvalue = {object:self,method:'doNothing'})
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



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

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


PhiBin_Types = ['Sum All','Grouping']
QBin_group = cw_bgroup(Q_Theta_base,PhiBin_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)

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


misc_submaster=widget_base(Misc_master,/row)
misc_left=widget_base(misc_submaster,/col)


Misc_Types1 = ['Detailed Balance']
Misc_Group1 = cw_bgroup(misc_left,Misc_Types1,/nonexclusive, $
           /no_release,/return_index,$
           uvalue = {object:self,method:'doNothing'})
self.Misc_Group1 = Misc_Group1

misc_left_A=widget_base(misc_left,/col,/frame)

void=widget_label(misc_left_A,value = 'Backround Subtraction Intensity Factor')

self.BackgroundSubtractionField = cw_field(misc_left_A,title='*',$
          uvalue = {object:self,method:'doNothing'},/row,value = '1.0')

misc_left_ReductionMethod=widget_base(misc_left,/col,/frame)

void = widget_label(misc_left_ReductionMethod,value = 'Reduction Method')


Misc_Types2 = ['á la Bruno Dorner','Poor Man''s Approach']
Misc_Group2 = cw_bgroup(misc_left_ReductionMethod,Misc_Types2,/exclusive,set_value=0, $
           /no_release,/return_index,$
           uvalue = {object:self,method:'doNothing'})
self.Misc_Group2 = Misc_Group2

void = widget_button(misc_left_ReductionMethod,value = 'Further Information', $
               uvalue = {object:self,method:'Reduction_Information'})

void = widget_button(misc_left,value = 'Instrument Parameters', $
               uvalue = {object:self,method:'Instrument_Characteristics'})

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 = 24, $
          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,'OSIRISSIMreduction::createwidgets',self.tlb, $
         event_handler = 'OSIRISSIMReductionEvents',$
         cleanup = 'OSIRISSIMReductionCleanup', /no_block
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function OSIRISSIMreduction::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
device, get_decomposed = old_dc
self.old_dc = old_dc
device,decomposed = 0

;loadCT,0 ,/silent
loadCT,5,NColors=12,Bottom=1 ,/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)
delim=path_sep()


filename=!DAVE_AUXILIARY_DIR+'ISIS'+delim+'OSIRISSIM'+delim+'OSIRISSIMConstants.txt'
constants=self->GetOSIRISSIMConstants(filename)


if constants.filefound eq 0 then begin
        void=dialog_message(dialog_parent=group_leader,/error, $
    'The file '+filename+' has not been found.  The program must exit.')
return,0
endif
;help,constants,/struc
self.ConstantsPtr = ptr_new(constants)


;
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.xvalsPtr = ptr_new(/allocate_heap)
self.yvalsPtr = ptr_new(/allocate_heap)
self.odataPtr = ptr_new(/allocate_heap)
self.oerrorPtr = ptr_new(/allocate_heap)
self.oxvalsPtr = ptr_new(/allocate_heap)
self.oyvalsPtr = ptr_new(/allocate_heap)
self.sigFilePtr = ptr_new(/allocate_heap)
self.bgFilePtr = ptr_new(/allocate_heap)
self.vanFilePtr = ptr_new(/allocate_heap)
self.TOFMonitorPtr = ptr_new(/allocate_heap)
self.oTOFMonitorPtr = ptr_new(/allocate_heap)
self.TOFMonitorErrorPtr = ptr_new(/allocate_heap)
self.oTOFMonitorErrorPtr = ptr_new(/allocate_heap)
self.Mon_cumPtr = ptr_new(/allocate_heap)
self.tempPtr = ptr_new(/allocate_heap)
self.InstrumentPtr = ptr_new(/allocate_heap)
self.treatmentPtr = ptr_new(/allocate_heap)
self.headerPtr = ptr_new(/allocate_heap)
self.daveFiles = ptr_new(/allocate_heap)
self.good_detPtr = ptr_new(/allocate_heap)
self.selDetPtr = ptr_new(/allocate_heap)
self.TOFMonitorxvalsPtr = ptr_new(/allocate_heap)
self.oTOFMonitorxvalsPtr = ptr_new(/allocate_heap)



*self.daveFiles = ''


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


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

;self.vanFilePtr = 'Automatic'



return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro OSIRISSIMreduction__define
define = {OSIRISSIMreduction,      $

          tlb:0L,          $
          ctrlBase:0L,        $
          grpSlider:0L,       $
          runGroup:0L,        $
          Bad_DetectorGroup:0L,  $
          treatGroup:0L,      $
          FormatTypesGroup:0L,      $
          DataOutputTypesGroup:0L,      $
          van_Base: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,       $
;          Signal_Runs:0L,   $
;          Background_Runs:0L,   $
;          Vanadium_Run:0L,   $
          old_dc:0L,   $
          BackgroundSubtractionField:0L,   $


         ;Misc related
          Misc_Group1:0L,       $
          Misc_Group2: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:'',       $
          MonitorsXlabel:'',       $
          ylabel:'',       $
          zlabel:'',       $
          titlePtr:ptr_new(),    $
          daveFiles:ptr_new(),     $



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

          ; Monitor Variables
          TOFMonitorPtr:ptr_new(),      $
          TOFMonitorErrorPtr:ptr_new(),      $
          oTOFMonitorPtr:ptr_new(),      $
          oTOFMonitorErrorPtr:ptr_new(),      $
          Mon_cumPtr:ptr_new(),      $

           ; Raw data file variables
          headerPtr:ptr_new(),     $
          tempPtr:ptr_new(),   $
          instrumentPtr:ptr_new(),   $
          ConstantsPtr:ptr_new(),   $
          ndet:0,          $
          curFile:'',         $


          ; Original inelastic data set
          odataPtr:ptr_new(),    $
          oerrorPtr:ptr_new(),     $
          oyvalsPtr:ptr_new(),     $

          ; Original tof arrays
          oxvalsPtr:ptr_new(),     $
          oTOFMonitorxvalsPtr:ptr_new(),     $

          ; Working tof array after conversion to point data
          xvalsPtr:ptr_new(),     $
          TOFMonitorxvalsPtr:ptr_new(),     $


       ; Working inelastic data set
          dataPtr:ptr_new(),   $
          errorPtr:ptr_new(),    $
          yvalsPtr:ptr_new(),    $



       ; Pointer to the lambda fields
       lambda_fieldPtr:ptr_new(),  $
       ; Good Detector Pointer
        good_detPtr: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()   $
          }


return
end
