;$Id: hscn_reduce__define.pro,v 1.9 2007/06/21 20:15:00 azuah Exp $
;###############################################################################
;
; NAME:
;  HSCN_REDUCE__DEFINE
;
; PURPOSE:
;  See description below.
;
; CATEGORY:
;  DAVE, HFBS, data reduction
;
; AUTHOR:
;   Robert M. Dimeo, Ph.D.
;   NIST Center for Neutron Research
;   100 Bureau Drive
;   Gaithersburg, MD 20899
;   Phone: (301) 975-8135
;   E-mail: robert.dimeo@nist.gov
;   http://www.ncnr.nist.gov/staff/dimeo
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used of if the code in this file is
;  included in another product.
;
;###############################################################################
;+
; NAME:
;       HSCN_REDUCE__DEFINE
;
; PURPOSE:
;
;   Object class for reducing the fixed-window scan flavor of HFBS data.  This
;   is a GUI program.
;
; AUTHOR:
;
;       Robert M. Dimeo, Ph.D.
;   NIST Center for Neutron Research
;       100 Bureau Drive
;   Gaithersburg, MD 20899
;       Phone: (301) 975-8135
;       E-mail: robert.dimeo@nist.gov
;       http://www.ncnr.nist.gov/staff/dimeo
;
; CATEGORY:
;
;       Data reduction, DAVE project, HFBS
;
; CALLING SEQUENCE:
;
;   OSCAN_REDUCE = OBJ_NEW("HSCN_REDUCE",GROUP_LEADER = group_leader)
;
; PARAMETERS:
;
;   GROUP_LEADER:  widget id of the parent program
;
; METHODS:
;   INIT (F):     Standard required creation lifecycle method.
;   CLEANUP (P):   Standard destruction lifecycle method.
;
; COMMON BLOCKS:
;
;   None
;
; REQUIREMENTS:
;
;   HSCN_DATA__DEFINE.PRO
;   RAFINS_FILE_INFO.PRO
;   CONVERT_BMP.PRO
;   HSCN_REBIN.PRO
;   SCATTER.BMP
;
;
; MODIFICATION HISTORY:
;
;       Written by Rob Dimeo, July 14, 2003
;-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hscn_reduce::cleanup
ptr_free,self.pslider_labels
heap_free,self.pwinfo
wdelete,self.win_pix
obj_destroy,self.data_container
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::desensitize_leader
widget_control,self.group_leader,sensitive = 1
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hscn_cleanup,tlb
widget_control,tlb,get_uvalue = self
ret = self->desensitize_leader()
obj_destroy,self
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::quit,event = event
widget_control,self.tlb,/destroy
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro winfo__define
; Definition of the named structure that contains all of the fields necessary
; to perform zooming operation in any of the draw widgets.
define =    { winfo,         $
         win:0L,       $
         autoscale:1,   $
         winVis:0L,      $
         winPix:0L,      $
         xPtr:ptr_new(),   $
         yPtr:ptr_new(),   $
         mouse:0B,      $
         xrange:fltarr(2),   $
         yrange:fltarr(2),   $
         xpos:0.0,      $
         ypos:0.0      $
      }
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::show_file_info,event = event
compile_opt idl2,hidden
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves gt 1 then begin
   void = dialog_message(dialog_parent = event.top,'Select only one file')
   return,0
endif
if (n_leaves eq 0) or not(widget_info(sel_leaves[0],/valid_id)) then return,0

widget_control,sel_leaves[0],get_uvalue = uval
ret = uval.odata->get(treatment = treatment)
; Call the non-modal widget and detect events coming from it
this_event = tag_names(event,/structure_name)
case this_event of
'RAFINS_FILE_INFO_EVENT':
'WIDGET_BUTTON':   $
   begin
     rafins_file_info,  treatment,           $
               group_leader = event.top, $
               notify_ids = [event.id,event.top], $
               title = 'HSCN file information'
   end
else:
endcase
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::plot_selection,event = event
n_data = self.data_container->count()
if n_data eq 0 then return,0
; Reserve enough symbols and linestyles to accomodate displaying 16 data sets.
symbol = [4,5,1,2,6,7,0]
linestyle = [0,1,2,3]
n_sym = n_elements(symbol)
n_lin = n_elements(linestyle)

; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves eq 0 then return,0
;if n_leaves gt 16 then begin  ; Too many files selected!
;   strout = 'Maximum number of files to plot at once is 16'
;   void = dialog_message(dialog_parent = event.top,strout)
;   return,0
;endif
xmin = 5.e55 & xmax = -xmin
ymin = xmin & ymax = xmax
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     names = tag_names(uval)
     ok = where(strupcase(names) eq 'ODATA',count_ok)
     if count_ok eq 0 then return,0
     ret = uval.odata->get_dep_var(qty = y,dqty = dy,label = ylabel)
     ret = uval.odata->get_indep_var(qty = x,label = xlabel)
     xmin = xmin < min(x)
     ymin = ymin < min(y)
     xmax = xmax > max(x)
     ymax = ymax > max(y)
   endif
endfor
dely = 0.1*(ymax-ymin)
delx = 0.1*(xmax-xmin)
xrange = [xmin-delx,xmax+delx] & yrange = [(ymin-dely)<0.0,ymax+dely]
if (*self.pwinfo).autoscale eq 0 then begin
   xrange = (*self.pwinfo).xrange
   yrange = (*self.pwinfo).yrange
endif
for i = 0,n_leaves-1 do begin
   widget_control,sel_leaves[i],get_uvalue = uval
   ret = uval.odata->get_dep_var(qty = y,dqty = dy,label = ylabel)
   ret = uval.odata->get_indep_var(qty = x,label = xlabel)

   psym = (i lt n_sym)? symbol[i] : symbol[i mod n_sym] 
   lsty = (i lt n_lin)? linestyle[i] : linestyle[i mod n_lin] 
   if i eq 0 then begin
     plot,x,y,psym = psym,linestyle = lsty,xtitle = xlabel, $
      ytitle = ylabel,xrange = xrange,yrange = yrange,/xsty,/ysty
     errplot,x,y-dy,y+dy,width = 0.0
   endif else begin
     oplot,x,y,psym = psym,linestyle = lsty
     errplot,x,y-dy,y+dy,width = 0.0
   endelse
endfor
*(*self.pwinfo).xptr = !x
*(*self.pwinfo).yptr = !y
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::refresh,event = event
wset,self.win_pix
ret = self->plot_selection(event = event)
wset,self.win_vis
device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.win_pix]
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::load_hscn_files,event = event
if n_elements(event) eq 0 then parent = 0L else parent = event.top
filename = dialog_pickfile(/read,filter = '*.hscn',dialog_parent = parent, $
   title = 'Select HSCN file(s)',/multiple_files,get_path = this_path, $
   path = self.dat_dir)
nfiles = n_elements(filename)
if filename[0] eq '' then return,0
;bmp_file = file_which('scatter.bmp')
bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
array = convert_bmp(bmp_file)

; Create new data leaves associated with each new data file
for i = 0,nfiles-1 do begin
   display_name = strmid(filename[i],strlen(this_path))
   leaf_id =  widget_tree(self.file_root,value = display_name, $
         bitmap = array,  $
         uname = 'HSCN_FILE',             $
         uvalue =   { object:self,         $
                 method:'select_data',    $
                 filename:filename[i],    $
                 odata:obj_new()      }   )
   o = obj_new('hscn_data',file = filename[i])
   ret = o->set(wid = leaf_id,path = this_path,display_name = display_name)
; Associate the object reference with the leaf id
   widget_control,leaf_id,get_uvalue = uval
   uval.odata = o
   widget_control,leaf_id,set_uvalue = uval
   self.data_container->add,o
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::show_context_menu,event = event
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::select_data,event = event
ret = self->refresh(event = event)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::merge_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves lt 2 then return,0

for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     widget_control,sel_leaves[i],get_value = display_name
     if i eq 0 then name_array = display_name else $
      name_array = [name_array,display_name]
   endif
endfor

for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     odata = uval.odata
     if i eq 0 then darray = odata else darray = [darray,odata]
    ret = odata->get(treatment = treatment)
    if i eq 0 then begin
       tarray = [treatment,'The following data files were merged: ', $
             name_array]
    endif else begin
       tarray = [treatment,'#####',tarray]
    endelse
   endif
endfor
omerge = merge_scan(darray)
ret = omerge->set(treatment = tarray)
; Create a new name for the merged data set
display_name = 'Merged Data Set'
; Create a new leaf
;bmp_file = file_which('scatter.bmp')
bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
array = convert_bmp(bmp_file)

; Create new data leaves associated with each new data file
leaf_id =   widget_tree(self.file_root,value = display_name,  $
      bitmap = array,                 $
      uname = 'HSCN_FILE',             $
      uvalue = {  object:self,       $
               method:'select_data',   $
               filename:'',   $
               odata:omerge      } )
ret = omerge->set(wid = leaf_id)
; Associate the object reference with the leaf id
widget_control,leaf_id,get_uvalue = uval
; Update the dependent variable
ret = omerge->get_dep_var(identity = identity,label = label)
tcontrol = (tsample = (time = 0))
wbm = (fc = (tbm = 0))
detector = 0
case identity of
'TCONTROL': tcontrol = 1
'TSAMPLE':  tsample = 1
'TIME':   time = 1
'TBM':     tbm = 1
'FC':    fc = 1
'WBM':     wbm = 1
'DETECTOR': $
   begin
     pos = strlen('!3DETECTOR:')
     detector = fix(strmid(label,pos))
   end
else:
endcase
ret = omerge->set_dep_var(    tcontrol = tcontrol,   $
                 tsample = tsample,    $
                 time = time,      $
                 fc = fc,        $
                 wbm = wbm,         $
                 tbm = tbm,         $
                 detector = detector     )
uval.odata = omerge
widget_control,leaf_id,set_uvalue = uval
self.data_container->add,omerge
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::revert_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves eq 0 then return,0
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->revert()
   endif
endfor
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::add_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves lt 2 then return,0
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     widget_control,sel_leaves[i],get_value = display_name
     if i eq 0 then name_array = display_name else $
      name_array = [name_array,display_name]
   endif
endfor
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     odata = uval.odata
     if i eq 0 then darray = odata else darray = [darray,odata]
    ret = odata->get(treatment = treatment)
    if i eq 0 then begin
       tarray = ['The following data were summed: ',name_array,treatment]
    endif else begin
       tarray = [treatment,'#####',tarray]
     endelse
   endif
endfor
tarray = [tarray,'End summing files']

oadd = add_scan(darray,/interp,/poisson)

if not(obj_valid(oadd)) then return,0

ret = oadd->set(treatment = tarray)
; Create a new name for the merged data set
display_name = 'Summed Data Set'
; Create a new leaf
;bmp_file = file_which('scatter.bmp')
bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
array = convert_bmp(bmp_file)

; Create new data leaves associated with each new data file
leaf_id =   widget_tree(self.file_root,value = display_name,  $
      uname = 'HSCN_FILE',             $
      bitmap = array,                 $
      uvalue = {  object:self,       $
               method:'select_data',   $
               filename:'',   $
               odata:oadd      }   )
ret = oadd->set(wid = leaf_id)
; Associate the object reference with the leaf id
widget_control,leaf_id,get_uvalue = uval
; Update the dependent variable
ret = oadd->get_dep_var(identity = identity,label = label)
tcontrol = (tsample = (time = 0))
wbm = (fc = (tbm = 0))
detector = 0
case identity of
'TCONTROL': tcontrol = 1
'TSAMPLE':  tsample = 1
'TIME':   time = 1
'TBM':     tbm = 1
'FC':    fc = 1
'WBM':     wbm = 1
'DETECTOR': $
   begin
     pos = strlen('!3DETECTOR:')
     detector = fix(strmid(label,pos))
   end
else:
endcase
ret = oadd->set_dep_var(     tcontrol = tcontrol,  $
                 tsample = tsample,    $
                 time = time,      $
                 fc = fc,        $
                 wbm = wbm,         $
                 tbm = tbm,         $
                 detector = detector     )
uval.odata = oadd
widget_control,leaf_id,set_uvalue = uval
self.data_container->add,oadd
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::split_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves ne 1 then begin
   strout = 'You can only split one data set at a time'
   void = dialog_message(dialog_parent = event.top,strout)
   return,0
endif
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     widget_control,sel_leaves[i],get_value = display_name
     if i eq 0 then name_array = display_name else $
      name_array = [name_array,display_name]
   endif
endfor
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     odata = uval.odata
     if i eq 0 then darray = odata else darray = [darray,odata]
    ret = odata->get(treatment = treatment)
   endif
endfor
ret = split_scan_dialog(group_leader = event.top)
if (n_elements(ret.tarray) eq 1) and (ret.tarray[0] eq -999) or $
   (ret.cancel eq 1) then return,0
oarray = split_scan(darray[0],ret.tarray)
if not(obj_valid(oarray[0])) then return,0
;
; Now loop over the new split objects...
nobj = n_elements(oarray)
for i = 0,nobj-1 do begin

; Create a new name for the merged data set
   ret = uval.odata->get(display_name = display_name)
   new_name = 'split_'+strtrim(string(i+1),2)+'_'+name_array[0]
   display_name = new_name
   ret = oarray[i]->set(display_name = display_name)
; Create a new leaf
   ;bmp_file = file_which('scatter.bmp')
   bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
   array = convert_bmp(bmp_file)

; Create new data leaves associated with each new data file
   leaf_id =  widget_tree(self.file_root,value = display_name, $
         uname = 'HSCN_FILE',             $
         bitmap = array,               $
         uvalue =   { object:self,         $
                 method:'select_data',    $
                 filename:'',    $
                 odata:oarray[i]      }   )
   ret = oarray[i]->set(wid = leaf_id)
; Associate the object reference with the leaf id
   widget_control,leaf_id,get_uvalue = uval
; Update the dependent variable
   ret = oarray[i]->get_dep_var(identity = identity,label = label)
   tcontrol = (tsample = (time = 0))
   wbm = (fc = (tbm = 0))
   detector = 0
   case identity of
   'TCONTROL':   tcontrol = 1
   'TSAMPLE': tsample = 1
   'TIME':    time = 1
   'TBM':   tbm = 1
   'FC':     fc = 1
   'WBM':   wbm = 1
   'DETECTOR':   $
         begin
           pos = strlen('!3DETECTOR:')
           detector = fix(strmid(label,pos))
         end
   else:
   endcase
   ret = oarray[i]->set_dep_var(   tcontrol = tcontrol,   $
                  tsample = tsample,     $
                  time = time,      $
                  fc = fc,       $
                  wbm = wbm,        $
                  tbm = tbm,        $
                  detector = detector   )
   uval.odata = oarray[i]
   widget_control,leaf_id,set_uvalue = uval
   self.data_container->add,oarray[i]
   ret = self->refresh()
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::subtract_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves ne 2 then begin
   void = dialog_message(dialog_parent = event.top, $
     'You must select only two data sets for subtraction.')
   return,0
endif
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     widget_control,sel_leaves[i],get_value = display_name
     if i eq 0 then name_array = display_name else $
      name_array = [name_array,display_name]
   endif
endfor
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     odata = uval.odata
     if i eq 0 then darray = odata else darray = [darray,odata]
    ret = odata->get(treatment = treatment)
    if i eq 0 then begin
       tarray = ['The following data were subtracted: ',name_array,treatment]
    endif else begin
       tarray = [treatment,'#####',tarray]
     endelse
   endif
endfor
tarray = [tarray,'End subtraction files']

osub = subtract_scan(darray,/interp)

if not(obj_valid(osub)) then return,0

ret = osub->set(treatment = tarray)
; Create a new name for the merged data set
display_name = 'Difference Data Set'
; Create a new leaf
bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
;bmp_file = file_which('scatter.bmp')
array = convert_bmp(bmp_file)

; Create new data leaves associated with each new data file
leaf_id =   widget_tree(self.file_root,value = display_name,  $
      uname = 'HSCN_FILE',             $
      bitmap = array,                 $
      uvalue = {  object:self,       $
               method:'select_data',   $
               filename:'',   $
               odata:osub      }   )
ret = osub->set(wid = leaf_id)
; Associate the object reference with the leaf id
widget_control,leaf_id,get_uvalue = uval
; Update the dependent variable
ret = osub->get_dep_var(identity = identity,label = label)
tcontrol = (tsample = (time = 0))
wbm = (fc = (tbm = 0))
detector = 0
case identity of
'TCONTROL': tcontrol = 1
'TSAMPLE':  tsample = 1
'TIME':   time = 1
'TBM':     tbm = 1
'FC':    fc = 1
'WBM':     wbm = 1
'DETECTOR': $
   begin
     pos = strlen('!3DETECTOR:')
     detector = fix(strmid(label,pos))
   end
else:
endcase
ret = osub->set_dep_var(     tcontrol = tcontrol,  $
                 tsample = tsample,    $
                 time = time,      $
                 fc = fc,        $
                 wbm = wbm,         $
                 tbm = tbm,         $
                 detector = detector     )
uval.odata = osub
widget_control,leaf_id,set_uvalue = uval
self.data_container->add,osub
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::merge_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves lt 2 then begin
   void = dialog_message(dialog_parent = event.top, $
     'You must select at least two data sets for subtraction.')
   return,0
endif
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     widget_control,sel_leaves[i],get_value = display_name
     if i eq 0 then name_array = display_name else $
      name_array = [name_array,display_name]
   endif
endfor
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     odata = uval.odata
     if i eq 0 then darray = odata else darray = [darray,odata]
    ret = odata->get(treatment = treatment)
    if i eq 0 then begin
       tarray = ['The following data were merged: ',name_array,treatment]
    endif else begin
       tarray = [treatment,'#####',tarray]
     endelse
   endif
endfor
tarray = [tarray,'End merge files']

omerge = merge_scan(darray)

if not(obj_valid(omerge)) then return,0

ret = omerge->set(treatment = tarray)
; Create a new name for the merged data set
display_name = 'Merged Data Set'
; Create a new leaf
;bmp_file = file_which('scatter.bmp')
bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
array = convert_bmp(bmp_file)

; Create new data leaves associated with each new data file
leaf_id =   widget_tree(self.file_root,value = display_name,  $
      uname = 'HSCN_FILE',             $
      bitmap = array,                 $
      uvalue = {  object:self,       $
               method:'select_data',   $
               filename:'',   $
               odata:omerge      } )
ret = omerge->set(wid = leaf_id)
; Associate the object reference with the leaf id
widget_control,leaf_id,get_uvalue = uval
; Update the dependent variable
ret = omerge->get_dep_var(identity = identity,label = label)
tcontrol = (tsample = (time = 0))
wbm = (fc = (tbm = 0))
detector = 0
case identity of
'TCONTROL': tcontrol = 1
'TSAMPLE':  tsample = 1
'TIME':   time = 1
'TBM':     tbm = 1
'FC':    fc = 1
'WBM':     wbm = 1
'DETECTOR': $
   begin
     pos = strlen('!3DETECTOR:')
     detector = fix(strmid(label,pos))
   end
else:
endcase
ret = omerge->set_dep_var(    tcontrol = tcontrol,   $
                 tsample = tsample,    $
                 time = time,      $
                 fc = fc,        $
                 wbm = wbm,         $
                 tbm = tbm,         $
                 detector = detector     )
uval.odata = omerge
widget_control,leaf_id,set_uvalue = uval
self.data_container->add,omerge
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hscn_reduce_event,event
;begin error handler------------------------------------------------------------
; RTA - handler to catch misc. errors and provide a graceful exit so
;       that main app does not crash. Remember to switch off debug flag when debugging!
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
;    eMsg = [eMsg,'Function/module name: calledfunc()',!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
        return
    endif
endif
;end error handler-------------------------------------------------------------

if (tag_names(event,/structure_name) eq 'WIDGET_CONTEXT') then begin
   context_base = widget_info(event.top,find_by_uname = 'CONTEXT_BASE')
; Which of the leaves (if any) have been selected?
   file_tree = widget_info(event.top,find_by_uname = 'FILE_TREE')
   sel_leaves = widget_info(file_tree,/tree_select)
   for i = 0,n_elements(sel_leaves)-1 do begin
     uname = widget_info(sel_leaves[i],/uname)
     if uname ne 'HSCN_FILE' then return
   endfor
   widget_displaycontextmenu,event.id,event.x,event.y,context_base
endif
widget_control,event.id,get_uvalue = cmd
result = call_method(cmd.method,cmd.object,event = event)
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::change_indep_var,event = event
widget_control,event.id,get_value = val
tsample = (tcontrol = (time = 0))
case strupcase(val[0]) of
'SAMPLE TEMPERATURE':   $
   begin
     tsample = 1
   end
'CONTROL TEMPERATURE':  $
   begin
     tcontrol = 1
   end
'TIME':  $
   begin
     time = 1
   end
else:
endcase
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->set_indep_var(  tcontrol = tcontrol,  $
                       tsample = tsample,    $
                       time = time)
     widget_control,sel_leaves[i],set_uvalue = uval
   endif
endfor
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::slider_change_indep_var,event = event
widget_control,event.id,get_value = val & val = fix(val[0])-1
; Just to start...change the label
id = widget_info(event.top,find_by_uname = 'INDEP_VAR_LABEL')
widget_control,id,set_value = (*self.pslider_labels)[val]
label = (*self.pslider_labels)[val]
tsample = (tcontrol = (time = 0))
case strupcase(label) of
'SAMPLE TEMPERATURE':   $
   begin
     tsample = 1
   end
'CONTROL TEMPERATURE':  $
   begin
     tcontrol = 1
   end
'TIME':  $
   begin
     time = 1
   end
else:
endcase
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves eq 0 or not(widget_info(sel_leaves[0],/valid_id)) then return,0
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->set_indep_var(  tcontrol = tcontrol,  $
                       tsample = tsample,    $
                       time = time)
     widget_control,sel_leaves[i],set_uvalue = uval
   endif
endfor
ret = self->refresh()

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::slider_change_dep_var,event = event
widget_control,event.id,get_value = val & val = fix(val[0])-1
; Just to start...change the label
id = widget_info(event.top,find_by_uname = 'DEP_VAR_LABEL')
widget_control,id,set_value = (*self.pslider_labels)[val]
label = (*self.pslider_labels)[val]

tsample = (tcontrol = (time = 0))
wbm = (tbm = (fc = 0))
detector = 0

case strupcase(label) of
'SAMPLE TEMPERATURE':   $
   begin
     tsample = 1
   end
'CONTROL TEMPERATURE':  $
   begin
     tcontrol = 1
   end
'TIME':  $
   begin
     time = 1
   end
'FISSION CHAMBER':   $
   begin
     fc = 1
   end
'TRANSMITTED BEAM MONITOR':   $
   begin
     tbm = 1
   end
'WHITE BEAM MONITOR':   $
   begin
     wbm = 1
   end
else: $  ; must be a detector selected
   begin
     l = strlen('DETECTOR ')
     detector = fix(strmid(label,l))
   end
endcase
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if (n_leaves eq 0) or not(widget_info(sel_leaves[0],/valid_id)) then return,0
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->set_dep_var( tcontrol = tcontrol, $
                     tsample = tsample,   $
                     time = time,      $
                     wbm = wbm,       $
                     detector = detector,   $
                     fc = fc,         $
                     tbm = tbm        $
                     )
     widget_control,sel_leaves[i],set_uvalue = uval
   endif
endfor
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::change_dep_var,event = event
widget_control,event.id,get_value = val
tsample = (tcontrol = (time = 0))
wbm = (tbm = (fc = 0))
detector = 0

case strupcase(val[0]) of
'SAMPLE TEMPERATURE':   $
   begin
     tsample = 1
   end
'CONTROL TEMPERATURE':  $
   begin
     tcontrol = 1
   end
'TIME':  $
   begin
     time = 1
   end
'FISSION CHAMBER':   $
   begin
     fc = 1
   end
'TRANSMITTED BEAM MONITOR':   $
   begin
     tbm = 1
   end
'WHITE BEAM MONITOR':   $
   begin
     wbm = 1
   end
else: $  ; must be a detector selected
   begin
     l = strlen('DETECTOR ')
     detector = fix(strmid(val[0],l))
   end
endcase
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->set_dep_var( tcontrol = tcontrol, $
                     tsample = tsample,   $
                     time = time,      $
                     wbm = wbm,       $
                     detector = detector,   $
                     fc = fc,         $
                     tbm = tbm        $
                     )
     widget_control,sel_leaves[i],set_uvalue = uval
   endif
endfor
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::window_events,event = event
; First test to see if any files have been selected and if they are valid
; widget ids....
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if not(widget_info(sel_leaves[0],/valid_id)) then return,0

case event.type of
0: begin    ; button press
     (*self.pwinfo).mouse = event.press
     if (*self.pwinfo).mouse eq 4 then begin
      (*self.pwinfo).autoscale = 1
       !x = *(*self.pwinfo).xPtr
       !y = *(*self.pwinfo).yPtr
     ret = self->refresh()
     endif
     if (*self.pwinfo).mouse eq 1 then begin
       (*self.pwinfo).xPos = event.x
       (*self.pwinfo).yPos = event.y
       !x = *(*self.pwinfo).xPtr
       !y = *(*self.pwinfo).yPtr
       wset,(*self.pwinfo).winvis
       device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*self.pwinfo).winpix]
       (*self.pwinfo).autoscale = 0
     endif
   end
1: begin ; button release
    if (*self.pwinfo).mouse eq 1 then begin
     !x = *(*self.pwinfo).xPtr
     !y = *(*self.pwinfo).yPtr
      xll = Min([(*self.pwinfo).xpos, event.x], Max=xur)
      yll = Min([(*self.pwinfo).ypos, event.y], Max=yur)
     ll = convert_coord(xll,yll,/device,/to_data)
     ur = convert_coord(xur,yur,/device,/to_data)
     (*self.pwinfo).xrange = [ll[0],ur[0]]
     (*self.pwinfo).yrange = [ll[1],ur[1]]
     ret = self->refresh()
     (*self.pwinfo).mouse = 0B
    endif
    if (*self.pwinfo).mouse eq 4 then begin
     !x = *(*self.pwinfo).xPtr
     !y = *(*self.pwinfo).yPtr
     ret = self->refresh()
     (*self.pwinfo).mouse = 0B
    endif
   end
2: begin ; mouse motion
     if (*self.pwinfo).mouse eq 1 then begin
        xc = [(*self.pwinfo).xpos,event.x,event.x,$
              (*self.pwinfo).xpos,$
              (*self.pwinfo).xpos]
        yc = [(*self.pwinfo).ypos,(*self.pwinfo).ypos,$
              event.y,event.y,$
              (*self.pwinfo).ypos]
        wset,(*self.pwinfo).winVis
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*self.pwinfo).winPix]
        plots,xc,yc,/device
     endif
   end
else:
endcase
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::normalize_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
; Has this data been normalized already?
     ret = uval.odata->get(treatment = treatment)
     normalized = where(strupcase(treatment) eq 'NORMALIZED TO FISSION CHAMBER', $
      count_norm)
     if count_norm eq 0 then begin
      ret = uval.odata->normalize_to_monitor()
      ret = uval.odata->get_dep_var(identity = identity,label = label)
      tcontrol = (tsample = (time = 0))
      wbm = (fc = (tbm = 0))
      detector = 0
      case identity of
      'TCONTROL': tcontrol = 1
      'TSAMPLE':  tsample = 1
      'TIME':   time = 1
      'TBM':     tbm = 1
      'FC':    fc = 1
      'WBM':     wbm = 1
      'DETECTOR': $
         begin
           pos = strlen('!3DETECTOR:')
           detector = fix(strmid(label,pos))
         end
      else:
      endcase
      ret = uval.odata->set_dep_var(   tcontrol = tcontrol,   $
                       tsample = tsample,    $
                       time = time,      $
                       fc = fc,        $
                       wbm = wbm,         $
                       tbm = tbm,         $
                       detector = detector     )
      widget_control,sel_leaves[i],set_uvalue = uval
     endif
   endif
endfor
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::rebin_data,event = event
; What leaves have been selected?
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->get_indep_var(qty = x)
     ret = hscn_rebin(x,group_leader = event.top)
     if ret.cancel ne 1 then begin
      ret = uval.odata->rebin(xlo = ret.xlo,xhi = ret.xhi,nbins = ret.nbins)
      ret = self->refresh()
     endif
   endif
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::write_hscn,event = event
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves eq 0 then return,0
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->write_hscn()
   endif
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::write_dave,event = event
sel_leaves = widget_info(self.file_tree,/tree_select)
n_leaves = n_elements(sel_leaves)
if n_leaves eq 0 then return,0
for i = 0,n_leaves-1 do begin
   if widget_info(sel_leaves[i],/valid_id) then begin
     widget_control,sel_leaves[i],get_uvalue = uval
     ret = uval.odata->write_dave(msg = msg,path = self.work_dir)
   endif
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::refresh_widget
ret = self->refresh()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::build_gui
tlb = widget_base(title = 'HFBS Fixed Window Scan Data Reduction', $
   /row,mbar = bar,/tlb_frame_attr)
self.tlb = tlb
; Create the file menu
file_menu = widget_button(bar,value = 'FILE',/menu)
void = widget_button(file_menu,value = 'Load HSCN file(s)', $
   uvalue = {object:self,method:'load_hscn_files'})
void = widget_button(file_menu,value = 'QUIT',  $
   uvalue = {object:self,method:'quit'})
; Create the tree widget
file_tree = widget_tree(self.tlb,/context_events,/multiple,uname = 'FILE_TREE', $
   uvalue = {object:self,method:'show_context_menu'})
self.file_tree = file_tree
file_root = widget_tree(self.file_tree,value = 'Fixed window scan files',  $
   /folder,/expanded, uname = 'FILE_ROOT', $
   uvalue = {object:self,method:'refresh'})
self.file_root = file_root

xsize = 400 & ysize = 400
col_base = widget_base(self.tlb,/col)
win = widget_draw(col_base,xsize = xsize,ysize = ysize,  $
   /button_events,/motion_events,  $
   uvalue = {object:self,method:'window_events'})
row_base = widget_base(col_base,/row)
slider_base1 = widget_base(row_base,/row,/frame)
void = widget_slider(slider_base1,value = 21,min = 20,max = 22, title = 'Indep Var',   $
   uvalue = {object:self,method:'slider_change_indep_var'},/suppress)
lab = widget_label(slider_base1, value = 'Control temperature', /dynamic_resize, $
   uname = 'INDEP_VAR_LABEL')
slider_base2 = widget_base(row_base,/row,/frame)
void = widget_slider(slider_base2,value = 1,min = 1,max = 22, title = 'Dep Var', $
   uvalue = {object:self,method:'slider_change_dep_var'},/suppress)
lab = widget_label(slider_base2, value = 'Detector 1', /dynamic_resize, $
   uname = 'DEP_VAR_LABEL')
; Create the context-sensitive menu for the files
csm_base = widget_base(self.tlb,/context_menu,uname = 'CONTEXT_BASE')
self.csm_base = csm_base
void = widget_button(self.csm_base,value = 'View data treatment', $
     uvalue = {object:self,method:'show_file_info'})
void = widget_button(self.csm_base,value = 'Merge data', $
     uvalue = {object:self,method:'merge_data'},/separator)
void = widget_button(self.csm_base,value = 'Add data', $
     uvalue = {object:self,method:'add_data'})
void = widget_button(self.csm_base,value = 'Subtract data', $
     uvalue = {object:self,method:'subtract_data'})
void = widget_button(self.csm_base,value = 'Split data', $
     uvalue = {object:self,method:'split_data'})
void = widget_button(self.csm_base,value = 'Normalize data to monitor', $
     uvalue = {object:self,method:'normalize_data'})
void = widget_button(self.csm_base,value = 'Rebin data', $
     uvalue = {object:self,method:'rebin_data'})
void = widget_button(self.csm_base,value = 'Revert to original data set', $
     uvalue = {object:self,method:'revert_data'},/separator)
;void = widget_button(self.csm_base,value = 'Write a new HSCN file', $
;   uvalue = {object:self,method:'write_hscn'})
void = widget_button(self.csm_base,value = 'Write to a DAVE file', $
     uvalue = {object:self,method:'write_dave'},/separator)

centertlb,self.tlb
widget_control,self.tlb,/realize
widget_control,win,get_value = win_vis & self.win_vis = win_vis
window,/free,xsize = xsize,ysize = ysize,/pixmap
self.win_pix = !d.window
(*self.pwinfo).winPix = self.win_pix
(*self.pwinfo).winVis = self.win_vis
widget_control,self.tlb,set_uvalue = self

xmanager,'hscn_reduce_gui',self.tlb,/no_block,cleanup = 'hscn_cleanup', $
   event_handler = 'hscn_reduce_event'
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function hscn_reduce::init,group_leader = group_leader,datDir = datDir, $
   workDir = workDir
forward_function convert_bmp
if n_elements(group_leader) eq 0 then group_leader = 0L
if n_elements(dat_dir) eq 0 then dat_dir = ''
if n_elements(workDir) eq 0 then workDir = ''
self.dat_dir = dat_dir
labels = strarr(22)
labels[0:15] = 'Detector '+strtrim(string(1+indgen(16)),2)
labels[16:21] = ['Fission chamber','White beam monitor','Transmitted beam monitor', $
         'Time','Control temperature','Sample temperature']
self.pslider_labels = ptr_new(labels)
self.pwinfo = ptr_new({winfo})
(*self.pwinfo).xPtr = ptr_new(/allocate_heap)
(*self.pwinfo).yPtr = ptr_new(/allocate_heap)
(*self.pwinfo).autoscale = 1

self.data_container = obj_new('IDL_CONTAINER')
self.csm_base = 0L & self.csm_menu = 0L
self.group_leader = group_leader
self.dat_dir = datDir
self.work_dir = workDir
ret = self->build_gui()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hscn_reduce__define

define = {  hscn_reduce,            $
         tlb:0L,                $
         group_leader:0L,          $
         file_tree:0L,            $
         file_root:0L,            $
         csm_menu:0L,            $
         csm_base:0L,            $
         pwinfo:ptr_new(),           $
         pslider_labels:ptr_new(),      $
         data_container:obj_new(),      $
         win_vis:0L,               $
         win_pix:0L,               $
         dat_dir:'',               $
         work_dir:''               $
      }
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro hscn_reduce
data_directory = 'c:\dimeo\hfbs\data\ch3i\mar2002\raw\'
o = obj_new('hscn_reduce',dat_dir = data_directory)
end
