; $Id: dtas_reduction_gui__define.pro,v 1.83.2.1 2008/06/30 18:09:41 azuah Exp $
;###############################################################################
;
; NAME:
;  DTAS_REDUCTION_GUI__DEFINE
;
; PURPOSE:
;  Class for TAS data reduction application.
;
; CATEGORY:
;  DAVE, TAS, 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.
;
;###############################################################################
; +
;
; -
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dtas_reduction_gui::cleanup
; This is the cleanup routine.
heap_free,self.prefs_ptr
heap_free,self.plot_info
ptr_free,self.dave_color_ptr,self.color_ptr,self.sym_ptr
ptr_free,self.dtas_color_ptr,self.sel_colors_ptr
ptr_free,self.file_icon,self.image_icon,self.legend_ptr
ptr_free,self.widget_info_ptr
heap_free,self.daveptr
wdelete,self.winpix
n = self.tas_container->count()
if n gt 0 then begin
   oall = self.tas_container->get(/all)
   for i = 0,n-1 do self.tas_container->remove,oall[i]
   obj_destroy,oall
endif
obj_destroy,self.tas_container
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::get_notify_ids
return,self.notify_ids
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function convert_symbol,shape,fill
case strupcase(shape) of
'CIRCLE': psym = hfbs_plotsym(/circle,fill = fill)
'TRIANGLE': psym = hfbs_plotsym(/triangle,fill = fill)
'BOX': psym = hfbs_plotsym(/box,fill = fill)
'DIAMOND': psym = hfbs_plotsym(/diamond,fill = fill)
else: psym = 4
endcase
return,psym
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::update_status,str
text_id = widget_info(self.tlb,find_by_uname = 'STATUS_TEXT')
widget_control,text_id,set_value = str
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::display_image,event,_Extra = extra
; Get the selected widget id
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
widget_control,sel_id,get_uvalue = uval
o = uval.image_object
ret = o->display()
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::display,event,REVERSE_COLORS = reverse_colors, $
   PLOT_INFO = plot_info,_Extra = extra
output = 0
plot_info_type = size(plot_info,/tname)
if plot_info_type eq 'STRUCT' then begin
   output = 1
   ; We will annotate the plot with the user's choices
   tags = tag_names(plot_info)
   match_1 = where(strlowcase(tags) eq 'column_one',count_1)
   match_2 = where(strlowcase(tags) eq 'column_two',count_2)
   if count_1 gt 0 then col1 = plot_info.column_one
   if count_2 gt 0 then col2 = plot_info.column_two
endif

if output eq 0 then position = [0.2,0.15,0.95,0.9] else $
   position = [0.15,0.6,0.9,0.95]
if n_elements(*self.plot_info) eq 0 then return,0

plot_str = *self.plot_info
n = n_elements(plot_str.px)

for i = 0,n-1 do begin
   if i eq 0 then begin
      x = *plot_str.px[i]
      y = *plot_str.py[i]
      dy = *plot_str.pdy[i]
      ;TDy = *plot_str.pTDy[i]
      mon = *plot_str.pmon[i]
      scan = plot_str.scan[i]
      treatment = *(plot_str).ptreatment[i]
      if scan ne 'ALIGNMENT' then begin
         ; Is it normalized to the beam monitor?
         index = where(treatment eq 'Normalized to beam monitor',count_treat)
         mon_norm = count_treat eq 1

         if mon_norm then mon_ave = mon else mon_ave = mon[0]
         if self.plot_det then begin
            if self.plot_detnorm then begin
               y = y*mon_ave/mon
               dy = dy*mon_ave/mon
            endif else begin
               ytitle = 'Raw detector counts'
            endelse
         endif else begin
            y = mon
            dy = sqrt(mon)
         endelse
      endif
   endif else begin
      treatment = *(plot_str).ptreatment[i]
      scan = plot_str.scan[i]
      ; Is it normalized to the beam monitor?
      index = where(treatment eq 'Normalized to beam monitor',count_treat)
      mon_norm = count_treat eq 1

      tmpx = *plot_str.px[i]
      tmpy = *plot_str.py[i]
      tmpdy = *plot_str.pdy[i]
      tmpmon = *plot_str.pmon[i]

      if mon_norm then mon_ave = tmpmon else mon_ave = tmpmon[0]
      if scan ne 'ALIGNMENT' then begin
         if self.plot_det then begin
            if self.plot_detnorm then begin
               tmpy = tmpy*mon_ave/tmpmon
               tmpdy = tmpdy*mon_ave/tmpmon
            endif else begin
               ytitle = 'Raw detector counts'
            endelse
         endif else begin
            tmpy = tmpmon
            tmpdy = sqrt(tmpmon)
         endelse
      endif

      x = [x,tmpx]
      y = [y,tmpy]
      dy = [dy,tmpdy]
      mon = [mon,tmpmon]

   endelse
endfor
xmin = min(x,max = xmax) & ymin = min(y,max = ymax) ;& ymin = min(y-dy) & ymax = max(y+dy)
anaMode = plot_str.anaMode[0]
anaMode2or3 = (anaMode eq 2) || (anaMode eq 3)
if (anaMode2or3 && plot_str.show_TD) then begin
    TDy = *plot_str.pTDy[0]
    aYmin = min(TDy,max=aYmax)
    ymin = aYmin < ymin
    ymax = aYmax > ymax
endif
if self.autoscale then begin
   delx = 0.2*(xmax-xmin)
   dely = 0.2*(ymax-ymin+max(dy))
   self.xrange = [xmin-delx,xmax+delx]
   self.yrange = [ymin-dely,ymax+dely]
endif

x = *plot_str.px[0]
y = *plot_str.py[0]
dy = *plot_str.pdy[0]
mon = *plot_str.pmon[0]
scan = plot_str.scan[0]
treatment = *(plot_str).ptreatment[0]


; Is it normalized to the beam monitor?
index = where(treatment eq 'Normalized to beam monitor',count_treat)
mon_norm = count_treat eq 1
if scan ne 'ALIGNMENT' then begin
   if mon_norm then mon_ave = mon else mon_ave = mon[0]
   if self.plot_det then begin
      if self.plot_detnorm then begin
         y = y*mon_ave/mon
         dy = dy*mon_ave/mon
         ytitle = plot_str.ytitle
         if (anaMode2or3 && plot_str.show_TD) then TDy = TDy*mon_ave/mon
      endif else begin
         ytitle = 'Raw detector counts'
      endelse
   endif else begin
      y = mon
      dy = sqrt(mon)
      ytitle = 'Raw monitor counts'
   endelse
endif
colors = *self.sel_colors_ptr
sym_str = *self.sym_ptr
; Get the symbol out
fill = sym_str.fill[0]
shape = sym_str.shape[0]
psym = convert_symbol(shape,fill)
axis_color = (*self.color_ptr).black
bg_color = (*self.color_ptr).white
sym_color = sym_str.color[0]
; Plot the axis first
if n eq 1 then title = plot_str.title else title = ''
;plot,x,y,psym = 0,xrange = self.xrange,yrange = self.yrange,/xsty,/ysty, /nodata,$
;   xtitle = plot_str.xtitle,ytitle = plot_str.ytitle,color = axis_color, $
;   background = bg_color,title = title,position = position
plot,x,y,psym = 0,xrange = self.xrange,yrange = self.yrange,/xsty,/ysty, /nodata,$
   xtitle = plot_str.xtitle,ytitle = ytitle,color = axis_color, $
   background = bg_color,title = title,position = position
oplot,x,y,psym = psym,color = sym_color
color_errplot,x,y-dy,y+dy,width = 0.0,color = sym_color
if (anaMode2or3 && plot_str.show_TD) then oplot,x,TDy,color=(*self.color_ptr).red,psym=0,thick=2.5

ok = where(tag_names(plot_str) eq 'FIT_PTR',count_ok)
if (count_ok gt 0) then begin
    oplot,(*plot_str.fit_ptr).x,(*plot_str.fit_ptr).yfit,psym=0,thick=2.0,color=colors[3]
    fit_text = (*plot_str.fit_ptr).fit_text
    if (n_elements(fit_text) gt 0) then begin
        cy1_top = 0.88 & cy1_bottom = 0.05
        cx1_start = 0.22 & cy1_end = 0.8
        nlines = n_elements(fit_text)
        longest_line = max(strlen(fit_text),i_max)
        
        chsize = 1.0 ; STR_SIZE(fit_text[i_max], 0.4,step = 1.0) < 1.25
        dely = ((cy1_top-cy1_bottom)/nlines) < 0.04
        ypos = cy1_top
        for i = 0,nlines-1 do begin
            xyouts,cx1_start,ypos,fit_text[i],/normal,color = (*self.color_ptr).black, $
                   charsize = chsize,charthick=1.0,font=0
            ypos = ypos-dely
        endfor
        
    endif
endif
if n gt 1 then begin
   for i = 1,n-1 do begin
       ii = n_elements(sym_str.color)
      sym_color = sym_str.color[i mod ii]
      x = *plot_str.px[i]
      y = *plot_str.py[i]
      dy = *plot_str.pdy[i]
      mon = *plot_str.pmon[i]
      scan = plot_str.scan[i]
      treatment = *(plot_str).ptreatment[i]
      ; Is it normalized to the beam monitor?
      index = where(treatment eq 'Normalized to beam monitor',count_treat)
      mon_norm = count_treat eq 1

      if mon_norm then mon_ave = mon else mon_ave = mon[0]
      if scan ne 'ALIGNMENT' then begin
         if self.plot_det then begin
;            y = y*mon_ave/mon
;            dy = dy*mon_ave/mon
         endif else begin
            y = mon
            dy = sqrt(mon)
         endelse
     endif
     iis = n_elements(sym_str.shape)
     iif = n_elements(sym_str.fill)
      oplot,x,y,psym = convert_symbol(sym_str.shape[i mod iis],sym_str.fill[i mod iif]), $
         color = sym_color
      color_errplot,x,y-dy,y+dy,width = 0.0,color = sym_color
   endfor
endif

if output eq 1 then begin  ; add the annotations
   if n_elements(col1) ne 0 then begin
      cy1_top = 0.5 & cy1_bottom = 0.05
      cx1_start = 0.05 & cy1_end = 0.5
      nlines = n_elements(col1)
      longest_line = max(strlen(col1),i_max)

      chsize = STR_SIZE(col1[i_max], 0.4,step = 0.01) < 0.6
      dely = ((cy1_top-cy1_bottom)/nlines) < 0.01
      ypos = cy1_top
      for i = 0,nlines-1 do begin
         xyouts,cx1_start,ypos,col1[i],/normal,color = (*self.color_ptr).black, $
            charsize = chsize
         ypos = ypos-dely
      endfor
   endif
   if n_elements(col2) ne 0 then begin
      cy2_top = 0.5 & cy2_bottom = 0.05
      cx2_start = 0.55 & cy2_end = 0.95
      nlines = n_elements(col2)
      longest_line = max(strlen(col2),i_max)

      chsize = STR_SIZE(col2[i_max], 0.4,step = 0.01) < 0.6
      dely = ((cy2_top-cy2_bottom)/nlines) < 0.01
      ypos = cy2_top
      for i = 0,nlines-1 do begin
         xyouts,cx2_start,ypos,col2[i],/normal,color = (*self.color_ptr).black, $
            charsize = chsize
         ypos = ypos-dely
      endfor
   endif
endif


; Plot the legend using mylegend.pro
if n gt 1 then begin
    ii = n_elements(sym_str.color)
    iis = n_elements(sym_str.shape)
    iif = n_elements(sym_str.fill)

   for i = 0,n-1 do begin
      if i eq 0 then this_shape = sym_str.shape[i] else $
         this_shape = [this_shape,sym_str.shape[i mod iis]]
      if i eq 0 then this_fill = sym_str.fill[i] else $
         this_fill = [this_fill,sym_str.fill[i mod iif]]
      if i eq 0 then this_sym = convert_symbol(sym_str.shape[i],this_fill[i]) else $
         this_sym = [this_sym,convert_symbol(sym_str.shape[i mod iis],this_fill[i])]
      if i eq 0 then this_color = sym_str.color[i] else $
         this_color = [this_color,sym_str.color[i mod ii]]
   endfor

   titles = plot_str.title
   shape = this_shape ;sym_str.shape[0:n-1] ; RTA - remove limitation on nos of files displayed simultaneously 
   fill = this_fill ;sym_str.fill[0:n-1]

   mylegend,(*self.legend_ptr).xpos,(*self.legend_ptr).ypos, titles,   $
            color = this_color,                    $
            psym = this_sym,                       $
            background = (*self.color_ptr).white,  $
            shape = shape,                         $
            fill = fill,                           $
            charsize = (*self.legend_ptr).charsize
endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::sel_display,event,IMAGE = image, $
   _Extra = extra
if keyword_set(image) then begin
   loadct,15,/silent
   ret = self->display_image(event,_Extra = extra)
   device,decomposed = self.dave_dc
endif else begin
   tvlct,(*self.dtas_color_ptr).r,(*self.dtas_color_ptr).g,(*self.dtas_color_ptr).b
   ret = self->display(event,/reverse_colors,_Extra = extra)
endelse
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::get_plot_information,event
; Get all of the plot information
plot_info = dtas_get_plot_info(group_leader = event.top, $
   choices = self.plot_choices)
self.plot_choices = [plot_info.(0),plot_info.(1),plot_info.(2)]
if total(self.plot_choices) eq 0 then return,0

if self.plot_choices[0] eq 1 then begin
   pheader = (*self.plot_info).pheader
   for j = 0,n_elements(pheader)-1 do begin
      header = *pheader[j]
      for k = 0,n_elements(header)-1 do begin
         if k eq 0 then begin
            column_one = header[k]
         endif else begin
            column_one = [column_one,header[k]]
         endelse
      endfor
   endfor
endif
ncol = n_elements(column_one)
if ncol gt 0 then column_one = [column_one,'==========']
if self.plot_choices[1] eq 1 then begin
   if ncol gt 0 then begin
      column_one = [column_one,'Files']
   endif else begin
      column_one = 'Files'
   endelse
   ncol = n_elements(column_one)
   files = (*self.plot_info).files
   for i = 0,n_elements(files)-1 do begin
      if ncol gt 0 then begin
         column_one = [column_one,files[i]]
      endif else begin
         for i = 0,n_elements(files)-1 do begin
            if i eq 0 then $
               column_one = files[i] else $
               column_one = [column_one,files[i]]
         endfor
      endelse
      ncol = n_elements(column_one)
   endfor
endif

if self.plot_choices[2] eq 1 then begin
   column_two = 'Data treatment'
   ptreatment = (*self.plot_info).ptreatment
   for j = 0,n_elements(ptreatment)-1 do begin
      treatment = *ptreatment[j]
      for k = 0,n_elements(treatment)-1 do begin
         column_two = [column_two,treatment[k]]
      endfor
   endfor
endif
nc1 = n_elements(column_one)
nc2 = n_elements(column_two)

if (nc1 eq 0) and (nc2 eq 0) then return,0
if (nc1 eq 0) and (nc2 ne 0) then return,{column_two:column_two}
if (nc1 ne 0) and (nc2 eq 0) then return,{column_one:column_one}
if (nc1 ne 0) and (nc2 ne 0) then return,{column_one:column_one,column_two:column_two}
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::print_to_ps,event
; Are there any file selected?
if n_elements(*self.plot_info) eq 0 then return,0
plot_result = self->get_plot_information(event)
filename = 'tas_plot.ps'
xsize = self.psxsize & ysize = self.psysize
if size(plot_result,/tname) eq 'STRUCT' then begin
   keywords =  PSConfig(Cancel=cancelled,group_leader = event.top,$
               filename = filename,color = 1, $
               directory = self.data_dir,xsize = xsize,ysize = ysize,xoff = self.psxoff,yoff = self.psyoff)
endif else begin
   keywords =  PSConfig(Cancel=cancelled,group_leader = event.top,$
               filename = filename,color = 1, $
               directory = self.data_dir)
endelse
IF cancelled then return,0
self.psxsize = keywords.xsize
self.psysize = keywords.ysize
self.psxoff = keywords.xoffset
self.psyoff = keywords.yoffset
thisDevice = !D.Name
Set_Plot, 'PS'
Device, _Extra=keywords
ret = self->sel_display(event,IMAGE = self.image,PLOT_INFO = plot_result,  $
   _Extra = extra)
Device, /Close_File
Set_Plot, thisDevice
device,decomposed = self.dave_dc
tvlct,(*self.dave_color_ptr).r,(*self.dave_color_ptr).g,(*self.dave_color_ptr).b
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::save_as_jpeg,event
; Are there any file selected?
if n_elements(*self.plot_info) eq 0 then return,0

sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel lt 1 then return,0
widget_control,sel_id[0],get_uvalue = o
o = o.data_object
ret = o->get_property(display_name = name)
per_pos = strpos(name,'.')
filename = strmid(name,0,per_pos)+'.jpg'
plot_result = self->get_plot_information(event)
if size(plot_result,/tname) eq 'STRUCT' then begin
;   filename = 'tas_plot.jpg'
   ; create a pixmap...
   xsize = 800
   this_window = !d.window
   window,/free,/pixmap,xsize = xsize,ysize = fix((11.0*xsize/8.5))
   tv_pix = !d.window
   wset,tv_pix
   ret = self->sel_display(event,IMAGE = self.image,PLOT_INFO = plot_result,  $
                           _Extra = extra)
   ; ...read from it...
   image = TVREAD()
   file =   dialog_pickfile(dialog_parent = event.top,path = self.data_dir, $
            /write,filter = '*.jpg',file = filename)
   if file ne '' then begin
      write_jpeg,file,image,quality = 100,true = 1
   endif
   ; ...and destroy it.
   wdelete,tv_pix
   wset,this_window
endif else begin
   filename = 'tas_plot.jpg'
   image = TVREAD()
   file =   dialog_pickfile(dialog_parent = event.top,path = self.data_dir, $
            /write,filter = '*.jpg',file = filename)
   if file ne '' then begin
      write_jpeg,file,image,quality = 100,true = 1
   endif
endelse
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::save_as_png,event
; Are there any file selected?
if n_elements(*self.plot_info) eq 0 then return,0

sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel lt 1 then return,0
widget_control,sel_id[0],get_uvalue = o
o = o.data_object
ret = o->get_property(display_name = name)
per_pos = strpos(name,'.')
filename = strmid(name,0,per_pos)+'.png'

plot_result = self->get_plot_information(event)
if size(plot_result,/tname) eq 'STRUCT' then begin
   ; create a pixmap...
   xsize = 800
   this_window = !d.window
   window,/free,/pixmap,xsize = xsize,ysize = fix((11.0*xsize/8.5))
   tv_pix = !d.window
   wset,tv_pix
   ret = self->sel_display(event,IMAGE = self.image,PLOT_INFO = plot_result,  $
                           _Extra = extra)
   ; ...read from it...
   image = TVREAD()
   ; ...and destroy it.
   wdelete,tv_pix
   wset,this_window
endif else begin
   image = TVREAD()
endelse
file =   dialog_pickfile(dialog_parent = event.top,path = self.data_dir, $
         /write,filter = '*.png',file = filename)
if file ne '' then begin
   write_png, file, image
endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::refresh,event,IMAGE = image,XCOLOR = xcolor, $
   _Extra = extra
if keyword_set(image) then begin
   if not keyword_set(xcolor) then begin
      device,decomposed = 0
      loadct,15,/silent
   endif
   wset,self.winpix
   ret = self->display_image(event,_Extra = extra)
   wset,self.winvis
   device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.winpix]
   device,decomposed = self.dave_dc
   tvlct,(*self.dave_color_ptr).r,(*self.dave_color_ptr).g,(*self.dave_color_ptr).b
   empty
endif else begin
   device,decomposed = self.dtas_dc
   tvlct,(*self.dtas_color_ptr).r,(*self.dtas_color_ptr).g,(*self.dtas_color_ptr).b
   wset,self.winpix
   ret = self->display(event,_Extra = extra)
   wset,self.winvis
   device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.winpix]
   device,decomposed = self.dave_dc
   tvlct,(*self.dave_color_ptr).r,(*self.dave_color_ptr).g,(*self.dave_color_ptr).b
   empty
endelse

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::resize,event
;tree_base_id = widget_info(event.top,find_by_uname = 'TREE_BASE')
;tree_geom = widget_info(tree_base_id,/geometry)
;newxsize = (event.x-tree_geom.xsize) > 300
;newysize = event.y
;wdelete,self.winpix
;window,/free,/pixmap,xsize = newxsize,ysize = newysize
;widget_control,self.win,draw_xsize = newxsize,draw_ysize = newysize
;widget_control,tree_base_id,ysize = event.y

tree_geom = widget_info(self.file_tree,/geometry)
tlb_geom = widget_info(self.tlb,/geometry)
tree_base_id = widget_info(self.tlb,find_by_uname = 'TREE_BASE')
status_id = widget_info(self.tlb,find_by_uname = 'STATUS_TEXT')
status_geom = widget_info(status_id,/geometry)
if widget_info(self.file_info_id,/valid_id) then $
   file_info_geom = widget_info(self.file_info_id,/geometry)
tree_base_geom = widget_info(tree_base_id,/geometry)

newxsize = (event.x-tree_geom.scr_xsize) > 300
if n_elements(file_info_geom) ne 0 then begin
   newysize = (event.y-status_geom.scr_ysize-file_info_geom.scr_ysize) > 300
endif else begin
   newysize = (event.y-status_geom.scr_ysize) > 300
endelse
wdelete,self.winpix
window,/free,/pixmap,xsize = newxsize,ysize = newysize
widget_control,self.win,draw_xsize = newxsize,draw_ysize = newysize
widget_control,self.file_tree,scr_xsize = tree_geom.scr_xsize,scr_ysize = newysize

ret = self->refresh(event,IMAGE = self.image)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dtas_reduction_gui_cleanup,tlb
widget_control,tlb,get_uvalue = self
if obj_valid(self) then begin
   s = size(self->get_notify_ids())
   if s[0] ne 0 then begin
      n = self->get_notify_ids()
      tas_info = {   DTAS_EVENT,                         $
                     id:(self->get_notify_ids())[0],     $
                     top:(self->get_notify_ids())[1],    $
                     handler:0L                          }
   endif
   if widget_info(n[0],/valid_id) then begin
      widget_control,n[0],send_event = tas_info
   endif
endif
obj_destroy,self
help,/heap,/brief
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::quit,event
widget_control,event.top,/destroy
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::update_plot_info,ids
sel_id = ids
n = n_elements(sel_id)
;if n gt 54 then return,0 ;!! RTA - 2/12/07 remove limitation
if size(ids[0],/tname) ne 'OBJREF' then begin
   for i = 0,n-1 do begin
      uname = widget_info(sel_id[i],/uname)
      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
         (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') then begin
         widget_control,sel_id[i],get_uvalue = uval
         o = uval.data_object
         if n_elements(oarray) eq 0 then oarray = o else oarray = [oarray,o]
      endif
   endfor
   n = n_elements(oarray)
   if n_elements(oarray) eq 0 then return,0
endif else begin
   oarray = ids
   n = n_elements(oarray)
endelse

; Check if the independent variable TITLE is the same
for i = 0,n-1 do begin
   ret = oarray[i]->get_property(plot_str = plot_str,fit_ptr = fit_ptr, $
      display_name = display_name,scan = this_scan)
   if i eq 0 then begin
      xtitle = plot_str.xtitle
      ytitle = plot_str.ytitle
      title = display_name
      scan = this_scan
      anaMode = plot_str.anaMode
      show_TD = (plot_str.anaMode gt 0)? plot_str.show_TD : 0
   endif else begin
      xtitle = [xtitle,plot_str.xtitle]
      ytitle = [ytitle,plot_str.ytitle]
      title = [title,display_name]
      scan = [scan,this_scan]
      anaMode = [anaMode,plot_str.anaMode]
   endelse
endfor

if n_elements(uniq(xtitle)) ne 1 then return,0
if n_elements(uniq(ytitle)) ne 1 then ytitle = 'Various Y units' else $
   ytitle = ytitle[0]

; Now update the self.plot_info....
if n_elements(*self.plot_info) ne 0 then begin
   ptr_free,(*self.plot_info).px
   ptr_free,(*self.plot_info).py
   ptr_free,(*self.plot_info).pdy
   ptr_free,(*self.plot_info).pmon
   ptr_free,(*self.plot_info).pTDy
   if ptr_valid((*self.plot_info).pheader[0]) then $
      ptr_free,(*self.plot_info).pheader
   if ptr_valid((*self.plot_info).ptreatment[0]) then $
      ptr_free,(*self.plot_info).ptreatment
endif

px = ptrarr(n,/allocate_heap)
py = ptrarr(n,/allocate_heap)
pdy = ptrarr(n,/allocate_heap)
pTDy = ptrarr(n,/allocate_heap)
pheader = ptrarr(n,/allocate_heap)
ptreatment = ptrarr(n,/allocate_heap)
pmon = ptrarr(n,/allocate_heap)

files = strarr(n)
for i = 0,n-1 do begin
   ret = oarray[i]->get_property(plot_str = plot_str,header = header,   $
      filename = filename,treatment = treatment)
   mon = oarray[i]->get_monitor()
   *pmon[i] = mon
   *px[i] = *plot_str.x
   *py[i] = *plot_str.y
   *pdy[i] = *plot_str.dy
   if (anaMode[0] gt 0) then *pTDy[i] = *plot_str.TDy
   *pheader[i] = header
   *ptreatment[i] = treatment
   files[i] = dtas_get_filename(filename)
endfor
if ptr_valid(fit_ptr) then begin
*self.plot_info = {  px:px,                     $
                     py:py,                     $
                     pdy:pdy,                   $
                     pmon:pmon,                 $
                     pTDy:pTDy, $ ; Door Det data for new analyzer package
                     anaMode:anaMode, $ ; analyzer mode
                     show_TD:show_TD, $
                     xtitle:plot_str.xtitle,    $
                     title:title,               $
                     fit_ptr:fit_ptr,           $
                     pheader:pheader,           $
                     ptreatment:ptreatment,     $
                     files:files,               $
                     scan:scan,                 $
                     ytitle:ytitle              }
endif else begin
*self.plot_info = {  px:px,                     $
                     pmon:pmon,                 $
                     py:py,                     $
                     pdy:pdy,                   $
                     pTDy:pTDy, $ ; Door Det data for new analyzer package
                     anaMode:anaMode, $ ; analyzer mode
                     show_TD:show_TD, $
                     xtitle:plot_str.xtitle,    $
                     title:title,               $
                     pheader:pheader,           $
                     ptreatment:ptreatment,     $
                     files:files,               $
                     scan:scan,                 $
                     ytitle:ytitle              }
endelse
return,0
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::select_data,event
widget_control,event.id,get_uvalue = uval
uname = widget_info(event.id,/uname)
sel_id = widget_info(self.file_tree,/tree_select)
; Is this an image file?
widget_control,sel_id[0],get_uvalue = uval
tags = tag_names(uval)
where_image = where(tags eq 'IMAGE_OBJECT',count_images)
if count_images gt 0 then begin
   widget_control,self.win,draw_button_events = 0,draw_motion_events = 0
   self.image = 1B
   ret = self->refresh(event,IMAGE = self.image)
endif else begin
;   if n_elements(sel_id) lt 55 then begin ;!! RTA - 2/12/07 remove limitation
      widget_control,self.win,/draw_button_events,/draw_motion_events
      ret = self->update_plot_info(sel_id)
      self.image = 0B
      ret = self->refresh(event,IMAGE = self.image)
      ret = self->tas_show_single_file_contents(event)
 ;  endif
endelse
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::do_nothing,event
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::reduce_data,event
; Which folder has been selected?
file_tree = self.file_tree
sel_id = widget_info(file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
if not widget_info(sel_id,/valid_id) then return,0
uname = widget_info(sel_id,/uname)
if uname ne 'REDUCTION_GROUP_FOLDER' then return,0
red_id = sel_id
widget_control,red_id,get_uvalue = uval
if not obj_valid(uval.tas_object) then begin
   strout = 'No files have been loaded yet'
   void = dialog_message(dialog_parent = event.top,strout,/information, $
      title = 'TAS Reduction Error')
   return,0
endif
ret = self->update_status('Reducing data')
tas_data = uval.tas_object
; Get the reduction preferences
prefs = *self.prefs_ptr
ret = tas_data->check_contents()
ro  = tas_data->reduce( sum_signal = prefs.sum_signal,$
                        sum_bg = prefs.sum_bg,$
                        straight_add = 1,$
                        detailed_balance = prefs.det_bal,$
                        resolution_correction = prefs.res_cor,$
                        monitor_correction = prefs.mon_cor,$
                        normalize_to_monitor = prefs.mon_norm,$
                        normalize_to_time = prefs.time_norm, $
                        fbg_set = prefs.fbg,$
                        fast_background = prefs.fbg_val,$
                        intermediate = prefs.save_int,$
                        subtraction = prefs.diff,$
                        display = 0,$
                        interp = prefs.interp,  $
                        sf_set = prefs.scale,   $
                        scale_factor = prefs.scale_val,msg = msg)

if not obj_valid(ro[0]) then begin
   void = dialog_message(dialog_parent = event.top,msg,title = 'TAS Reduction Error')
   return,0
endif

if prefs.save_int eq 1 then begin
   ; Fill up the INTERMEDIATE folder
   int_id = widget_info(red_id,find_by_uname = 'INTERMEDIATE_DATA_FOLDER')
   ; Kill everything in this folder first....
   widget_control,file_tree,set_tree_select = 0
   widget_control,int_id,set_tree_select = 1
   ; Select the INTERMEDIATE_DATA_FOLDER
   ret = self->tas_delete_all_folder_files()


   ret = tas_data->get_property(intermediate = int_container)
   n_int = int_container->count()
   if n_int gt 0 then begin
      int_all = int_container->get(/all)
      for i = 0,n_elements(int_all)-1 do begin
         if obj_valid(int_all[i]) then begin
         ret = int_all[i]->get_property(display_name = display_name)
         data_leaf = widget_tree(int_id,value = display_name,        $
                     uname = 'INTERMEDIATE_FILE',                    $
                     bitmap = *self.file_icon,                       $
                     uvalue = {  object:self,                        $
                                 method:'select_data',               $
                                 data_object:int_all[i]              })
         endif
      endfor
   endif
endif

no = n_elements(ro)
red_object = ro[no-1]
oarray = ro
; Now create the new data leaves in the REDUCED_GROUP
reduced_id = widget_info(red_id,find_by_uname = 'REDUCED_DATA_FOLDER')
; Kill everything in this folder first....
widget_control,file_tree,set_tree_select = 0
widget_control,reduced_id,set_tree_select = 1
; Select the REDUCED_DATA_FOLDER
ret = self->tas_delete_all_folder_files()
for i = 0,no-1 do begin

   ret = oarray[i]->get_property(display_name = display_name)
   data_leaf = widget_tree(reduced_id,value = display_name,    $
               uname = 'REDUCED_FILE',                         $
               bitmap = *self.file_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           data_object:oarray[i]               })
endfor
ret = self->update_status('Reduction complete')
return,1
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::isNG5aplus, filename
; Determine if this is an SPINS data file with PSD used in a+ mode
; where pixels are integrated in the vertical direction.

;begin error handler------------------------------------------------------------
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'Error encountered in dtas_reduction_gui::isNG5aplus()'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle)
        catch, /cancel
        return, obj_new()
    endif
endif
;end error handler-------------------------------------------------------------

openr, lun,filename,/get_lun
buffer = strarr(12)
readf, lun, buffer
free_lun,lun,/force

; Is there a '#ASD' entry on line twelve? If so, this is a+ mode SPINS
; data file
return, strcmp(strmid(strtrim(buffer[11],2),0,4),'#ASD')

end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::load_NG5aPlus, event,file, dataType
; Load data from NG5 (SPINS) file - PSD used in a+ mode with
;                                   integration along vertical direction
; For each data file, there will be two datasets (objects)
; created. The first is a standard ICP file data with intensity
; (integrated) vs scan variable. The socond is 2D image data with
; pixels and scan variable as the two dimensions.

;begin error handler------------------------------------------------------------
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'Error encountered in dtas_reduction_gui::load_asd()'
        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, obj_new()
    endif
endif
;end error handler-------------------------------------------------------------

nlines = file_lines(file)
dstring = strarr(nlines)
openr,lun,file,/get_lun
readf,lun,dstring
free_lun,lun,/force















reads,dstring,nx,ny,data

for j=0,nd-1 do begin
    oData = obj_new('dtas_zip')
    err = data[*,*,j]
    ind = where(err le 0,cnt)
    if (cnt gt 0) then err[ind] = 1
    err = sqrt(err)
    display_name = (nd eq 1)?  file_basename(file) : file_basename(file)+'-'+strtrim(string(j),2)
    ret = oData->set_property(xval = findgen(nx) $
                              ,yval = findgen(ny) $
                              ,z = data[*,*,j] $
                              ,dz = err $
                              ,xtitle = 'Pixel number' $
                              ,display_name = display_name $
                              ,treatment = file $
                              ,ytitle = 'Pixel number' $
                             )
    if (obj_valid(oData)) then $
      retVal = (n_elements(retVal) gt 0)? [retVal,oData] : oData
endfor

return, (n_elements(retVal) gt 0)? retVal : obj_new()

end




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::load_asd, event,files

;begin error handler------------------------------------------------------------
if (n_elements(!debug) && (!debug eq 0)) then begin
    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'Error encountered in dtas_reduction_gui::load_asd()'
        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, obj_new()
    endif
endif
;end error handler-------------------------------------------------------------

nfiles = n_elements(files)
for i=0,nFiles-1 do begin
    file = files[i]
    nlines = file_lines(file)
    dstring = strarr(nlines)
    openr,lun,file,/get_lun
    readf,lun,dstring
    free_lun,lun,/force

    toks = strsplit(dstring[0],' ',/extract,count=ntoks)
    if (ntoks ne 2) then begin
        void = dialog_message([filename,'does not appear to be an ASD format file'])
        continue
    endif
    nx = fix(toks[0])
    ny = fix(toks[1])
    nd = fix((nlines*39.0)/(1.0*nx*ny) + 0.25) ; nos of data points

    data = (nd eq 1)? fltarr(nx,ny) : fltarr(nx,ny,nd)
    
    reads,dstring,nx,ny,data

   ; locate COMBINED DATA folder widget id in tree widget
    ;red_id = widget_info(widget_info(sel_id[0],/parent),/parent)
;   comb_id = widget_info(event.top,find_by_uname = 'SIGNAL_DATA_FOLDER')

    for j=0,nd-1 do begin
        oData = obj_new('dtas_zip')
        err = data[*,*,j]
        ind = where(err le 0,cnt)
        if (cnt gt 0) then err[ind] = 1
        err = sqrt(err)
        display_name = (nd eq 1)?  file_basename(file) : file_basename(file)+'-'+strtrim(string(j),2)
        ret = oData->set_property(xval = findgen(nx) $
                              ,yval = findgen(ny) $
                              ,z = data[*,*,j] $
                              ,dz = err $
                              ,xtitle = 'Pixel number' $
                              ,display_name = display_name $
                              ,treatment = file $
                              ,ytitle = 'Pixel number' $
                             )
;        self.tas_container->add,oData
;
;
;        comb_leaf = widget_tree(comb_id,value = display_name $
;                                ,uname = 'COMBINED_FILE' $
;                                ,bitmap = *self.image_icon $
;                                ,uvalue = {object:self,method:'select_data',image_object:oData} $
;                               )   
        if (obj_valid(oData)) then $
          retVal = (n_elements(retVal) gt 0)? [retVal,oData] : oData
    endfor

endfor
;self.data_dir = file_dirname(files[0])
return, (n_elements(retVal) gt 0)? retVal : obj_new()

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::load_signal_files,event
; Pop up the file browser and allow the user to select a file
file_tree = self.file_tree
filter = self.filter

files = rmd_pickfile(group_leader = event.top,path = self.data_dir,     $
         title = 'TAS data selection',/multiple,get_path = this_path,   $
         filter_in = filter,filter_out = filter_out)



;files = dialog_pickfile(dialog_parent = event.top,path = self.data_dir,    $
;   title = 'TAS data selection',/multiple_files, get_path = this_path,  $
;   display_name = 'Select one or more TAS "signal" files to load',filter = self.filter);, index_out = this)
;help,this
;print,this

if files[0] eq '' then return,0
self.filter = filter_out
str = 'Loading signal files in...'
ret = self->update_status(str)

nfiles = n_elements(files)
files = files[sort(files)]
;oarray = objarr(nfiles)
;unames = strarr(nfiles)
obj_increment = 0
nAsdFiles = 0
for i = 0,nfiles-1 do begin
   ; Fudge to provide support for SPINS image (.asd) files.
   ; Store image files in an array and deal with them later
   ppos = strpos(files[i],'.',/reverse_search)
   extension = strmid(files[i],ppos+1)
   if (strupcase(extension) eq 'ASD') then begin
       asdFiles = (n_elements(asdFiles) eq 0)? files[i] : [asdFiles,files[i]]
       nAsdFiles++
       continue
   endif

   ; Create the TAS data objects and read them in
    o =  obj_new('dtas_data',filename = files[i],signal_type = 'SIGNAL',/read)
   if obj_valid(o) then begin
      oarray = (n_elements(oarray) gt 0)? [oarray,o] : o
      dataType = (n_elements(dataType) gt 0)? [dataType,'1D'] : '1D'
      obj_increment = obj_increment + 1
   endif
endfor
if (nAsdFiles gt 0) then begin
    oAsdData = self->load_asd(event,asdFiles)
    ;void = dialog_message('Image files are loaded in the Combined Data folder',/info,dialog_parent=event.top)
    if (obj_valid(oAsdData[0])) then begin
        nAsd = n_elements(oAsdData)
        oarray = (n_elements(oarray) gt 0)? [oarray,oAsdData] : oAsdData
        dataType = (n_elements(dataType) gt 0)? [dataType,strarr(nAsd)+'2D'] : strarr(nAsd)+'2D'
        obj_increment = n_elements(oarray)
        ;if (obj_increment lt 1) then return, 0 ; exit if no other files to be loaded
    endif
endif

if (obj_increment lt 1) then begin
   str = 'File loading failure'
   ret = self->update_status(str)
   return,0
endif

nfiles = obj_increment

self.data_dir = this_path

; Is there a REDUCTION GROUP folder selected?
this_id = widget_info(file_tree,/tree_select)
if n_elements(this_id) gt 1 then begin
   obj_destroy,oarray
   str = 'File loading failure'
   ret = self->update_status(str)
   return,0
endif

red_id=0L
if not widget_info(this_id,/valid_id) then begin
; Find the first reduction group id
   red_id = widget_info(file_tree,find_by_uname = 'REDUCTION_GROUP_FOLDER')
   widget_control,red_id,/set_tree_select
endif else begin
   uname = widget_info(this_id,/uname)
   if (uname eq 'SIGNAL_DATA_FOLDER') or (uname eq 'EMPTY_DATA_FOLDER') or $
      (uname eq 'INTERMEDIATE_DATA_FOLDER') or (uname eq 'REDUCED_DATA_FOLDER') or $
      (uname eq 'SIGNAL_FILE') or (uname eq 'COMBINED_FILE') or (uname eq 'EMPTY_FILE') or $
      (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') $
      then begin
         widget_control,this_id,get_uvalue = uval
         red_id = uval.parent
   endif
   if (uname eq 'REDUCTION_GROUP_FOLDER') then red_id = this_id
endelse
if (~widget_info(red_id,/valid)) then begin
    msg = 'Please select the Signal Data folder before launching load file'
    void = dialog_message(msg,dialog_parent=event.top)
    obj_destroy,oarray
    ret = self->update_status(msg)
    return, 0
endif

widget_control,red_id,get_uvalue = uval
if obj_valid(uval.tas_object) then begin
   ret = uval.tas_object->add(oarray)
   tas_data = uval.tas_object
endif else begin
   tas_data = obj_new('dtas_reduce',oarray)
   uval.tas_object = tas_data
endelse
widget_control,red_id,set_uvalue = uval
self.tas_container->add,tas_data
; Now create the data "leaves" and stuff a reference to the data object
; into the file
for i=0,nfiles-1 do begin
   ret = oarray[i]->get_property(display_name = display_name)
   signal_id = widget_info(red_id,find_by_uname = 'SIGNAL_DATA_FOLDER')
   data_leaf = widget_tree(signal_id,value = display_name,     $
                           uname = (dataType[i] eq '1D')? 'SIGNAL_FILE' : 'COMBINED_FILE', $
                           bitmap = (dataType[i] eq '1D')? *self.file_icon : *self.image_icon, $
                           uvalue = (dataType[i] eq '1D')? $
                           {object:self,method:'select_data',data_object:oarray[i],parent:red_id} : $
                           {object:self,method:'select_data',image_object:oarray[i],parent:red_id} $
                          )
endfor
str = 'Signal files loaded'
ret = self->update_status(str)
str = 'Zooming->Hold down left mouse button, drag rubberband box, '+ $
      'and release button. Autoscale->Press right mouse button'
ret = self->update_status(str)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::load_example_file,event
; Pop up the file browser and allow the user to select a file
file_tree = self.file_tree
files = !DAVE_AUXILIARY_DIR+'lacam025.bt9'
;if file_which('lacam025.bt9') eq '' then begin
;  files = 'lacam025.bt9'
;endif else begin
;  files = file_which('lacam025.bt9')
;endelse
if files[0] eq '' then return,0
nfiles = n_elements(files)
files = files[sort(files)]
oarray = objarr(nfiles)
for i = 0,nfiles-1 do begin
   ; Create the TAS data objects and read them in
   oarray[i] = obj_new('dtas_data',filename = files[i],signal_type = 'SIGNAL',/read)
endfor

; Is there a REDUCTION GROUP folder selected?
this_id = widget_info(file_tree,/tree_select)
if n_elements(this_id) gt 1 then begin
   obj_destroy,oarray
   return,0
endif

if not widget_info(this_id,/valid_id) then begin
; Find the first reduction group id
   red_id = widget_info(file_tree,find_by_uname = 'REDUCTION_GROUP_FOLDER')
   widget_control,red_id,/set_tree_select
endif else begin
   uname = widget_info(this_id,/uname)
   if (uname eq 'SIGNAL_DATA_FOLDER') or (uname eq 'EMPTY_DATA_FOLDER') or $
      (uname eq 'INTERMEDIATE_DATA_FOLDER') or (uname eq 'REDUCED_DATA_FOLDER') or $
      (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
      (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') or $
      (uname eq 'COMBINED_DATA_FOLDER') or (uname eq 'COMBINED_FILE') then begin
         widget_control,this_id,get_uvalue = uval
         red_id = uval.parent
   endif
   if (uname eq 'REDUCTION_GROUP_FOLDER') then red_id = this_id
endelse

widget_control,red_id,get_uvalue = uval
if obj_valid(uval.tas_object) then begin
   ret = uval.tas_object->add(oarray)
   tas_data = uval.tas_object
endif else begin
   tas_data = obj_new('dtas_reduce',oarray)
   uval.tas_object = tas_data
endelse
widget_control,red_id,set_uvalue = uval
self.tas_container->add,tas_data
; Now create the data "leaves" and stuff a reference to the data object
; into the file
for i=0,nfiles-1 do begin
   ret = oarray[i]->get_property(display_name = display_name)
   signal_id = widget_info(red_id,find_by_uname = 'SIGNAL_DATA_FOLDER')
   data_leaf = widget_tree(signal_id,value = display_name,     $
               uname = 'SIGNAL_FILE',                          $
               bitmap = *self.file_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           data_object:oarray[i],              $
                           parent:red_id                       })
endfor
         str = 'Zooming->Hold down left mouse button, drag rubberband box, '+ $
               'and release button. Autoscale->Press right mouse button'
         ret = self->update_status(str)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::load_empty_files,event
; Pop up the file browser and allow the user to select a file
file_tree = self.file_tree
;files = dialog_pickfile(dialog_parent = event.top,path = self.data_dir,    $
;   title = 'TAS data selection',/multiple_files, get_path = this_path,  $
;   display_name = 'Select one or more TAS "background" files to load')
filter = self.filter
files = rmd_pickfile(group_leader = event.top,path = self.data_dir,     $
         title = 'TAS data selection',/multiple,get_path = this_path,   $
         filter_in = filter,filter_out = filter_out)

if files[0] eq '' then return,0
self.filter = filter_out
str = 'Loading background files'
ret = self->update_status(str)
nfiles = n_elements(files)
files = files[sort(files)]
oarray = objarr(nfiles)
for i = 0,nfiles-1 do begin
   ; Create the TAS data objects and read them in
   oarray[i] = obj_new('dtas_data',filename = files[i],signal_type = 'EMPTY',/read)
endfor

; Is there a REDUCTION GROUP folder selected?
this_id = widget_info(file_tree,/tree_select)
if n_elements(this_id) gt 1 then begin
   str = 'File loading failure'
   ret = self->update_status(str)
   obj_destroy,oarray
   return,0
endif
self.data_dir = this_path
if not widget_info(this_id,/valid_id) then begin
; Find the first reduction group id
   red_id = widget_info(file_tree,find_by_uname = 'REDUCTION_GROUP_FOLDER')
   widget_control,red_id,/set_tree_select
endif else begin
   uname = widget_info(this_id,/uname)
   if (uname eq 'SIGNAL_DATA_FOLDER') or (uname eq 'EMPTY_DATA_FOLDER') or $
      (uname eq 'INTERMEDIATE_DATA_FOLDER') or (uname eq 'REDUCED_DATA_FOLDER') or $
      (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
      (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') $
      then begin
         widget_control,this_id,get_uvalue = uval
         red_id = uval.parent
   endif
   if (uname eq 'REDUCTION_GROUP_FOLDER') then red_id = this_id
endelse

widget_control,red_id,get_uvalue = uval
if obj_valid(uval.tas_object) then begin
   ret = uval.tas_object->add(oarray)
   tas_data = uval.tas_object
endif else begin
   tas_data = obj_new('dtas_reduce',oarray)
   uval.tas_object = tas_data
endelse
widget_control,red_id,set_uvalue = uval
self.tas_container->add,tas_data
; Now create the data "leaves" and stuff a reference to the data object
; into the file
for i=0,nfiles-1 do begin
   ret = oarray[i]->get_property(display_name = display_name)
   empty_id = widget_info(red_id,find_by_uname = 'EMPTY_DATA_FOLDER')
   data_leaf = widget_tree(empty_id,value = display_name,     $
               uname = 'EMPTY_FILE',                           $
               bitmap = *self.file_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           data_object:oarray[i]               })
endfor
str = 'Background files loaded'
ret = self->update_status(str)
         str = 'Zooming->Hold down left mouse button, drag rubberband box, '+ $
               'and release button. Autoscale->Press right mouse button'
         ret = self->update_status(str)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::context_events,event
; Which child has been selected?
sel_id = widget_info(event.id,/tree_select)
n_sel = n_elements(sel_id)
if not widget_info(sel_id[0],/valid_id) then return,0
unames = strarr(n_sel)
for i = 0,n_sel-1 do unames[i] = widget_info(sel_id[i],/uname)
if n_elements(uniq(unames)) eq 1 then begin
   uname = unames[0]
   case uname of
   'REDUCTION_GROUP_FOLDER':   $
      begin
         context_base = widget_info(event.top,find_by_uname = 'REDUCTION_GROUP_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'SIGNAL_FILE':   $
      begin
         context_base = widget_info(event.top,find_by_uname = 'SIGNAL_DATA_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'EMPTY_FILE':   $
      begin
         context_base = widget_info(event.top,find_by_uname = 'EMPTY_DATA_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'SIGNAL_DATA_FOLDER': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'SIGNAL_FOLDER_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'EMPTY_DATA_FOLDER': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'EMPTY_FOLDER_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'COMBINED_DATA_FOLDER': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'COMBINED_FOLDER_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'INTERMEDIATE_DATA_FOLDER': $
      begin
         context_base = widget_info(event.top,find_by_uname =  $
            'INTERMEDIATE_FOLDER_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'REDUCED_DATA_FOLDER': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'REDUCED_FOLDER_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'INTERMEDIATE_FILE': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'INTERMEDIATE_DATA_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'REDUCED_FILE': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'REDUCED_DATA_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   'COMBINED_FILE': $
      begin
         context_base = widget_info(event.top,find_by_uname = 'COMBINED_DATA_MENU')
         widget_displaycontextmenu, event.id, event.x, event.y, context_base
      end
   else:
   endcase
endif else begin
; Now we want to display a context-sensitive menu that appears when multiple
; file tabs are selected from different folders.
   sel_names = unames[uniq(unames)]
   red_index = where(unames eq 'REDUCED_FILE',count_red)
   int_index = where(unames eq 'INTERMEDIATE_FILE',count_int)
   sig_index = where(unames eq 'SIGNAL_FILE',count_sig)
   bg_index = where(unames eq 'EMPTY_FILE',count_bg)
   tot_good_file_types = count_red+count_int+count_sig+count_bg
   if (tot_good_file_types eq 0) or $
      (tot_good_file_types lt n_elements(unames)) then return,0
   context_base = widget_info(event.top,find_by_uname = 'MULTIPLE_FILES_MENU')
   widget_displaycontextmenu, event.id, event.x, event.y, context_base
endelse
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_delete_files,event
; Which files were selected?
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
; Determine if any of the children of FILE_TREE were selected
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if not widget_info(sel_id[0],/valid_id) then return,0
uname = widget_info(sel_id[0],/uname)
if (uname eq 'SIGNAL_FILE') or   $
   (uname eq 'REDUCED_FILE') or  $
   (uname eq 'EMPTY_FILE') or (uname eq 'COMBINED_FILE') or $
   (uname eq 'INTERMEDIATE_FILE') then begin
   ; Now cycle through and remove the objects from the DTAS_REDUCE object
   red_id = widget_info(file_tree_id,find_by_uname = 'REDUCTION_GROUP_FOLDER')
   widget_control,red_id,get_uvalue = uval
   tas_object = uval.tas_object
   for i = 0,n_sel-1 do begin
      widget_control,sel_id[i],get_uvalue = uv_sel
      if uname eq 'COMBINED_FILE' then o = uv_sel.image_object else $
         o = uv_sel.data_object
      ret = tas_object->destroy_element(o)
      widget_control,sel_id[i],/destroy
   endfor
endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tas_launch_text_display,event,o,title = title,txt = txt,   $
   group_leader = group_leader
this_event = tag_names(event,/structure_name)
case this_event of
'WIDGET_BUTTON':  $
   begin
      tas_text_display, group_leader = group_leader,        $
                        notify_ids = [event.id,event.top],  $
                        o = o,                              $
                        title = title,                      $
                        txt = txt
   end
else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_show_treatment,event
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
; Determine if any of the children of FILE_TREE were selected
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
uname = widget_info(sel_id,/uname)
if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
   (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') or $
   (uname eq 'COMBINED_FILE') then begin
      widget_control,sel_id,get_uvalue = uval
      tags = tag_names(uval)
      where_image = where(tags eq 'IMAGE_OBJECT',count_image)
      where_data = where(tags eq 'DATA_OBJECT',count_data)
      if count_image gt 0 then o = uval.image_object else $
         o = uval.data_object
      ret = o->get_property(display_name = display_name,treatment = treatment)
      title = 'TAS Data Treatment: '+display_name
      tas_launch_text_display,event,group_leader = sel_id,o,title = title, $
         txt = treatment
endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_show_contents,event
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
; Determine if any of the children of FILE_TREE were selected
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
uname = widget_info(sel_id,/uname)
if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
   (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') then begin
      widget_control,sel_id,get_uvalue = uval
      o = uval.data_object
      ret = o->get_property(display_name = display_name,contents = contents)
      title = 'TAS Data Contents: '+display_name
      tas_launch_text_display,group_leader = sel_id,event,o,title = title, $
         txt = contents
endif

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_show_single_file_contents,event,show = show
if keyword_set(show) then show = 1B else show = 0B
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
; Determine if any of the children of FILE_TREE were selected
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
if ~widget_info(sel_id,/valid_id) then return,0
uname = widget_info(sel_id,/uname)
if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
   (uname eq 'REDUCED_FILE') or (uname eq 'INTERMEDIATE_FILE') then begin
      widget_control,sel_id,get_uvalue = uval
      o = uval.data_object
      ret = o->get_property(display_name = display_name,contents = contents)
      title = 'TAS Data Contents'
      structure_name = tag_names(event,/structure)
      if structure_name eq 'WIDGET_TREE_SEL' then begin
         if widget_info(self.file_info_id,/valid_id) then $
            widget_control,self.file_info_id,set_value = contents
      endif
      if show then begin
         widget_control,self.file_info_id,set_value = contents
      endif
endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_move_files_to_empty,event
; Which files were selected?
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
; Determine if any of the children of FILE_TREE were selected
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if not widget_info(sel_id[0],/valid_id) then return,0
uname = widget_info(sel_id[0],/uname)
if uname ne 'SIGNAL_FILE' then return,0
; Now cycle through and remove the objects from the DTAS_REDUCE object
signal_id = widget_info(sel_id[0],/parent)
red_id = widget_info(signal_id,/parent)
empty_id = widget_info(red_id,find_by_uname = 'EMPTY_DATA_FOLDER')
widget_control,red_id,get_uvalue = uval
tas_object = uval.tas_object
ret = tas_object->get_property(signal = signal_container,empty = empty_container)
nsignal = signal_container->count()
if nsignal eq 0 then return,0
osignal = signal_container->get(/all)
; ...and create new leaf widgets in the empty folder...
for i = 0,n_sel-1 do begin
   widget_control,sel_id[i],get_uvalue = uval
   o = uval.data_object
   widget_control,sel_id[i],/destroy
   signal_container->remove,o
   empty_container->add,o
   ret = o->get_property(display_name = display_name)
   ret = o->set_property(signal_type = 'EMPTY')
   data_leaf = widget_tree(empty_id,value = display_name,      $
               uname = 'EMPTY_FILE',                           $
               bitmap = *self.file_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           data_object:o                       })
endfor

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_move_files_to_signal,event
; Which files were selected?
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
; Determine if any of the children of FILE_TREE were selected
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if not widget_info(sel_id[0],/valid_id) then return,0
uname = widget_info(sel_id[0],/uname)
if uname ne 'EMPTY_FILE' then return,0
; Now cycle through and remove the objects from the DTAS_REDUCE object
empty_id = widget_info(sel_id[0],/parent)
red_id = widget_info(empty_id,/parent)
signal_id = widget_info(red_id,find_by_uname = 'SIGNAL_DATA_FOLDER')
widget_control,red_id,get_uvalue = uval
tas_object = uval.tas_object
ret = tas_object->get_property(signal = signal_container,empty = empty_container)
nsignal = signal_container->count()
nempty = empty_container->count()
if nempty eq 0 then return,0
; ...and create new leaf widgets in the empty folder...
for i = 0,n_sel-1 do begin
   widget_control,sel_id[i],get_uvalue = uval
   o = uval.data_object
   widget_control,sel_id[i],/destroy
   empty_container->remove,o
   signal_container->add,o
   ret = o->get_property(display_name = display_name)
   ret = o->set_property(signal_type = 'SIGNAL')
   data_leaf = widget_tree(signal_id,value = display_name,     $
               uname = 'SIGNAL_FILE',                          $
               bitmap = *self.file_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           data_object:o                       })
endfor

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::copy_data_folder,event
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
if not widget_info(sel_id,/valid_id) then return,0
uname = widget_info(sel_id,/uname)
if uname ne 'REDUCTION_GROUP_FOLDER' then return,0
widget_control,sel_id,get_uvalue = uval
tas_object = uval.tas_object

; Get the widget ids of each of the child folders
signal_id = widget_info(sel_id,find_by_uname = 'SIGNAL_DATA_FOLDER')
int_id = widget_info(sel_id,find_by_uname = 'INTERMEDIATE_DATA_FOLDER')
empty_id = widget_info(sel_id,find_by_uname = 'EMPTY_DATA_FOLDER')
reduced_id = widget_info(sel_id,find_by_uname = 'REDUCED_DATA_FOLDER')
signal_list = get_list_items(signal_id,IDS = sig_ids,unames = names)
int_list = get_list_items(int_id,IDS = int_ids,unames = names)
empty_list = get_list_items(empty_id,IDS = empty_ids,unames = names)
reduced_list = get_list_items(reduced_id,IDS = reduced_ids,unames = names)
if n_elements(sig_ids) ne 0 then begin
   for i = 0,n_elements(sig_ids)-1 do begin
      widget_control,sig_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,sig_ids[i],/destroy
   endfor
endif

if n_elements(int_ids) ne 0 then begin
   for i = 0,n_elements(int_ids)-1 do begin
      widget_control,int_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,int_ids[i],/destroy
   endfor
endif

if n_elements(empty_ids) ne 0 then begin
   for i = 0,n_elements(empty_ids)-1 do begin
      widget_control,empty_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,empty_ids[i],/destroy
   endfor
endif

if n_elements(reduced_ids) ne 0 then begin
   for i = 0,n_elements(reduced_ids)-1 do begin
      widget_control,reduced_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,reduced_ids[i],/destroy
   endfor
endif

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_delete_all,event
; This method deletes all of the files contained in a particular data group
; folder.
; Which folder was selected?
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
if not widget_info(sel_id,/valid_id) then return,0
uname = widget_info(sel_id,/uname)
if uname ne 'REDUCTION_GROUP_FOLDER' then return,0
widget_control,sel_id,get_uvalue = uval
tas_object = uval.tas_object

; Get the widget ids of each of the child folders
signal_id = widget_info(sel_id,find_by_uname = 'SIGNAL_DATA_FOLDER')
int_id = widget_info(sel_id,find_by_uname = 'INTERMEDIATE_DATA_FOLDER')
empty_id = widget_info(sel_id,find_by_uname = 'EMPTY_DATA_FOLDER')
reduced_id = widget_info(sel_id,find_by_uname = 'REDUCED_DATA_FOLDER')
signal_list = get_list_items(signal_id,IDS = sig_ids,unames = names)
int_list = get_list_items(int_id,IDS = int_ids,unames = names)
empty_list = get_list_items(empty_id,IDS = empty_ids,unames = names)
reduced_list = get_list_items(reduced_id,IDS = reduced_ids,unames = names)
if n_elements(sig_ids) ne 0 then begin
   for i = 0,n_elements(sig_ids)-1 do begin
      widget_control,sig_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,sig_ids[i],/destroy
   endfor
endif

if n_elements(int_ids) ne 0 then begin
   for i = 0,n_elements(int_ids)-1 do begin
      widget_control,int_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,int_ids[i],/destroy
   endfor
endif

if n_elements(empty_ids) ne 0 then begin
   for i = 0,n_elements(empty_ids)-1 do begin
      widget_control,empty_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,empty_ids[i],/destroy
   endfor
endif

if n_elements(reduced_ids) ne 0 then begin
   for i = 0,n_elements(reduced_ids)-1 do begin
      widget_control,reduced_ids[i],get_uvalue = uv_sel
      ret = tas_object->destroy_element(uv_sel.data_object)
      widget_control,reduced_ids[i],/destroy
   endfor
endif

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_delete_all_folder_files,event
; This method deletes all of the files contained in a particular signal, empty,
; intermediate, or reduced folder.
; Which folder was selected?
file_tree_id = self.file_tree
if not widget_info(file_tree_id,/valid_id) then return,0
sel_id = widget_info(file_tree_id,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
if not widget_info(sel_id,/valid_id) then return,0
uname = widget_info(sel_id,/uname)

if (uname eq 'EMPTY_DATA_FOLDER') or (uname eq 'SIGNAL_DATA_FOLDER') or $
   (uname eq 'INTERMEDIATE_DATA_FOLDER') or $
   (uname eq 'REDUCED_DATA_FOLDER') or (uname eq 'COMBINED_DATA_FOLDER') then begin
   list = get_list_items(sel_id,ids = ids,unames = unames)
   if n_elements(ids) eq 0 then return,0
   widget_control,sel_id,get_uval = uval
   red_id = uval.parent
   widget_control,red_id,get_uvalue = uvalue
   tas_object = uvalue.tas_object
   for i = 0,n_elements(ids)-1 do begin
      widget_control,ids[i],get_uvalue = uv_sel
      tags = tag_names(uv_sel)
      where_image_object = where(tags eq 'IMAGE_OBJECT',count_image)
      where_data_object = where(tags eq 'DATA_OBJECT',count_data)
      if count_data gt 0 then o = uv_sel.data_object
      if count_image gt 0 then o = uv_sel.image_object
      ret = tas_object->destroy_element(o)
      widget_control,ids[i],/destroy
   endfor
endif

return,1
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_change_ivar,event
this_event = tag_names(event,/structure_name)
register_name = 'change_ivar'
case this_event of
'WIDGET_BUTTON':  $
   begin
      title='Select Independent Variable'
      file_tree_id = self.file_tree
      if not widget_info(file_tree_id,/valid_id) then return,0
      sel_id = widget_info(file_tree_id,/tree_select)
      n_sel = n_elements(sel_id)
      if not widget_info(sel_id[0],/valid_id) then return,0
      uname = widget_info(sel_id[0],/uname)
      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
         (uname eq 'INTERMEDIATE_FILE') or (uname eq 'REDUCED_FILE') then begin
         ocontainer = obj_new('IDL_CONTAINER')
         for i = 0,n_sel-1 do begin
            widget_control,sel_id[i],get_uvalue = uval
            ocontainer->add,uval.data_object
         endfor
         dtas_change_ivar,ocontainer,group_leader = event.top,   $
            notify_ids = [event.id,event.top],register_name = register_name, $
            no_update = 0,num_elements = 15,title=title
      endif
      if uname eq 'REDUCTION_GROUP_FOLDER' then begin
         ; Get all of the DATA objects out and change em'
         list = get_list_items(sel_id[0],IDS = parent_ids,UNAMES = unames)
         ocontainer = obj_new('IDL_CONTAINER')
         for i = 0,n_elements(parent_ids)-1 do begin
            signal_list = get_list_items(parent_ids[i],IDS = child_ids)
            for j = 0,n_elements(child_ids)-1 do begin
               widget_control,child_ids[j],get_uvalue = uval
               ocontainer->add,uval.data_object
            endfor
         endfor
            dtas_change_ivar,ocontainer,group_leader = event.top,               $
               notify_ids = [event.id,event.top],register_name = register_name, $
               no_update = 1,num_elements = 15,title=title
      endif
   end
'DCI_EVENT':   $
   begin
      o = event.ocontainer
      n = o->count()
      oall = o->get(/all)
      for i = 0,n-1 do begin
         ret = oall[i]->get_property(var_names = var_names)
         new_choice = var_names[event.selection]
         ret = oall[i]->set_property(xvar_name = new_choice)
      endfor
      if not xregistered(register_name) then begin
         for i = 0,n-1 do o->remove,oall[i]
         obj_destroy,o
      endif
      sel_id = widget_info(self.file_tree,/tree_select)
      ret = self->update_plot_info(oall)
      if event.update eq 1 then ret = self->refresh(event)
   end
else:
endcase

return,1
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_change_var,event
this_event = tag_names(event,/structure_name)
register_name = 'change_var'
case this_event of
'WIDGET_BUTTON':  $
   begin
      title = 'Select Dependent Variable'
      file_tree_id = self.file_tree
      if not widget_info(file_tree_id,/valid_id) then return,0
      sel_id = widget_info(file_tree_id,/tree_select)
      n_sel = n_elements(sel_id)
      if not widget_info(sel_id[0],/valid_id) then return,0
      uname = widget_info(sel_id[0],/uname)
      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
         (uname eq 'INTERMEDIATE_FILE') or (uname eq 'REDUCED_FILE') then begin
         ocontainer = obj_new('IDL_CONTAINER')
         for i = 0,n_sel-1 do begin
            widget_control,sel_id[i],get_uvalue = uval
            ocontainer->add,uval.data_object
         endfor
         dtas_change_ivar,ocontainer,group_leader = event.top,   $
            notify_ids = [event.id,event.top],register_name = register_name, $
            no_update = 0,num_elements = 15,title=title,/dependent
      endif
      if uname eq 'REDUCTION_GROUP_FOLDER' then begin
         ; Get all of the DATA objects out and change em'
         list = get_list_items(sel_id[0],IDS = parent_ids,UNAMES = unames)
         ocontainer = obj_new('IDL_CONTAINER')
         for i = 0,n_elements(parent_ids)-1 do begin
            signal_list = get_list_items(parent_ids[i],IDS = child_ids)
            for j = 0,n_elements(child_ids)-1 do begin
               widget_control,child_ids[j],get_uvalue = uval
               ocontainer->add,uval.data_object
            endfor
         endfor
            dtas_change_ivar,ocontainer,group_leader = event.top,               $
               notify_ids = [event.id,event.top],register_name = register_name, $
               no_update = 1,num_elements = 15,title=title,/dependent
      endif
   end
'DCI_EVENT':   $
   begin
      o = event.ocontainer
      n = o->count()
      oall = o->get(/all)
      for i = 0,n-1 do begin
         ret = oall[i]->get_property(var_names = var_names)
         new_choice = var_names[event.selection]
         ret = oall[i]->set_property(yvar_name = new_choice)
      endfor
      if not xregistered(register_name) then begin
         for i = 0,n-1 do o->remove,oall[i]
         obj_destroy,o
      endif
      sel_id = widget_info(self.file_tree,/tree_select)
      ret = self->update_plot_info(oall)
      if event.update eq 1 then ret = self->refresh(event)
   end
else:
endcase

return,1
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_change_detsInSum,event
this_event = tag_names(event,/structure_name)
register_name = 'change_detsInSum'
case this_event of
    'WIDGET_BUTTON': begin
        title = 'Select Detectors to Include in Sum'
        file_tree_id = self.file_tree
        if not widget_info(file_tree_id,/valid_id) then return,0
        sel_id = widget_info(file_tree_id,/tree_select)
        n_sel = n_elements(sel_id)
        if not widget_info(sel_id[0],/valid_id) then return,0
        uname = widget_info(sel_id[0],/uname)
;      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
;         (uname eq 'INTERMEDIATE_FILE') or (uname eq 'REDUCED_FILE') then begin
        if ((uname eq 'SIGNAL_FILE') || (uname eq 'EMPTY_FILE'))then begin
            ocontainer = obj_new('IDL_CONTAINER')
            mixedModeFlag = 0
            for i = 0,n_sel-1 do begin
                widget_control,sel_id[i],get_uvalue = uval
                ocontainer->add,uval.data_object
                void = uval.data_object->get_property(anaMode=mode)
                if (i eq 0) then mode0 = mode
                if (mode eq -1 || mode ne mode0) then begin
                    mixedModeFlag = 1
                    break
                endif
            endfor
            if (mixedModeFlag) then begin
                oContainer->remove, oContainer->get(/all)
                obj_destroy, oContainer
                msg = ['Cannot determine analyzer package mode','OR','Datasets do not all have the same mode']
                void = dialog_message(msg,dialog_parent=event.top)
                return, 0
            endif
;            dtas_change_ivar,ocontainer,group_leader = event.top,   $
;                             notify_ids = [event.id,event.top],register_name = register_name, $
;                             no_update = 0,num_elements =
 ;                             15,title=title,/dependent
            dtas_change_detsInSum, oContainer, group_leader=event.top, $
              notify_ids=[event.id,event.top], register_name=register_name, $
              no_update=0, num_elements=15, title=title, /dependent
        endif
;      if uname eq 'REDUCTION_GROUP_FOLDER' then begin
;         ; Get all of the DATA objects out and change em'
;         list = get_list_items(sel_id[0],IDS = parent_ids,UNAMES = unames)
;         ocontainer = obj_new('IDL_CONTAINER')
;         for i = 0,n_elements(parent_ids)-1 do begin
;            signal_list = get_list_items(parent_ids[i],IDS = child_ids)
;            for j = 0,n_elements(child_ids)-1 do begin
;               widget_control,child_ids[j],get_uvalue = uval
;               ocontainer->add,uval.data_object
;            endfor
;         endfor
;            dtas_change_ivar,ocontainer,group_leader = event.top,               $
;               notify_ids = [event.id,event.top],register_name = register_name, $
;               no_update = 1,num_elements = 15,title=title,/dependent
;      endif
    end
    'DETSINSUM_EVENT': begin
        oCont = event.oContainer
        oData = oCont->get(/all,count=nData)
        for i = 0,nData-1 do begin
            ret = oData[i]->get_property(anaPkgStr=anaPkgStr)
            switch anaPkgStr.mode of
                1: begin
                    ;; Diffraction detectors
                    detFlags = (*event.DDFlags)
                    ind = where(detFlags eq 1,cnt)
                    if (cnt gt 0) then begin
                        detsInSum = anaPkgStr.DDDets[ind]
                        anaPkgStr.sigDetsInSum = strjoin(detsInSum,';',/single)
                    endif else $
                      anaPkgStr.sigDetsInSum = ''
                    break
                end
                
                2:
                3: begin
                    ;; Primary detectors
                    detFlags = (*event.SDFlags)
                    ind = where(detFlags eq 1,cnt)
                    if (cnt gt 0) then begin
                        detsInSum = anaPkgStr.SDDets[ind]
                        anaPkgStr.sigDetsInSum = strjoin(detsInSum,';',/single)
                    endif else $
                      anaPkgStr.sigDetsInSum = ''
                    ;; Door Detectors
                    detFlags = (*event.TDFlags)
                    ind = where(detFlags eq 1,cnt)
                    if (cnt gt 0) then begin
                        detsInSum = anaPkgStr.TDDets[ind]
                        anaPkgStr.TDDetsInSum = strjoin(detsInSum,';',/single)
                    endif else $
                      anaPkgStr.TDDetsInSum = ''
                    break
                end
                
                else: return, 0
            endswitch
            
            ret = oData[i]->set_property(anaPkgStr=anaPkgStr,/anaPkgUpdData,show_TD=event.show_TD)
        endfor
        if not xregistered(register_name) then begin
            oCont->remove,oData
            obj_destroy,oCont
        endif
;        sel_id = widget_info(self.file_tree,/tree_select)
        ret = self->update_plot_info(oData)
        if event.update eq 1 then ret = self->refresh(event)
    end
    
    else:
endcase

return,1
end



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_change_second_ivar,event
this_event = tag_names(event,/structure_name)
register_name = 'change_second_ivar'
case this_event of
'WIDGET_BUTTON':  $
   begin
      file_tree_id = self.file_tree
      if not widget_info(file_tree_id,/valid_id) then return,0
      sel_id = widget_info(file_tree_id,/tree_select)
      n_sel = n_elements(sel_id)
      if not widget_info(sel_id[0],/valid_id) then return,0
      uname = widget_info(sel_id[0],/uname)
      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
         (uname eq 'REDUCED_FILE') then begin
         ocontainer = obj_new('IDL_CONTAINER')
         for i = 0,n_sel-1 do begin
            widget_control,sel_id[i],get_uvalue = uval
            ocontainer->add,uval.data_object
         endfor
         ret = uval.data_object->get_property(second_var_name = var_name, $
            var_names = var_names)
         ntitles = n_elements(var_names)
         titles = strupcase([var_names[0:ntitles-3],'HFIELD'])
         sel_index = (where(titles eq var_name))[0]
;         sel_index = (where([var_names,'HFIELD'] eq var_name))[0]
         dtas_change_second_ivar,ocontainer,group_leader = event.top,   $
            notify_ids = [event.id,event.top],register_name = register_name, $
            init_index = sel_index
      endif
   end
'DC2I_EVENT':   $
   begin
      o = event.ocontainer
      n = o->count()
      oall = o->get(/all)
      for i = 0,n-1 do begin
         ret = oall[i]->get_property(var_names = var_names)
         nvars = n_elements(var_names)
;         all_names = [var_names[0:nvars-3],'HFIELD']
         all_names = [var_names[0:nvars-3],'HFIELD'] ; remove counts and errors - they are assummed to be the last two items in the list
         new_choice = all_names[event.selection]
         ret = oall[i]->set_property(second_var_name = new_choice)
      endfor
      if not xregistered(register_name) then begin
         for i = 0,n-1 do o->remove,oall[i]
         obj_destroy,o
      endif
   end
else:
endcase

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_fit_n_gaussians,event
this_event = tag_names(event,/structure_name)
register_name = 'tas_reduction_preferences'
case this_event of
'WIDGET_BUTTON':  tas_sel_n_curves, group_leader = event.top,              $
                                    notify_ids = [event.id,event.top],     $
                                    ncurves = 10,                          $
                                    curve_name = 'Gaussians'
'TSN_EVENT':   $
   begin
      n = event.ncurves
      top = event.top
;      sliderOff = (event.slider eq 0)
      ; Now fit it...
      sel_id = widget_info(self.file_tree,/tree_select)
      nsel = n_elements(sel_id)
      if nsel ne 1 then return,0
      uname = widget_info(sel_id,/uname)
      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
         (uname eq 'REDUCED_FILE') then begin
         widget_control,sel_id,get_uvalue = uval
         o = uval.data_object
         ret = o->auto_gauss_fit(msg = msg,fit_text = fit_text,n = n,plot_mon = self.plot_mon)
         ret = self->update_plot_info(o)
         ret = self->refresh(event)
         if n_elements(fit_text) gt 1 then begin
;            if (sliderOff) then $
            void = dialog_message(dialog_parent = event.top,fit_text,   $
                                  title = 'Gaussian Fit Parameters', $
                                  /information)
         endif else begin
            text = 'Could not fit '+strtrim(string(n),2)+' Gaussians to the data'
            void = dialog_message(dialog_parent = event.top,text,   $
               title = 'Gaussian Fit Information')
      endelse
      id = event.wid
      if (widget_info(id,/valid)) then widget_control,id,input_focus = 1
   endif
   end
else:
endcase

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_fit_n_lorentzians,event
this_event = tag_names(event,/structure_name)
register_name = 'tas_reduction_preferences'
case this_event of
'WIDGET_BUTTON':  tas_sel_n_curves, group_leader = event.top,              $
                                    notify_ids = [event.id,event.top],     $
                                    ncurves = 1,                           $
                                    curve_name = 'Lorentzians'
'TSN_EVENT':   $
   begin
      n = event.ncurves
      top = event.top
      ; Now fit it...
      sel_id = widget_info(self.file_tree,/tree_select)
      nsel = n_elements(sel_id)
      if nsel ne 1 then return,0
      uname = widget_info(sel_id,/uname)
      if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
         (uname eq 'REDUCED_FILE') then begin
         widget_control,sel_id,get_uvalue = uval
         o = uval.data_object
         ret = o->auto_lorentz_fit(msg = msg,fit_text = fit_text,n = n,plot_mon = self.plot_mon)
         ret = self->update_plot_info(o)
         ret = self->refresh(event)
         if n_elements(fit_text) gt 1 then begin
            void = dialog_message(dialog_parent = event.top,fit_text,   $
               title = 'Lorentzian Fit Parameters', $
               /information)
         endif else begin
            text = 'Could not fit '+strtrim(string(n),2)+' Lorentzians to the data'
            void = dialog_message(dialog_parent = event.top,text,   $
               title = 'Lorentzian Fit Information')
      endelse
      id = event.wid
      if (widget_info(id,/valid)) then widget_control,id,input_focus = 1
   endif
   end
else:
endcase

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::add_data_group,event
;root_id = widget_info(event.top,find_by_uname = 'ROOT')
widget_control,self.file_tree,set_tree_select = 0
root_id = self.file_tree
red_group = widget_tree(root_id,value = 'Data Group',/folder,$
   /expanded,uname = 'REDUCTION_GROUP_FOLDER',uvalue = {object:self,method:'do_nothing', $
      tas_object:obj_new()})
signal_group = widget_tree(red_group,value = 'Signal Data',/folder,$
   /expanded,uname = 'SIGNAL_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
      parent:red_group})
empty_group = widget_tree(red_group,value = 'Background Data',/folder, $
   /expanded,uname = 'EMPTY_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
      parent:red_group})
int_group = widget_tree(red_group,value = 'Intermediate Steps',/folder, $
   /expanded,uname = 'INTERMEDIATE_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
   parent:red_group})
reduced_group = widget_tree(red_group,value = 'Reduced Data',/folder, $
   /expanded,uname = 'REDUCED_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
   parent:red_group})
combined_group = widget_tree(red_group,value = 'Combined Data',/folder, $
   /expanded,uname = 'COMBINED_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
   parent:red_group})

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_red_preferences,event
this_event = tag_names(event,/structure_name)
register_name = 'tas_reduction_preferences'
case this_event of
'WIDGET_BUTTON':  tas_reduction_prefs, group_leader = event.top,              $
                                       notify_ids = [event.id,event.top],     $
                                       pinit_values = self.prefs_ptr,         $
                                       prefs_dir = self.work_dir,             $
                                       register_name = register_name
'TAS_RED_PREF_EVENT':   $
   begin
      *self.prefs_ptr = *event.prefs
      if not xregistered(register_name) then $
         ptr_free,event.prefs
      ; Select the REDUCTION_GROUP_FOLDER
      widget_control,self.file_tree,set_tree_select = 0
      id = widget_info(self.file_tree,find_by_uname = 'REDUCTION_GROUP_FOLDER')
      widget_control,id,set_tree_select = 1
      ret = self->reduce_data(event)
   end
else:
endcase
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::zoom_events,event
if n_elements(*self.plot_info) eq 0 then return,0

;         str = 'Zooming->Hold down left mouse button, drag rubberband box, '+ $
;               'and release button. Autoscale->Press right mouse button'
;         ret = self->update_status(str)

tvlct,(*self.dtas_color_ptr).r,(*self.dtas_color_ptr).g,(*self.dtas_color_ptr).b
case event.type of
6: begin    ; key press
   if event.press then begin
      increment = 0.025
      case event.key of
      5: begin       ; move legend left
            (*self.legend_ptr).xpos = (*self.legend_ptr).xpos-increment
            ret = self->refresh(event,IMAGE = self.image)
         end
      6: begin       ; move legend right
            (*self.legend_ptr).xpos = (*self.legend_ptr).xpos+increment
            ret = self->refresh(event,IMAGE = self.image)
         end
      7: begin       ; move legend up
            (*self.legend_ptr).ypos = (*self.legend_ptr).ypos+increment
            ret = self->refresh(event,IMAGE = self.image)
         end
      8: begin       ; move legend down
            (*self.legend_ptr).ypos = (*self.legend_ptr).ypos-increment
            ret = self->refresh(event,IMAGE = self.image)
         end
      else:
      endcase
   endif
   end
0: begin    ; button press
      self.mouse = event.press
      if self.mouse eq 4 then begin
         self.autoscale = 1
         ret = self->refresh(event)
      endif
      if self.mouse eq 1 then begin
         self.xbox[0] = event.x
         self.ybox[0] = event.y
         wset,self.winVis
         device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.winPix]
         empty
         self.autoscale = 0
      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]]
         ret = self->refresh(event)
         self.mouse = 0B
      endif
      if self.mouse eq 4 then begin
         ret = self->refresh(event)
         self.mouse = 0B
      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 = (*self.color_ptr).black
         empty
      endif
   end
else:
endcase
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dtas_reduction_gui_events,event

if dave_set_focus(event) then return

;begin error handler------------------------------------------------------------
; RTA - handler to catch misc. errors and provide a graceful exit so
;       that main app does not crash. Remember to comment out handler
;       block 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_BASE' then begin
   widget_control,event.top,get_uvalue = the_object
   ret = the_object->resize(event)
   return
endif
uname = widget_info(event.id,/uname)
widget_control,event.id,get_uvalue = cmd
ret = call_method(cmd.method,cmd.object,event)
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::init_colors
color_names = fsc_color(/names)
ncolors = n_elements(color_names)
s = create_struct(color_names[0],FSC_COLOR(color_names[0], !D.Table_Size-1))
for i = 1,ncolors-1 do begin
   s = create_struct(s,color_names[i],FSC_COLOR(color_names[i], !D.Table_Size-1-i))
endfor
*self.color_ptr = s
;color_array = [s.yellow,s.green,s.aquamarine,s.red,s.salmon,s.white,s.purple]
color_array = [s.black,s.blue,s.red,s.purple,s.green,s.maroon,s.aquamarine,s.gold]
*self.sel_colors_ptr = color_array
tvlct,r,g,b,/get
*self.dtas_color_ptr = {r:r,g:g,b:b}
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_rename_data_group,event
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
uname = widget_info(sel_id,/uname)
if uname ne 'REDUCTION_GROUP_FOLDER' then return,0
widget_control,sel_id,get_value = old_name
new_name = dtas_new_name(old_name,group_leader = event.top)
widget_control,sel_id,set_value = new_name
return,1
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_rename_file,event
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel ne 1 then return,0
uname = widget_info(sel_id,/uname)
if (uname eq 'SIGNAL_FILE') or (uname eq 'EMPTY_FILE') or $
   (uname eq 'INTERMEDIATE_FILE') or (uname eq 'REDUCED_FILE') or $
   (uname eq 'COMBINED_FILE') then begin
   widget_control,sel_id,get_uvalue = uval
   if uname eq 'COMBINED_FILE' then o = uval.image_object else $
      o = uval.data_object
   ret = o->get_property(display_name = display_name)
   new_name = dtas_new_name(display_name,group_leader = event.top, $
      title = 'Enter new file name with extension')
   if new_name ne '' then begin
;      ret = o->get_property(plot_str = plot_str)
;      plot_str.title = new_name
      ret = o->set_property(display_name = new_name);,plot_str = plot_str)
      widget_control,sel_id,set_value = new_name
      ret = self->update_plot_info(sel_id)
   endif
endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::init_symbols
n = 8
; Create the fill array so that there are alternating unfilled and filled
; symbols respectively
fill = intarr(n)
;one_index = where(indgen(n) mod 2 ne 0)
;fill[one_index] = 1
fill[4:7] = 1
; Create the shape array
;shape = strarr(n)

; The following four lines defined the shapes originally in the software
;shape[0:13] = 'circle'
;shape[14:27] = 'triangle'
;shape[28:41] = 'box'
;shape[42:n-1] = 'diamond'

; The following lines define the symbol shapes for the new version of
; this software
;prim_shapes = ['circle','circle','triangle','triangle','box','box',  $
;               'diamond','diamond']
;for i = 0,7 do begin
;   if i eq 0 then shape = prim_shapes else $
;      shape = [shape,prim_shapes]
;endfor
shape = ['circle','triangle','box','diamond'] ; RTA change above defn to this single line

; Create the color array
colors = *self.color_ptr
color_choices = *self.sel_colors_ptr
ncolors = n_elements(color_choices)

; The following seven lines defined the colors originally in the
; software
;color = lonarr(n)
;for j = 0,ncolors-2 do begin
;   color[2*j:2*j+1] = color_choices[j]
;   color[2*j+14:2*j+14+1] = color_choices[j]
;   color[2*j+28:2*j+28+1] = color_choices[j]
;   color[2*j+42:(2*j+42+1)] = color_choices[j]
;endfor

; The following lines define the colors for the new version of
; this software
;color = lonarr(n)
;for j = 0,ncolors-2 do begin
;   for i = 0,7 do begin
;      if j eq 0 and i eq 0 then color = color_choices[j] else $
;         color = [color,color_choices[j]]
;   endfor
;endfor
color = color_choices           ; RTA change above defn to this single line


*self.sym_ptr = {fill:fill,shape:shape,color:color}
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_combine,event
;
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel lt 2 then return,0
for i = 0,n_sel-1 do begin
   uname = widget_info(sel_id[i],/uname)
   if i eq 0 then unames = uname else unames = [unames,uname]
endfor
if n_elements(uniq(unames)) ne 1 then return,0
if (unames[0] eq 'SIGNAL_FILE') or (unames[0] eq 'EMPTY_FILE') or $
   (unames[0] eq 'REDUCED_FILE') or (unames[0] eq 'INTERMEDIATE_FILE') then begin
   red_id = widget_info(widget_info(sel_id[0],/parent),/parent)
   widget_control,red_id,get_uvalue = uval




   tas_object = uval.tas_object
   oarray = objarr(n_sel)
   for j = 0,n_sel-1 do begin
      widget_control,sel_id[j],get_uvalue = uv
      oarray[j] = uv.data_object
   endfor

   ret = tas_object->clear_zip()
   ret = tas_object->add_zip(oarray)

;; Determine if there are second independent variables present
;   nobj = n_elements(oarray)
;   for i = 0,nobj-1 do begin
;      ret = oarray[i]->get_property()
;   endfor

   o = tas_object->zip_data(msg = msg)
;   o = tas_object->zip_non_orth_data(msg = msg)

   if msg ne '' then begin
      strout = msg
      void = dialog_message(dialog_parent = event.top,strout)
      return,0
   endif
   ; Create a new leaf node under the COMBINED DATA folder
   red_id = widget_info(widget_info(sel_id[0],/parent),/parent)
   comb_id = widget_info(red_id,find_by_uname = 'COMBINED_DATA_FOLDER')
   ret = o->get_property(display_name = display_name)
   comb_leaf = widget_tree(comb_id,value = display_name,       $
               uname = 'COMBINED_FILE',                        $
               bitmap = *self.image_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           image_object:o                      })

endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_combine_non_orth,event
;
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel lt 2 then return,0
for i = 0,n_sel-1 do begin
   uname = widget_info(sel_id[i],/uname)
   if i eq 0 then unames = uname else unames = [unames,uname]
endfor
if n_elements(uniq(unames)) ne 1 then return,0
if (unames[0] eq 'SIGNAL_FILE') or (unames[0] eq 'EMPTY_FILE') or $
   (unames[0] eq 'REDUCED_FILE') or (unames[0] eq 'INTERMEDIATE_FILE') then begin
   red_id = widget_info(widget_info(sel_id[0],/parent),/parent)
   widget_control,red_id,get_uvalue = uval




   tas_object = uval.tas_object
   oarray = objarr(n_sel)
   for j = 0,n_sel-1 do begin
      widget_control,sel_id[j],get_uvalue = uv
      oarray[j] = uv.data_object
   endfor

   ret = tas_object->clear_zip()
   ret = tas_object->add_zip(oarray)

;; Determine if there are second independent variables present
;   nobj = n_elements(oarray)
;   for i = 0,nobj-1 do begin
;      ret = oarray[i]->get_property()
;   endfor

;   o = tas_object->zip_data(msg = msg)
   o = tas_object->zip_non_orth_data(msg = msg)

   if msg ne '' then begin
      strout = msg
      void = dialog_message(dialog_parent = event.top,strout)
      return,0
   endif
   ; Create a new leaf node under the COMBINED DATA folder
   red_id = widget_info(widget_info(sel_id[0],/parent),/parent)
   comb_id = widget_info(red_id,find_by_uname = 'COMBINED_DATA_FOLDER')
   ret = o->get_property(display_name = display_name)
   comb_leaf = widget_tree(comb_id,value = display_name,       $
               uname = 'COMBINED_FILE',                        $
               bitmap = *self.image_icon,                       $
               uvalue = {  object:self,                        $
                           method:'select_data',               $
                           image_object:o                      })

endif
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_save_dave,event
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel eq 0 then return,0
for i = 0,n_sel-1 do begin
   uname = widget_info(sel_id[i],/uname)
   if i eq 0 then unames = uname else unames = [unames,uname]
endfor
for j = 0,n_sel-1 do begin
   widget_control,sel_id[j],get_uvalue = uval
   if (unames[j] eq 'SIGNAL_FILE') or (unames[j] eq 'EMPTY_FILE') or $
      (unames[j] eq 'REDUCED_FILE') or (unames[j] eq 'INTERMEDIATE_FILE') then begin
      widget_control,sel_id[j],get_uvalue = uval
      o = uval.data_object
   endif
   if unames[j] eq 'COMBINED_FILE' then begin
      o = uval.image_object
   endif
   saved_filename = o->write_dave(self.work_dir, self.plot_detnorm, self.plot_det)
   
   void = dialog_message(['Output saved to: ',saved_filename])
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_save_ascii,event
sel_id = widget_info(self.file_tree,/tree_select)
n_sel = n_elements(sel_id)
if n_sel eq 0 then return,0
for i = 0,n_sel-1 do begin
   uname = widget_info(sel_id[i],/uname)
   if i eq 0 then unames = uname else unames = [unames,uname]
endfor
for j = 0,n_sel-1 do begin
   widget_control,sel_id[j],get_uvalue = uval
   if (unames[j] eq 'SIGNAL_FILE') or (unames[j] eq 'EMPTY_FILE') or $
      (unames[j] eq 'REDUCED_FILE') or (unames[j] eq 'INTERMEDIATE_FILE') then begin
      widget_control,sel_id[j],get_uvalue = uval
      o = uval.data_object
      saved_filename = o->write_ascii(self.work_dir)
      void = dialog_message(['Output saved to: ',saved_filename])
   endif
endfor
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::about,event
strout = strarr(4)
strout[0] = 'TAS Data Reduction'
strout[1] = 'Written by Rob Dimeo'
strout[2] = 'December 17, 2003'
strout[3] = 'NIST Center for Neutron Research'
void = dialog_message(dialog_parent = event.top,strout,  $
   title = 'About TAS Data Reduction',/information)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::launch_dtas_help,event
;pdf_file = file_which('dtas_red.pdf',/include_current_dir)
pdf_file = !DAVE_AUXILIARY_DIR+'dtas_red.pdf'
void = launch_help(pdf_file,tlb = event.top)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::launch_quick_start,event
;pdf_file = file_which('tas_reduction_quick_start.pdf',/include_current_dir)
pdf_file = !DAVE_AUXILIARY_DIR+'tas_reduction_quick_start.pdf'
void = launch_help(pdf_file,tlb = event.top)
return,1
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::send_to_pan,event
thisEvent = tag_names(event,/structure_name)
case thisEvent of
'WIDGET_BUTTON': $
   begin
;      if n_elements(*self.plot_info) eq 0 then return,0
;      plot_str = *self.plot_info
      sel_id = widget_info(self.file_tree,/tree_select)
      n_sel = n_elements(sel_id)
      if n_sel ne 1 then return,0
      widget_control,sel_id,get_uvalue = uval
      if not self.image then begin
         o = uval.data_object
         ret = o->get_property(  plot_str = plot_str,          $
                              display_name = display_name,  $
                              treatment = treatment,scan=scan         )
         x = *plot_str.x
         y = 0.0
         if self.plot_mon then begin
            qty = o->get_monitor()
            err = sqrt(qty)
         endif else begin
            qty = *plot_str.y
            err = *plot_str.dy
         endelse
         
         qtlabel = plot_str.ytitle

         mon = o->get_monitor()
         if scan ne 'ALIGNMENT' then begin
             ; Is it normalized to the beam monitor?
             index = where(treatment eq 'Normalized to beam monitor',count_treat)
             mon_norm = count_treat eq 1
             
             if mon_norm then mon_ave = mon else mon_ave = mon[0]
             if self.plot_det then begin
                if self.plot_detnorm then begin
                   qty = qty*mon_ave/mon
                   err = err*mon_ave/mon
                endif else begin
                   qtlabel = 'Raw detector counts'
                endelse
             endif
         endif
         
         zeros = where(err eq 0.0,count_zeros)
         if count_zeros gt 0 then err[zeros] = 1.0
         ; Sort the data
         xsort = sort(x)
         x = x[xsort] & qty = qty[xsort] & err = err[xsort]
         RET_VAL = CREATE_DAVE_POINTER(   thisPTR,          $
                  INSTRUMENT = 'TAS',  $
                  QTY = qty,                          $
                  ERR = err,                          $
                  XLABEL = plot_str.xtitle,                 $
                  QTLABEL = qtlabel,                $
                  YVALS = y,                          $
                  XVALS = x,                          $
                  XTYPE = 'POINTS',                   $
                  YTYPE = 'POINTS',                   $
                  TREATMENT = treatment)
      endif else begin
         o = uval.image_object
         thisptr = o->create_dave_ptr()
      endelse
       *self.daveptr = thisptr
       o = obj_new('opan',notifyId = [event.id,event.top], $
                         group_leader = event.top, $
                           davePtr = thisPtr,   $
                           workdir = self.work_dir)
   end
'OPANEVENT': $
  begin
    obj = event.object  ; This is the object that just quit
   obj_destroy,obj
   heap_free,self.daveptr
   self.daveptr = ptr_new(/allocate_heap)
  end
else:
endcase

return,1
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::send_to_DB,event
  thisEvent = tag_names(event,/structure_name)
  case thisEvent of
     'WIDGET_BUTTON': begin
;        if n_elements(*self.plot_info) eq 0 then return,0
;        plot_str = *self.plot_info
        sel_id = widget_info(self.file_tree,/tree_select)
        n_sel = n_elements(sel_id)
        if (n_sel lt 1) then return,0
        
        for i_sel=0,n_sel-1 do begin
           widget_control,sel_id[i_sel],get_uvalue = uval
           if not self.image then begin
              o = uval.data_object
              ret = o->get_property(  plot_str = plot_str,          $
                                      display_name = display_name,  $
                                      treatment = treatment,scan=scan         )
              x = *plot_str.x
              y = 0.0
              if self.plot_mon then begin
                 qty = o->get_monitor()
                 err = sqrt(qty)
              endif else begin
                 qty = *plot_str.y
                 err = *plot_str.dy
              endelse
              zeros = where(err eq 0.0,count_zeros)
              if count_zeros gt 0 then err[zeros] = 1.0
              ;; Sort the data

             qtlabel = plot_str.ytitle
    
             mon = o->get_monitor()
             if scan ne 'ALIGNMENT' then begin
                 ; Is it normalized to the beam monitor?
                 index = where(treatment eq 'Normalized to beam monitor',count_treat)
                 mon_norm = count_treat eq 1
                 
                 if mon_norm then mon_ave = mon else mon_ave = mon[0]
                 if self.plot_det then begin
                    if self.plot_detnorm then begin
                       qty = qty*mon_ave/mon
                       err = err*mon_ave/mon
                    endif else begin
                       qtlabel = 'Raw detector counts'
                    endelse
                 endif
             endif



              xsort = sort(x)
              x = x[xsort] & qty = qty[xsort] & err = err[xsort]
              RET_VAL = CREATE_DAVE_POINTER(   thisPTR,          $
                                               INSTRUMENT = 'TAS',  $
                                               QTY = qty,                          $
                                               ERR = err,                          $
                                               XLABEL = plot_str.xtitle,                 $
                                               QTLABEL = qtlabel,                $
                                               YVALS = y,                          $
                                               XVALS = x,                          $
                                               XTYPE = 'POINTS',                   $
                                               YTYPE = 'POINTS',                   $
                                               TREATMENT = treatment)
           endif else begin
              o = uval.image_object
              ret = o->get_property(display_name = display_name)
              thisptr = o->create_dave_ptr()
           endelse
           ;;        *self.daveptr = thisptr
           
           ;;; remove extension from display_name
           ;i = strpos(display_name,'.',/reverse_search)
           ;ext = (i lt 0)? '' : strmid(display_name,i)
           ;display_name = file_basename(display_name, ext)
           
           if (xregistered('DaveDataBrowser')) then begin
              ;;print,'DB is running...'
              ;;print,'dbTLB = ',self.dataBrowserTLB
              if (widget_info(self.dataBrowserTLB,/valid)) then begin
                 DB_i_loadDataFromDavePtrs, self.dataBrowserTLB, data=thisPtr, nametag=display_name
                 widget_control, self.dataBrowserTLB,/show
              endif else begin  ; 
                 title = 'View '+display_name+' in Data Browser'
                 msg = 'Cannot locate a running Data Browser instance!'
                 msg = [msg,'If an instance of the Data Browser is currently running,']
                 msg = [msg,'please, end it before trying this function again.']
                 void = dialog_message(msg,/info,title=title,dialog_parent=event.top)
                 break
              endelse
           endif else begin
              db_interface, GROUP_LEADER=self.group_leader, WORKING_DIRECTORY=(*!dave_defaults).workDir, $
                            data=thisPtr, nameTag=display_name, dbTLB=dbTLB
              self.dataBrowserTLB=dbTLB
           endelse
           
           heap_free,thisPtr
        endfor
     end
     
     else:
  endcase
  
  return,1
end



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::change_colors,event
thisEvent = tag_names(event,/structure_name)
case thisEvent of
'WIDGET_BUTTON': $
   begin
      XColors, Group_Leader=event.top, NotifyID=[event.id, event.top]
   end
'XCOLORS_LOAD': $
   begin
      ret = self->refresh(event,IMAGE = self.image,/xcolor)
   end
else:
endcase

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::legend_pref,event
thisEvent = tag_names(event,/structure_name)
register_name = 'DTAS_LEGEND_PREFS'
case thisEvent of
'WIDGET_BUTTON': $
   begin
      dtas_legend_prefs, Group_Leader=event.top, Notify_IDs=[event.id, event.top], $
         *self.legend_ptr,register_name = register_name
   end
'PREFS_LEGEND_EVENT': $
   begin
      *self.legend_ptr = *event.prefs
      ret = self->refresh(event,IMAGE = self.image)
      if not xregistered(register_name) then $
         ptr_free,event.prefs
   end
else:
endcase

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::launch_spurion,event
thisEvent = tag_names(event,/structure_name)
case thisEvent of
'WIDGET_BUTTON': $
   begin
      spurion,NotifyIDs=[event.id, event.top]
   end
else:
endcase

return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_shift_spectrum,event
sel_id = widget_info(self.file_tree,/tree_select)
if n_elements(sel_id) ne 1 then return,0
widget_control,sel_id,get_uvalue = uval
o = uval.data_object
ret = o->get_property(shift_value = shift_value)
title = 'Enter the independent variable shift amount'
result = dave_input_box(group_leader = event.top,title = title,   $
   value = shift_value, cancel = cancel)
if (cancel eq 1B) then return,1
ret = o->set_property(shift_value = double(result[0]))
;**********************Debugging**********************
;ret = o->get_property(var_names = var_names,data = data)
;nvars = n_elements(var_names)
ret = o->shift_spectrum()
;ret = o->get_property(data = data)
ret = self->update_plot_info(sel_id)
;**********************End Debugging******************

ret = self->refresh(event,IMAGE = self.image)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_plot_mon,event
self.plot_mon = 1B
self.plot_det = 0B
ret = self->refresh(event,IMAGE = self.image)
return,1B
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_plot_detector,event
self.plot_det = 1B
self.plot_mon = 0B
ret = self->refresh(event,IMAGE = self.image)
return,1B
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_plot_raw_detector,event
self.plot_det = 1B
self.plot_detnorm = 0B
self.plot_detnonorm = 1B
self.plot_mon = 0B
ret = self->refresh(event,IMAGE = self.image)
return,1B
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::tas_plot_norm_detector,event
self.plot_det = 1B
self.plot_detnorm = 1B
self.plot_detnonorm = 0B
self.plot_mon = 0B
ret = self->refresh(event,IMAGE = self.image)
return,1B
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::toggle_hide_show,event
if widget_info(self.file_info_id,/valid_id) then begin   ; exists so kill it
   widget_control,self.file_info_id,/destroy
   self.file_info_id = 0L
endif else begin  ; does not exist so create it and populate it
   self.file_info_id = widget_text(self.tlb,ysize = 20,/scroll,value = '') ; rta increase ysize to 20
   ret = self->tas_show_single_file_contents(event,/show)
endelse
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::build_gui
; Get the DAVE colors
device,get_decomposed = dc
self.dave_dc = dc
tvlct,r,g,b,/get
*self.dave_color_ptr = {r:r,g:g,b:b}
ret = self->init_colors()
ret = self->init_symbols()
self.tlb = widget_base(title = 'Triple Axis Spectrometer Data Reduction',  $
                        /col,mbar = bar,/tlb_size_events,   $
                           group_leader = self.group_leader)
filemenu = widget_button(bar,value = 'FILE',/menu)
;void = widget_button(filemenu,value = 'Save session',   $
;   uvalue = {object:self, method:'DTAS_SAVE_SESSION'})
;void = widget_button(filemenu,value = 'Restore session',   $
;   uvalue = {object:self, method:'DTAS_RESTORE_SESSION'})
void = widget_button(filemenu,value = 'Load Signal File',   $
   uvalue = {object:self, method:'LOAD_SIGNAL_FILES'})
void = widget_button(filemenu,value = 'Add New Data Group',   $
   uvalue = {object:self, method:'ADD_DATA_GROUP'})
void = widget_button(filemenu,value = 'Load Example TAS File',   $
   uvalue = {object:self, method:'LOAD_EXAMPLE_FILE'},/separator)
void = widget_button(filemenu,value = 'QUIT',   $
   uvalue = {object:self, method:'QUIT'},/separator)
;plot_menu = widget_button(bar,value = 'PLOT')
;void = widget_button(plot_menu,value = 'Legend plot preferences', $
;   uvalue = {object:self,method:'legend_pref'})
misc_menu = widget_button(bar,value = 'MISC')
void = widget_button(misc_menu,value = 'Quick-Start Instructions',   $
   uvalue = {object:self, method:'launch_quick_start'})
void = widget_button(misc_menu,value = 'Data Reduction Manual',   $
   uvalue = {object:self, method:'launch_dtas_help'})
void = widget_button(misc_menu,value = 'Spurion calculator',   $
   uvalue = {object:self, method:'launch_spurion'})
void = widget_button(misc_menu,value = 'About TAS Data Reduction',   $
   uvalue = {object:self, method:'about'})

device,get_screen_size = scr_size
aspect_ratio = float(scr_size[0])/float(scr_size[1])
dual_monitor = aspect_ratio gt 4./3.
xsize = 400 & ysize = 300

tree_ysize = ysize
if dual_monitor then begin
   tree_xsize = fix(0.33*0.5*scr_size[0])
endif else begin
   tree_xsize = fix(0.33*scr_size[0])
endelse


row_base = widget_base(self.tlb,/row,uname = 'ROW_BASE')
tree_base = widget_base(row_base,/col,uname = 'TREE_BASE')

self.file_tree = widget_tree(tree_base,scr_xsize = tree_xsize, $
   scr_ysize = tree_ysize,/context_events, multiple = 1,$
   uvalue = {object:self,method:'context_events'})

root_id = self.file_tree
red_group = widget_tree(root_id,value = 'Data Group',/folder,$
   /expanded,uname = 'REDUCTION_GROUP_FOLDER',uvalue = {object:self,method:'do_nothing', $
      tas_object:obj_new()})
signal_group = widget_tree(red_group,value = 'Signal Data',/folder,$
   /expanded,uname = 'SIGNAL_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
      parent:red_group})
empty_group = widget_tree(red_group,value = 'Background Data',/folder, $
   /expanded,uname = 'EMPTY_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
      parent:red_group})
int_group = widget_tree(red_group,value = 'Intermediate Steps',/folder, $
   /expanded,uname = 'INTERMEDIATE_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
   parent:red_group})
reduced_group = widget_tree(red_group,value = 'Reduced Data',/folder, $
   /expanded,uname = 'REDUCED_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
   parent:red_group})
combined_group = widget_tree(red_group,value = 'Combined Data',/folder, $
   /expanded,uname = 'COMBINED_DATA_FOLDER',uvalue = {object:self,method:'do_nothing', $
   parent:red_group})


; Create the reduction group menu
red_menu = widget_base(self.tlb,/context_menu,uname = 'REDUCTION_GROUP_MENU')
void = widget_button(red_menu,value = 'Set Reduction Preferences',   $
   uvalue = {object:self,method:'tas_red_preferences'})
void = widget_button(red_menu,value = 'Reduce Data',   $
   uvalue = {object:self,method:'reduce_data'})
void = widget_button(red_menu,value = 'Rename data group',   $
   uvalue = {object:self,method:'tas_rename_data_group'},/separator)
void = widget_button(red_menu,value = 'Change independent variable',   $
   uvalue = {object:self,method:'tas_change_ivar'})
void = widget_button(red_menu,value = 'Change dependent variable',   $
   uvalue = {object:self,method:'tas_change_var'})
void = widget_button(red_menu,value = 'Copy data group folder and all its contents',   $
   uvalue = {object:self,method:'copy_data_folder'},sensitive = 0)
void = widget_button(red_menu,value = 'Remove all data files in all folders',   $
   uvalue = {object:self,method:'tas_delete_all'},/separator)

; Create the signal file group menu
data_menu = widget_base(self.tlb,/context_menu,uname = 'SIGNAL_DATA_MENU')
void = widget_button(data_menu,value = 'Change independent variable',   $
   uvalue = {object:self,method:'tas_change_ivar'})
void = widget_button(data_menu,value = 'Change dependent variable',   $
   uvalue = {object:self,method:'tas_change_var'})
void = widget_button(data_menu,value = 'Change detectors included in sum',   $
   uvalue = {object:self,method:'tas_change_detsInSum'})
void = widget_button(data_menu,value = 'Plot normalized detector data',   $
   uvalue = {object:self,method:'tas_plot_norm_detector'},/separator)
void = widget_button(data_menu,value = 'Plot raw detector data',   $
   uvalue = {object:self,method:'tas_plot_raw_detector'})
;void = widget_button(data_menu,value = 'Plot detector data',   $
;   uvalue = {object:self,method:'tas_plot_detector'})
void = widget_button(data_menu,value = 'Plot monitor data',   $
   uvalue = {object:self,method:'tas_plot_mon'})
void = widget_button(data_menu,value = 'Show data file contents',   $
   uvalue = {object:self,method:'tas_show_contents'},/separator)
void = widget_button(data_menu,value = 'Show data treatment',   $
   uvalue = {object:self,method:'tas_show_treatment'})
void = widget_button(data_menu,value = 'Rename data file',   $
   uvalue = {object:self,method:'tas_rename_file'},/separator)
void = widget_button(data_menu,value = 'Remove selected data file(s)',   $
   uvalue = {object:self,method:'tas_delete_files'})
void = widget_button(data_menu,value = 'Move selected data file(s) to background folder',   $
   uvalue = {object:self,method:'tas_move_files_to_empty'})

void = widget_button(data_menu,value = 'Fit to N Gaussians',   $
   uvalue = {object:self,method:'tas_fit_n_gaussians'},/separator)
void = widget_button(data_menu,value = 'Fit to N Lorentzians',   $
   uvalue = {object:self,method:'tas_fit_n_lorentzians'})

void = widget_button(data_menu,value = 'Shift spectrum',   $
   uvalue = {object:self,method:'tas_shift_spectrum'})
void = widget_button(data_menu,value = 'Select "combining" variable',   $
   uvalue = {object:self,method:'tas_change_second_ivar'},/separator)
void = widget_button(data_menu,value = 'Combine selected datasets (using x range for first dataset)',   $
   uvalue = {object:self,method:'tas_combine'})
;void = widget_button(data_menu,value = 'Combine all signal files with different ranges',   $
;   uvalue = {object:self,method:'tas_combine_non_orth'})
void = widget_button(data_menu,value = 'Save as DAVE file',   $
   uvalue = {object:self,method:'tas_save_dave'},/separator)
void = widget_button(data_menu,value = 'Save as text file',   $
   uvalue = {object:self,method:'tas_save_ascii'})
void = widget_button(data_menu,value = 'Print to postscript file',   $
   uvalue = {object:self,method:'print_to_ps'})
void = widget_button(data_menu,value = 'Save as JPEG',   $
   uvalue = {object:self,method:'save_as_jpeg'})
void = widget_button(data_menu,value = 'Save as PNG',   $
   uvalue = {object:self,method:'save_as_png'})
void = widget_button(data_menu,value = 'Send data to PAN',   $
   uvalue = {object:self,method:'send_to_pan'})
void = widget_button(data_menu,value = 'View data in Data Browser',   $
   uvalue = {object:self,method:'send_to_DB'})

; Create the signal data group menu
data_menu = widget_base(self.tlb,/context_menu,uname = 'SIGNAL_FOLDER_MENU')
void = widget_button(data_menu,value = 'Load file(s)',   $
   uvalue = {object:self,method:'load_signal_files',type:'SIGNAL'})
void = widget_button(data_menu,value = 'Remove all signal files',   $
   uvalue = {object:self,method:'tas_delete_all_folder_files'})

; Create the combined file group menu
data_menu = widget_base(self.tlb,/context_menu,uname = 'COMBINED_DATA_MENU')
void = widget_button(data_menu,value = 'Rename',   $
   uvalue = {object:self,method:'tas_rename_file'})
void = widget_button(data_menu,value = 'Show data treatment',   $
   uvalue = {object:self,method:'tas_show_treatment'})
void = widget_button(data_menu,value = 'Remove selected data file(s)',   $
   uvalue = {object:self,method:'tas_delete_files'})
void = widget_button(data_menu,value = 'Change colors',   $
   uvalue = {object:self,method:'change_colors'})
void = widget_button(data_menu,value = 'Save as DAVE file',   $
   uvalue = {object:self,method:'tas_save_dave'})
void = widget_button(data_menu,value = 'Print to postscript file',   $
   uvalue = {object:self,method:'print_to_ps'})
void = widget_button(data_menu,value = 'Save as JPEG',   $
   uvalue = {object:self,method:'save_as_jpeg'})
void = widget_button(data_menu,value = 'Save as PNG',   $
   uvalue = {object:self,method:'save_as_png'})
void = widget_button(data_menu,value = 'Send data to PAN',   $
   uvalue = {object:self,method:'send_to_pan'})
void = widget_button(data_menu,value = 'View data in Data Browser',   $
   uvalue = {object:self,method:'send_to_DB'})

comb_menu = widget_base(self.tlb,/context_menu,uname = 'COMBINED_FOLDER_MENU')
void = widget_button(comb_menu,value = 'Remove all combined files',   $
   uvalue = {object:self,method:'tas_delete_all_folder_files'})


; Create the empty folder group menu
data_menu = widget_base(self.tlb,/context_menu,uname = 'EMPTY_FOLDER_MENU')
void = widget_button(data_menu,value = 'Load file(s)',               $
   uvalue = {object:self,method:'LOAD_EMPTY_FILES',type:'EMPTY'})
void = widget_button(data_menu,value = 'Remove all background files',     $
   uvalue = {object:self,method:'tas_delete_all_folder_files'})

; Create the intermediate folder group menu
int_data_menu = widget_base(self.tlb,/context_menu,uname = 'INTERMEDIATE_FOLDER_MENU')
void = widget_button(int_data_menu,value = 'Remove all intermediate files',     $
   uvalue = {object:self,method:'tas_delete_all_folder_files'})

; Create the reduced folder group menu
reduced_data_menu = widget_base(self.tlb,/context_menu,uname = 'REDUCED_FOLDER_MENU')
void = widget_button(reduced_data_menu,value = 'Remove all reduced files',     $
   uvalue = {object:self,method:'tas_delete_all_folder_files'})

; Create the empty data group menu
empty_data_menu = widget_base(self.tlb,/context_menu,uname = 'EMPTY_DATA_MENU')
void = widget_button(empty_data_menu,value = 'Change independent variable',   $
   uvalue = {object:self,method:'tas_change_ivar'})
void = widget_button(empty_data_menu,value = 'Change dependent variable',   $
   uvalue = {object:self,method:'tas_change_var'})

void = widget_button(empty_data_menu,value = 'Change detectors included in sum',   $
   uvalue = {object:self,method:'tas_change_detsInSum'})
void = widget_button(empty_data_menu,value = 'Plot normalized detector data',   $
   uvalue = {object:self,method:'tas_plot_norm_detector'},/separator)
void = widget_button(empty_data_menu,value = 'Plot raw detector data',   $
   uvalue = {object:self,method:'tas_plot_raw_detector'})
;void = widget_button(empty_data_menu,value = 'Plot detector data',   $
;   uvalue = {object:self,method:'tas_plot_detector'})
void = widget_button(empty_data_menu,value = 'Plot monitor data',   $
   uvalue = {object:self,method:'tas_plot_mon'})



void = widget_button(empty_data_menu,value = 'Show data file contents',   $
   uvalue = {object:self,method:'tas_show_contents'},/separator)
void = widget_button(empty_data_menu,value = 'Show data treatment',   $
   uvalue = {object:self,method:'tas_show_treatment'})
void = widget_button(empty_data_menu,value = 'Rename data file',   $
   uvalue = {object:self,method:'tas_rename_file'},/separator)
void = widget_button(empty_data_menu,value = 'Remove selected data file(s)',   $
   uvalue = {object:self,method:'tas_delete_files'})
void = widget_button(empty_data_menu,value = 'Move selected data file(s) to signal folder',   $
   uvalue = {object:self,method:'tas_move_files_to_signal'})
void = widget_button(empty_data_menu,value = 'Fit to N Gaussians',   $
   uvalue = {object:self,method:'tas_fit_n_gaussians'},/separator)
void = widget_button(empty_data_menu,value = 'Fit to N Lorentzians',   $
   uvalue = {object:self,method:'tas_fit_n_lorentzians'})
void = widget_button(empty_data_menu,value = 'Combine selected datasets (using x range for first dataset)',   $
   uvalue = {object:self,method:'tas_combine'})
;void = widget_button(empty_data_menu,value = 'Combine all background files with different ranges',   $
;   uvalue = {object:self,method:'tas_combine_non_orth'},/separator)
void = widget_button(empty_data_menu,value = 'Save as DAVE file',   $
   uvalue = {object:self,method:'tas_save_dave'},/separator)
void = widget_button(empty_data_menu,value = 'Save as text file',   $
   uvalue = {object:self,method:'tas_save_ascii'})
void = widget_button(empty_data_menu,value = 'Save as JPEG',   $
   uvalue = {object:self,method:'save_as_jpeg'})
void = widget_button(empty_data_menu,value = 'Save as PNG',   $
   uvalue = {object:self,method:'save_as_png'})
void = widget_button(empty_data_menu,value = 'Print to postscript file',   $
   uvalue = {object:self,method:'print_to_ps'})
void = widget_button(empty_data_menu,value = 'Send data to PAN',   $
   uvalue = {object:self,method:'send_to_pan'})
void = widget_button(empty_data_menu,value = 'View data in Data Browser',   $
   uvalue = {object:self,method:'send_to_DB'})

; Create the intermediate data group menu
int_data_menu = widget_base(self.tlb,/context_menu,uname = 'INTERMEDIATE_DATA_MENU')
void = widget_button(int_data_menu,value = 'Change independent variable',   $
   uvalue = {object:self,method:'tas_change_ivar'})
void = widget_button(int_data_menu,value = 'Change dependent variable',   $
   uvalue = {object:self,method:'tas_change_var'})
void = widget_button(int_data_menu,value = 'Show data file contents',   $
   uvalue = {object:self,method:'tas_show_contents'})
void = widget_button(int_data_menu,value = 'Show data treatment',   $
   uvalue = {object:self,method:'tas_show_treatment'})
void = widget_button(int_data_menu,value = 'Rename data file',   $
   uvalue = {object:self,method:'tas_rename_file'},/separator)
void = widget_button(int_data_menu,value = 'Remove selected data file(s)',   $
   uvalue = {object:self,method:'tas_delete_files'})
void = widget_button(int_data_menu,value = 'Save as DAVE file',   $
   uvalue = {object:self,method:'tas_save_dave'},/separator)
void = widget_button(int_data_menu,value = 'Save as text file',   $
   uvalue = {object:self,method:'tas_save_ascii'})
void = widget_button(int_data_menu,value = 'Print to postscript file',   $
   uvalue = {object:self,method:'print_to_ps'})
void = widget_button(int_data_menu,value = 'Save as JPEG',   $
   uvalue = {object:self,method:'save_as_jpeg'})
void = widget_button(int_data_menu,value = 'Save as PNG',   $
   uvalue = {object:self,method:'save_as_png'})
void = widget_button(int_data_menu,value = 'Send data to PAN',   $
   uvalue = {object:self,method:'send_to_pan'})
void = widget_button(int_data_menu,value = 'View data in Data Browser',   $
   uvalue = {object:self,method:'send_to_DB'})

mf_data_menu = widget_base(self.tlb,/context_menu,uname = 'MULTIPLE_FILES_MENU')
void = widget_button(mf_data_menu,value = 'Print to postscript file',   $
   uvalue = {object:self,method:'print_to_ps'})
void = widget_button(mf_data_menu,value = 'Save as JPEG',   $
   uvalue = {object:self,method:'save_as_jpeg'})
void = widget_button(mf_data_menu,value = 'Save as PNG',   $
   uvalue = {object:self,method:'save_as_png'})

; Create the reduced data group menu
empty_data_menu = widget_base(self.tlb,/context_menu,uname = 'REDUCED_DATA_MENU')
void = widget_button(empty_data_menu,value = 'Change independent variable',   $
   uvalue = {object:self,method:'tas_change_ivar'})
void = widget_button(empty_data_menu,value = 'Change dpendent variable',   $
   uvalue = {object:self,method:'tas_change_var'})
void = widget_button(empty_data_menu,value = 'Show data file contents',   $
   uvalue = {object:self,method:'tas_show_contents'})
void = widget_button(empty_data_menu,value = 'Show data treatment',   $
   uvalue = {object:self,method:'tas_show_treatment'})
void = widget_button(empty_data_menu,value = 'Rename data file',   $
   uvalue = {object:self,method:'tas_rename_file'},/separator)
void = widget_button(empty_data_menu,value = 'Remove selected data file(s)',   $
   uvalue = {object:self,method:'tas_delete_files'})
void = widget_button(empty_data_menu,value = 'Fit to N Gaussians',   $
   uvalue = {object:self,method:'tas_fit_n_gaussians'},/separator)
void = widget_button(empty_data_menu,value = 'Fit to N Lorentzians',   $
   uvalue = {object:self,method:'tas_fit_n_lorentzians'})
void = widget_button(empty_data_menu,value = 'Select "combining" variable',   $
   uvalue = {object:self,method:'tas_change_second_ivar'},/separator)
void = widget_button(empty_data_menu,value = 'Combine selected datasets (using x range for first dataset)',   $
   uvalue = {object:self,method:'tas_combine'})
;void = widget_button(empty_data_menu,value = 'Combine all reduced files with different ranges',   $
;   uvalue = {object:self,method:'tas_combine_non_orth'})
void = widget_button(empty_data_menu,value = 'Save as DAVE file',   $
   uvalue = {object:self,method:'tas_save_dave'},/separator)
void = widget_button(empty_data_menu,value = 'Save as text file',   $
   uvalue = {object:self,method:'tas_save_ascii'})
void = widget_button(empty_data_menu,value = 'Print to postscript file',   $
   uvalue = {object:self,method:'print_to_ps'})
void = widget_button(empty_data_menu,value = 'Save as JPEG',   $
   uvalue = {object:self,method:'save_as_jpeg'})
void = widget_button(empty_data_menu,value = 'Save as PNG',   $
   uvalue = {object:self,method:'save_as_png'})
void = widget_button(empty_data_menu,value = 'Send data to PAN',   $
   uvalue = {object:self,method:'send_to_pan'})
void = widget_button(empty_data_menu,value = 'View data in Data Browser',   $
   uvalue = {object:self,method:'send_to_DB'})

win_base = widget_base(row_base,/col,uname = 'WIN_BASE')
self.win = widget_draw(win_base,xsize = tree_xsize,ysize = tree_ysize, $
   uvalue = {object:self,method:'zoom_events'},/button_events, $
   /motion_events,keyboard_events = 1)
void = widget_label(self.tlb,value = 'PROGRAM STATUS/INFORMATION')
status_id = widget_text(self.tlb,value = '',uname = 'STATUS_TEXT')
;self.file_info_base = widget_base(self.tlb,/col)
self.show_hide_id = widget_button(self.tlb,value = 'Hide/Show File Info',   $
   uvalue = {object:self, method:'toggle_hide_show'})
self.file_info_id = 0L;widget_text(self.tlb,ysize = 12,/scroll,value = '')
centertlb,self.tlb
widget_control,self.tlb,/realize
;self.file_info_id = widget_text(self.tlb,ysize = 12,/scroll,value = '')

; Get out the reduction container
tree_geom = widget_info(tree_base,/geom)
widget_control,self.win,get_value = winvis
self.winvis = winvis
winxsize = tree_xsize & winysize = tree_ysize
window,/free,/pixmap,xsize = winxsize,ysize = winysize
self.winpix = !d.window

tlb_geom = widget_info(self.tlb,/geometry)
tree_base_id = widget_info(self.tlb,find_by_uname = 'TREE_BASE')
tree_geom = widget_info(tree_base_id,/geometry)
newxsize = (tlb_geom.xsize-tree_geom.xsize) > 300
newysize = tree_geom.ysize

wdelete,self.winpix
window,/free,/pixmap,xsize = newxsize,ysize = newysize
widget_control,self.win,draw_xsize = newxsize,draw_ysize = newysize
widget_control,tree_base_id,ysize = newysize

widget_control,self.tlb,set_uvalue = self
register_name = 'DTAS_REDUCE'

ret = dave_set_focus(self.tlb)

xmanager,register_name,self.tlb,event_handler = 'dtas_reduction_gui_events', $
   cleanup = 'dtas_reduction_gui_cleanup',/no_block
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function dtas_reduction_gui::init,  notify_ids = notify_ids,               $
                                    group_leader = group_leader,           $
                                    work_dir = work_dir,                   $
                                    data_dir = data_dir
if n_elements(notify_ids) eq 0 then notify_ids = [0L,0L]
if n_elements(group_leader) eq 0 then group_leader = 0L
if n_elements(work_dir) eq 0 then cd,current = work_dir
if n_elements(data_dir) eq 0 then cd,current = data_dir
self.filter = '*'
self.plot_choices = [0,0,0]
self.plot_mon = 0B
self.plot_det = 1B
self.plot_detnorm = 1B
self.plot_detnonorm = 0B
self.image_icon = ptr_new(/allocate_heap)
self.file_icon = ptr_new(/allocate_heap)

;bmp_file = file_which('scatter.bmp')
bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
if (strtrim(bmp_file,2) eq '') then bmp_file = 'scatter.bmp'

*self.file_icon = convert_bmp(bmp_file)
;image_file = file_which('image.bmp')
image_file = !DAVE_AUXILIARY_DIR+'image.bmp'
if (strtrim(image_file,2) eq '') then image_file = 'image.bmp'
*self.image_icon = convert_bmp(image_file)

self.sel_colors_ptr = ptr_new(/allocate_heap)
self.sym_ptr = ptr_new(/allocate_heap)
self.work_dir = work_dir
self.data_dir = data_dir
self.notify_ids = notify_ids
self.group_leader = group_leader
self.tlb = 0L
self.tas_container = obj_new('IDL_CONTAINER')
self.dtas_color_ptr = ptr_new(/allocate_heap)
self.dave_color_ptr = ptr_new(/allocate_heap)
self.color_ptr = ptr_new(/allocate_heap)

ret = self->build_gui()

; Initialize the data reduction preferences
   ; Set up the defaults for the widget
fbg = 1
fbg_val = 0.0
det_bal = 1
mon_cor = 1
res_cor = 1
scale = 1
scale_val = 1.0
save_int = 0
sum_signal = 1
sum_bg = 1
diff = 1
mon_norm = 0
time_norm = 0
linear_interp = 0
interp = 'BINNING'
init_values =  {     fbg:fbg,                      $
                     fbg_val:fbg_val,              $
                     det_bal:det_bal,              $
                     mon_cor:mon_cor,              $
                     mon_norm:mon_norm,            $
                     time_norm:time_norm,          $
                     res_cor:res_cor,              $
                     scale:scale,                  $
                     scale_val:scale_val,          $
                     save_int:save_int,            $
                     sum_signal:sum_signal,        $
                     sum_bg:sum_bg,                $
                     diff:diff,                    $
                     interp:interp,                $
                     linear_interp:linear_interp   }

self.legend_ptr = ptr_new(/allocate_heap)
leg_str = {xpos:0.75,ypos:0.75,charsize:1.0}
*self.legend_ptr = leg_str
self.prefs_ptr = ptr_new(init_values,/no_copy)
self.plot_info = ptr_new(/allocate_heap)
self.daveptr = ptr_new(/allocate_heap)
self.dtas_dc = 0
device,decomposed = self.dtas_dc
self.autoscale = 1B
self.xrange = [0.0,1.0] & self.yrange = [0.0,1.0]
self.widget_info_ptr = ptr_new(/allocate_heap)
self.psxsize = 8.0 & self.psysize = 11.0
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dtas_reduction_gui__define
class =  {  dtas_reduction_gui,                 $
            tlb:0L,                             $
            plot_choices:intarr(3),             $
            notify_ids:lonarr(2),               $
            dave_color_ptr:ptr_new(),           $
            dtas_color_ptr:ptr_new(),           $
            color_ptr:ptr_new(),                $
            sel_colors_ptr:ptr_new(),           $
            group_leader:0L,                    $
            plot_det:0B,                        $
            plot_mon:0B,                        $
            plot_detnorm:0B,                    $
            plot_detnonorm:0B,                  $
            work_dir:'',                        $
            data_dir:'',                        $
            filter:'',                          $
            file_tree:0L,                       $
            psxsize:0.0,                        $
            psysize:0.0,                        $
            psxoff:0.0,                         $
            psyoff:0.0,                         $
            win:0L,                             $
            winvis:0L,                          $
            autoscale:0B,                       $
            dave_dc:0,                          $
            dtas_dc:0,                          $
            winpix:0L,                          $
            legend_ptr:ptr_new(),               $
            mouse:0B,                           $
            image:0B,                           $
            text_id:0L,                         $
            show_hide_id:0L,                    $
            file_info_id:0L,                    $
            file_info_base:0L,                  $
            image_icon:ptr_new(),               $
            file_icon:ptr_new(),                $
            sym_ptr:ptr_new(),                  $
            xbox:intarr(2),                     $
            ybox:intarr(2),                     $
            xrange:fltarr(2),                   $
            yrange:fltarr(2),                   $
            plot_info:ptr_new(),                $
            prefs_ptr:ptr_new(),                $
            daveptr:ptr_new(),                  $
            dataBrowserTLB:0L, $
            widget_info_ptr:ptr_new(),          $
            tas_container:obj_new()             }
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro dtas_test_gui
device,decomposed = 0
dir = 'c:\dimeo\data\TAS_DATA\'
ogui = obj_new('dtas_reduction_gui',work_dir = dir,data_dir = dir)
end
