Index: guiframe/local_perspectives/plotting/AnnulusSlicer.py
===================================================================
--- guiframe/local_perspectives/plotting/AnnulusSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
+++ guiframe/local_perspectives/plotting/AnnulusSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -0,0 +1,326 @@
+#TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it
+#      before pushing a new 1D data update.
+
+#
+#TODO: NEED MAJOR REFACTOR
+#
+
+
+# Debug printout
+from sans.guicomm.events import StatusEvent 
+from sans.guicomm.events import NewPlotEvent
+from BaseInteractor import _BaseInteractor
+from copy import deepcopy
+import math
+
+import SlicerParameters
+import wx
+
+class AnnulusInteractor(_BaseInteractor):
+    """
+         Select an annulus through a 2D plot
+    """
+    def __init__(self,base,axes,color='black', zorder=3):
+        
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        self.qmax = self.base.qmax
+        self.connect = self.base.connect
+        
+        ## Number of points on the plot
+        self.nbins = 20
+
+        # Inner circle
+        self.inner_circle = RingInteractor(self, self.base.subplot, zorder=zorder, r=self.qmax/2.0)
+        self.inner_circle.qmax = self.base.qmax
+        self.outer_circle = RingInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax/1.8)
+        self.outer_circle.qmax = self.base.qmax*1.2
+        #self.outer_circle.set_cursor(self.base.qmax/1.8, 0)
+        
+                      
+        self.update()
+        #self._post_data()
+        
+        # Bind to slice parameter events
+        self.base.parent.Bind(SlicerParameters.EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
+
+
+    def _onEVT_SLICER_PARS(self, event):
+        wx.PostEvent(self.base.parent, StatusEvent(status="AnnulusSlicer._onEVT_SLICER_PARS"))
+        event.Skip()
+        if event.type == self.__class__.__name__:
+            self.set_params(event.params)
+            self.base.update()
+
+    def update_and_post(self):
+        self.update()
+        self._post_data()
+
+    def save_data(self, path, image, x, y):
+        output = open(path, 'w')
+        
+        data_x, data_y = self.get_data(image, x, y)
+        
+        output.write("<phi>  <average>\n")
+        for i in range(len(data_x)):
+            output.write("%g  %g\n" % (data_x[i], data_y[i]))
+        output.close()
+
+    def set_layer(self, n):
+        self.layernum = n
+        self.update()
+        
+    def clear(self):
+        self.clear_markers()
+        self.outer_circle.clear()
+        self.inner_circle.clear()
+        #self.base.connect.disconnect()
+        self.base.parent.Unbind(SlicerParameters.EVT_SLICER_PARS)
+        
+    def update(self):
+        """
+        Respond to changes in the model by recalculating the profiles and
+        resetting the widgets.
+        """
+        # Update locations        
+        self.inner_circle.update()
+        self.outer_circle.update()
+        
+  
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.base.freeze_axes()
+        self.inner_circle.save(ev)
+        self.outer_circle.save(ev)
+
+    def _post_data(self):
+         # Compute data
+        data = self.base.data2D
+        # If we have no data, just return
+        if data == None:
+            return
+        
+        from DataLoader.manipulations import SectorPhi
+        radius = math.sqrt(math.pow(self.qmax,2)+math.pow(self.qmax,2))
+        phimin = self.right_line.theta
+        phimax = self.left_line.theta
+        sect = SectorPhi(r_min=-1*radius , r_max= radius , phi_min=phimin, phi_max=phimax)
+        if nbins!=None:
+            sect.nbins = nbins
+        
+        sector = sect(self.base.data2D)
+        
+        from sans.guiframe.dataFitting import Data1D
+        if hasattr(sector,"dxl"):
+            dxl= sector.dxl
+        else:
+            dxl= None
+        if hasattr(sector,"dxw"):
+            dxw= sector.dxw
+        else:
+            dxw= None
+       
+        new_plot = Data1D(x=sector.x,y=sector.y,dy=sector.dy,dxl=dxl,dxw=dxw)
+        new_plot.name = "SectorPhi" +"("+ self.base.data2D.name+")"
+        
+       
+
+        new_plot.source=self.base.data2D.source
+        new_plot.info=self.base.data2D.info
+        new_plot.interactive = True
+        #print "loader output.detector",output.source
+        new_plot.detector =self.base.data2D.detector
+        # If the data file does not tell us what the axes are, just assume...
+        new_plot.xaxis("\\rm{Q}", 'rad')
+        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
+        new_plot.group_id = "SectorPhi"+self.base.data2D.name
+        wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot,
+                                                 title="SectorPhi" ))
+        
+         
+        
+        
+    def moveend(self, ev):
+        self.base.thaw_axes()
+        
+        # Post paramters
+        event = SlicerParameters.SlicerParameterEvent()
+        event.type = self.__class__.__name__
+        event.params = self.get_params()
+        wx.PostEvent(self.base.parent, event)
+
+        self._post_data()
+            
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.inner_circle.restore()
+        self.outer_circle.restore()
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        pass
+        
+    def set_cursor(self, x, y):
+        pass
+        
+    def get_params(self):
+        params = {}
+        params["inner_radius"] = self.inner_circle._inner_mouse_x
+        params["outer_radius"] = self.outer_circle._inner_mouse_x
+        params["nbins"] = self.nbins
+        return params
+    
+    def set_params(self, params):
+        
+        inner = params["inner_radius"] 
+        outer = params["outer_radius"] 
+        self.nbins = int(params["nbins"])
+        self.inner_circle.set_cursor(inner, self.inner_circle._inner_mouse_y)
+        self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y)
+        self._post_data()
+        
+    def freeze_axes(self):
+        self.base.freeze_axes()
+        
+    def thaw_axes(self):
+        self.base.thaw_axes()
+
+    def draw(self):
+        self.base.draw()
+
+        
+class RingInteractor(_BaseInteractor):
+    """
+         Select an annulus through a 2D plot
+    """
+    def __init__(self,base,axes,color='black', zorder=5, r=1.0):
+        
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        self._inner_mouse_x = r
+        self._inner_mouse_y = 0
+        self._inner_save_x  = r
+        self._inner_save_y  = 0
+        self.scale = 10.0
+        
+        try:
+            # Inner circle marker
+            self.inner_marker = self.axes.plot([self._inner_mouse_x],[0], linestyle='',
+                                          marker='s', markersize=10,
+                                          color=self.color, alpha=0.6,
+                                          pickradius=5, label="pick", 
+                                          zorder=zorder, # Prefer this to other lines
+                                          visible=True)[0]
+        except:
+            self.inner_marker = self.axes.plot([self._inner_mouse_x],[0], linestyle='',
+                                          marker='s', markersize=10,
+                                          color=self.color, alpha=0.6,
+                                          label="pick", 
+                                          visible=True)[0]
+            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION OF MATPLOTLIB\n"
+            message += "Get the SVN version that is at least as recent as June 1, 2007"
+            
+            #raise "Version error", message
+            
+        # Inner circle
+
+           
+        [self.inner_circle] = self.axes.plot([],[],
+                                      linestyle='-', marker='',
+                                      color=self.color)
+        self.npts = 20
+            
+        self.connect_markers([self.inner_marker])
+        self.update()
+
+    def set_layer(self, n):
+        self.layernum = n
+        self.update()
+        
+    def clear(self):
+        self.clear_markers()
+        try:
+            self.inner_marker.remove()
+            self.inner_circle.remove()
+        except:
+            # Old version of matplotlib
+            for item in range(len(self.axes.lines)):
+                del self.axes.lines[0]
+        
+        
+        
+    def get_radius(self):
+        return self._inner_mouse_x
+        
+    def update(self):
+        """
+        Draw the new roughness on the graph.
+        """
+        # Plot inner circle
+        x = []
+        y = []
+        for i in range(self.npts):
+            phi = 2.0*math.pi/(self.npts-1)*i
+            
+            xval = 1.0*self._inner_mouse_x*math.cos(phi) 
+            yval = 1.0*self._inner_mouse_x*math.sin(phi) 
+            
+            x.append(xval)
+            y.append(yval)
+        
+        self.inner_marker.set(xdata=[self._inner_mouse_x],ydata=[0])
+        self.inner_circle.set_data(x, y)        
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self._inner_save_x = self._inner_mouse_x
+        self._inner_save_y = self._inner_mouse_y
+        self.base.freeze_axes()
+
+    def moveend(self, ev):
+        self.base.moveend(ev)
+            
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self._inner_mouse_x = self._inner_save_x
+        self._inner_mouse_y = self._inner_save_y
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        self._inner_mouse_x = x
+        self._inner_mouse_y = y
+        self.base.base.update()
+        
+    def set_cursor(self, x, y):
+        self.move(x, y, None)
+        self.update()
+        
+        
+    def get_params(self):
+        params = {}
+        params["radius"] = self._inner_mouse_x
+        return params
+    
+    def set_params(self, params):
+
+        x = params["radius"] 
+        self.set_cursor(x, self._inner_mouse_y)
+        
+        
Index: guiframe/local_perspectives/plotting/AzimutSlicer.py
===================================================================
--- guiframe/local_perspectives/plotting/AzimutSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
+++ guiframe/local_perspectives/plotting/AzimutSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -0,0 +1,276 @@
+#TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it
+#      before pushing a new 1D data update.
+
+#
+#TODO: NEED MAJOR REFACTOR
+#
+
+
+# Debug printout
+
+from BaseInteractor import _BaseInteractor
+from copy import deepcopy
+import math
+
+from sans.guicomm.events import NewPlotEvent, StatusEvent
+import SlicerParameters
+import wx
+
+class SectorInteractor(_BaseInteractor):
+    """
+         Select an annulus through a 2D plot
+    """
+    def __init__(self,base,axes,color='black', zorder=3):
+        
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        self.qmax = self.base.qmax
+        self.connect = self.base.connect
+        
+        ## Number of points on the plot
+        self.nbins = 20
+        theta1=math.pi/8
+        theta2=math.pi/2
+        theta1=2*math.pi/3
+        theta2=-2*math.pi/3
+        r1=self.qmax/2.0
+        r2=self.qmax/1.8
+       
+        # Inner circle
+        from Arc import ArcInteractor
+        self.inner_circle = ArcInteractor(self, self.base.subplot, zorder=zorder, r=self.qmax/2.0,theta1= theta1,
+                                           theta2=theta2)
+        self.inner_circle.qmax = self.base.qmax
+        self.outer_circle = ArcInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax/1.8,theta1= theta1,
+                                           theta2=theta2)
+        self.outer_circle.qmax = self.base.qmax*1.2
+        #self.outer_circle.set_cursor(self.base.qmax/1.8, 0)
+        from Edge import RadiusInteractor
+        self.right_edge= RadiusInteractor(self, self.base.subplot, zorder=zorder+1,
+                                             arc1=self.inner_circle,
+                                             arc2=self.outer_circle,
+                                            theta=theta1)
+        self.left_edge= RadiusInteractor(self, self.base.subplot, zorder=zorder+1,
+                                             arc1=self.inner_circle,
+                                             arc2=self.outer_circle,
+                                            theta=theta2)
+        self.update()
+        self._post_data()
+        # Bind to slice parameter events
+        self.base.parent.Bind(SlicerParameters.EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
+
+
+    def _onEVT_SLICER_PARS(self, event):
+        #printEVT("AnnulusSlicer._onEVT_SLICER_PARS")
+        event.Skip()
+        if event.type == self.__class__.__name__:
+            self.set_params(event.params)
+            self.base.update()
+
+    """
+    def update_and_post(self):
+        self.update()
+        self._post_data()
+
+    """
+    def save_data(self, path, image, x, y):
+        output = open(path, 'w')
+        
+        data_x, data_y = self.get_data(image, x, y)
+        
+        output.write("<phi>  <average>\n")
+        for i in range(len(data_x)):
+            output.write("%g  %g\n" % (data_x[i], data_y[i]))
+        output.close()
+
+    def set_layer(self, n):
+        self.layernum = n
+        self.update()
+        
+    def clear(self):
+        self.clear_markers()
+        self.outer_circle.clear()
+        self.inner_circle.clear()
+        self.right_edge.clear()
+        self.left_edge.clear()
+        #self.base.connect.disconnect()
+        self.base.parent.Unbind(SlicerParameters.EVT_SLICER_PARS)
+        
+    def update(self):
+        """
+        Respond to changes in the model by recalculating the profiles and
+        resetting the widgets.
+        """
+        # Update locations   
+        if self.inner_circle.has_move:    
+            print "inner circle has moved" 
+            self.inner_circle.update()
+            r1=self.inner_circle.get_radius()
+            r2=self.outer_circle.get_radius()
+            self.right_edge.update(r1,r2)
+            self.left_edge.update(r1,r2)
+        if self.outer_circle.has_move:    
+            print "outer circle has moved" 
+            self.outer_circle.update()
+            r1=self.inner_circle.get_radius()
+            r2=self.outer_circle.get_radius()
+            self.left_edge.update(r1,r2)
+            self.right_edge.update(r1,r2)
+        if self.right_edge.has_move:
+            print "right edge has moved"
+            self.right_edge.update()
+            self.inner_circle.update(theta1=self.right_edge.get_angle(), theta2=None)
+            self.outer_circle.update(theta1=self.right_edge.get_angle(), theta2=None)
+        if  self.left_edge.has_move:
+            print "left Edge has moved"
+            self.left_edge.update()
+            self.inner_circle.update(theta1=None, theta2=self.left_edge.get_angle())
+            self.outer_circle.update(theta1=None, theta2=self.left_edge.get_angle())
+             
+        
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.base.freeze_axes()
+        self.inner_circle.save(ev)
+        self.outer_circle.save(ev)
+        self.right_edge.save(ev)
+        self.left_edge.save(ev)
+        
+    def _post_data(self):
+        pass
+    
+    def post_data(self,new_sector ):
+        """ post data averaging in Q"""
+        if self.inner_circle.get_radius() < self.outer_circle.get_radius():
+            rmin=self.inner_circle.get_radius()
+            rmax=self.outer_circle.get_radius()
+        else:
+            rmin=self.outer_circle.get_radius()
+            rmax=self.inner_circle.get_radius()
+        if self.right_edge.get_angle() < self.left_edge.get_angle():
+            phimin=self.right_edge.get_angle()
+            phimax=self.left_edge.get_angle()
+        else:
+            phimin=self.left_edge.get_angle()
+            phimax=self.right_edge.get_angle()
+            
+        print "phimin, phimax, rmin ,rmax",math.degrees(phimin), math.degrees(phimax), rmin ,rmax
+        #from DataLoader.manipulations import SectorQ
+        
+        sect = new_sector(r_min=rmin, r_max=rmax, phi_min=phimin, phi_max=phimax)
+        sector = sect(self.base.data2D)
+        
+        from sans.guiframe.dataFitting import Data1D
+        if hasattr(sector,"dxl"):
+            dxl= sector.dxl
+        else:
+            dxl= None
+        if hasattr(sector,"dxw"):
+            dxw= sector.dxw
+        else:
+            dxw= None
+       
+        new_plot = Data1D(x=sector.x,y=sector.y,dy=sector.dy,dxl=dxl,dxw=dxw)
+        new_plot.name = str(new_sector.__name__) +"("+ self.base.data2D.name+")"
+        
+       
+
+        new_plot.source=self.base.data2D.source
+        new_plot.info=self.base.data2D.info
+        new_plot.interactive = True
+        #print "loader output.detector",output.source
+        new_plot.detector =self.base.data2D.detector
+        # If the data file does not tell us what the axes are, just assume...
+        new_plot.xaxis("\\rm{Q}", 'rad')
+        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
+        new_plot.group_id = str(new_sector.__name__)+self.base.data2D.name
+        wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot,
+                                                 title=str(new_sector.__name__) ))
+        
+        
+    def moveend(self, ev):
+        #self.base.thaw_axes()
+        
+         # Post paramters
+        #event = SlicerParameters.SlicerParameterEvent()
+        #event.type = self.__class__.__name__
+        #event.params = self.get_params()
+        #print "main moveend ", event.params
+        #wx.PostEvent(self.base.parent, event)
+        self._post_data()
+            
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.inner_circle.restore()
+        self.outer_circle.restore()
+        self.right_edge.restore()
+        self.left_edge.restore()
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        pass
+        
+    def set_cursor(self, x, y):
+        pass
+        
+    def get_params(self):
+        params = {}
+        params["r_min"] = self.inner_circle.get_radius()
+        params["r_max"] = self.outer_circle.get_radius()
+        params["phi_min"] = self.right_edge.get_angle()
+        params["phi_max"] = self.left_edge.get_angle()
+        params["nbins"] = self.nbins
+        return params
+    
+    def set_params(self, params):
+        print "setparams on main slicer ",params
+        inner = params["r_min"] 
+        outer = params["r_max"] 
+        phi_min= params["phi_min"]
+        phi_max=params["phi_max"]
+        self.nbins = int(params["nbins"])
+        
+        
+        self.inner_circle.set_cursor(inner, phi_min, phi_max,self.nbins)
+        self.outer_circle.set_cursor(outer,  phi_min, phi_max, self.nbins)
+        self.right_edge.set_cursor(inner, outer, phi_min)
+        self.left_edge.set_cursor(inner, outer, phi_max)
+        self._post_data()
+        
+    def freeze_axes(self):
+        self.base.freeze_axes()
+        
+    def thaw_axes(self):
+        self.base.thaw_axes()
+
+    def draw(self):
+        self.base.draw()
+
+class SectorInteractorQ(SectorInteractor):
+    def __init__(self,base,axes,color='black', zorder=3):
+        SectorInteractor.__init__(self, base, axes, color=color)
+        self.base=base
+        self._post_data()
+    def _post_data(self):
+        from DataLoader.manipulations import SectorQ
+        self.post_data(SectorQ )   
+        
+
+class SectorInteractorPhi(SectorInteractor):
+    def __init__(self,base,axes,color='black', zorder=3):
+        SectorInteractor.__init__(self, base, axes, color=color)
+        self.base=base
+        self._post_data()
+    def _post_data(self):
+        from DataLoader.manipulations import SectorPhi
+        self.post_data(SectorPhi )   
+        
+        
Index: guiframe/local_perspectives/plotting/LineSlicer.py
===================================================================
--- guiframe/local_perspectives/plotting/LineSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
+++ guiframe/local_perspectives/plotting/LineSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -0,0 +1,286 @@
+#TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it
+#      before pushing a new 1D data update.
+
+
+#
+#TODO: NEED MAJOR REFACTOR
+#
+
+# Debug printout
+from sans.guicomm.events import StatusEvent 
+from BaseInteractor import _BaseInteractor
+from copy import deepcopy
+import math
+
+from sans.guicomm.events import NewPlotEvent
+import SlicerParameters
+import wx
+
+class LineInteractor(_BaseInteractor):
+    """
+        Select a slice through a 2D plot
+    """
+    #TODO: get rid of data that is not related to the image
+    # For instance, get rid of access to qmax
+    
+    def __init__(self,base,axes,color='black', zorder=3):
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        self._mouse_x = 0
+        self._mouse_y = self.base.qmax/2
+        self._save_x  = 0
+        self._save_y  = self.base.qmax/2
+        self.scale = 10.0
+        
+        self.npts = 150
+        ## Number of bins on the line
+        self.nbins = 50
+        ## Width of the line
+        self.tolerance = None
+        
+        try:
+            self.marker = self.axes.plot([0],[self.base.qmax/2], linestyle='',
+                                          marker='s', markersize=10,
+                                          color=self.color, alpha=0.6,
+                                          label="pick", 
+                                          zorder=zorder, # Prefer this to other lines
+                                          visible=True)[0]
+        except:
+            self.marker = self.axes.plot([0],[self.base.qmax/2], linestyle='',
+                                          marker='s', markersize=10,
+                                          color=self.color, alpha=0.6,
+                                          pickradius=5, label="pick", 
+                                          visible=True)[0]
+            
+            message  = "\nTHIS PROTOTYPE NEEDS THE LATEST VERSION OF MATPLOTLIB\n"
+            message += "Get the SVN version that is at least as recent as June 1, 2007"
+                          
+        self.line = self.axes.plot([0,0],[0.0,self.base.qmax/2*self.scale],
+                                      linestyle='-', marker='',
+                                      color=self.color,
+                                      visible=True)[0]
+        
+            
+        self.connect_markers([self.marker])
+        self.update()
+        self._post_data()
+        
+        # Bind to slice parameter events
+        self.base.parent.Bind(SlicerParameters.EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
+        
+    def _onEVT_SLICER_PARS(self, event):
+        event.Skip()
+        wx.PostEvent(self.base.parent, StatusEvent(status="LineSlicer._onEVT_SLICER_PARS"))
+        if event.type == self.__class__.__name__:
+            self.set_params(event.params)
+            self.base.update()
+        
+    def update_and_post(self):
+        self.update()
+        self._post_data()
+
+    def save_data(self, path, image, x, y):
+        output = open(path, 'w')
+        
+        data_x, data_y = self.get_data(image, x, y)
+        
+        output.write("<q>  <average>\n")
+        for i in range(len(data_x)):
+            output.write("%g  %g\n" % (data_x[i], data_y[i]))
+        output.close()
+
+
+    def get_event(self, image=None, x=None, y=None):
+        evt = SliceEvent(self._mouse_x, self._mouse_y)
+        evt.type = SliceInteractor
+        if not image==None and not x==None and not y==None:
+            data_x, data_y = self.get_data(image, x, y)
+            evt.data_x = data_x
+            evt.data_y = data_y
+        evt.min_xlim = 0
+        evt.max_xlim = self.base.qmax
+        evt.params = self.get_params()
+        evt.ylabel = r'$\rm{Intensity}\ (cm^{-1})$'
+        evt.xlabel = r'$\rm{q}\ (A^{-1})$'
+
+        return evt
+
+    def set_layer(self, n):
+        self.layernum = n
+        self.update()
+        
+    def clear(self):
+        self.clear_markers()
+        try:
+            self.marker.remove()
+            self.line.remove()
+        except:
+            # Old version of matplotlib
+            for item in range(len(self.axes.lines)):
+                del self.axes.lines[0]
+        
+        # Unbind panel
+        #self.base.connect.disconnect()
+        self.base.parent.Unbind(SlicerParameters.EVT_SLICER_PARS)
+
+        
+    def update(self):
+        """
+        Draw the new roughness on the graph.
+        """
+        self.marker.set(xdata=[self._mouse_x],ydata=[self._mouse_y])
+        self.line.set(xdata=[0,self._mouse_x*self.scale], ydata=[0,self._mouse_y*self.scale])
+
+    def get_data(self, image=None, x=None, y=None):
+        """
+            Return the slice data
+        """
+        #TODO: Computer variance 
+        
+        # If we have no data, just return
+        if image == None:
+            return
+        
+        # Now the slice
+        nbins = self.nbins
+        data_x = nbins*[0]
+        data_y = nbins*[0]
+        counts = nbins*[0]
+        
+        length = len(image)
+        qmax = x[length-1]
+        
+        #TODO: only good for square detector!
+        #data_step = (x[length-1]-x[length-2])/2.0
+        data_step = (x[length-1]-x[length-2])
+        if self.tolerance==None:
+            self.tolerance = data_step
+        else:
+            data_step = self.tolerance
+        
+        #TODO: calculate the slice from the actual matrix 
+        # this must be done for real data
+        print "STEP", data_step
+        for i_x in range(length):
+            for i_y in range(length):
+                    
+                # Check whether that cell touches the line
+                # Careful with the sign of the slope
+                xval = x[i_x]
+                yval = y[i_y]
+                
+                if (self._mouse_x==0 and math.fabs(xval)<data_step) \
+                    or (self._mouse_x>0 and \
+                        math.fabs(yval-xval*self._mouse_y/self._mouse_x)<data_step) \
+                    or (self._mouse_x<0 and \
+                        math.fabs(yval+xval*self._mouse_y/self._mouse_x)<data_step) \
+                    or (self._mouse_y>0 and \
+                        math.fabs(xval-yval*self._mouse_x/self._mouse_y)<data_step) \
+                    or (self._mouse_y<0 and \
+                        math.fabs(xval+yval*self._mouse_x/self._mouse_y)<data_step):
+                    
+                    q = math.sqrt(x[i_x]*x[i_x] + y[i_y]*y[i_y])
+                       
+                    i_bin = int(math.floor(q/(qmax/nbins)))
+                    
+                    # Check for out-of-range q bins (possible in the corners)
+                    if i_bin<nbins:
+                        #data_y[i_bin] += math.exp(image[i_x][i_y])
+                        data_y[i_bin] += image[i_y][i_x]
+                        counts[i_bin] += 1
+                    
+        data_pos_x = []
+        data_pos_y = []
+        for i in range(nbins):
+            data_x[i] = (i+0.5)*qmax/nbins
+            if counts[i]>0:
+                data_y[i] = data_y[i]/counts[i]
+                data_pos_x.append(data_x[i])
+                data_pos_y.append(data_y[i])
+        
+        return data_x, data_y
+
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self._save_x = self._mouse_x
+        self._save_y = self._mouse_y
+        self.base.freeze_axes()
+
+    def _post_data(self):
+        # Compute data
+        data = self.base.get_corrected_data()
+        # If we have no data, just return
+        if data == None:
+            return
+
+        data_x, data_y = self.get_data(data, self.base.x, self.base.y)
+        
+        name = "Line"
+        if hasattr(self.base, "name"):
+            name += " %s" % self.base.name
+        print "data_x", data_x
+        """    
+        wx.PostEvent(self.base.parent, AddPlotEvent(name=name,
+                                               x = data_x,
+                                               y = data_y,
+                                               yscale = 'log',
+                                               variable = 'Q',
+                                               ylabel = "\\rm{Intensity} ",
+                                               yunits = "cm^{-1}",
+                                               xlabel = '\\rm{q} ',
+                                               xunits = 'A^{-1}',
+                                               parent = self.base.__class__.__name__))
+        """
+    def moveend(self, ev):
+        self.base.thaw_axes()
+        
+        # Post paramters
+        event = SlicerParameters.SlicerParameterEvent()
+        event.type = self.__class__.__name__
+        event.params = self.get_params()
+        wx.PostEvent(self.base.parent, event)
+
+        self._post_data()
+            
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self._mouse_x = self._save_x
+        self._mouse_y = self._save_y
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        self._mouse_x = x
+        self._mouse_y = y
+        
+    def set_cursor(self, x, y):
+        self.move(x, y, None)
+        self.update()
+        self._post_data()
+        
+    def get_params(self):
+        params = {}
+        params["x"] = self._mouse_x
+        params["y"] = self._mouse_y
+        params["nbins"] = self.nbins
+        params["line_width"] = self.tolerance
+        return params
+    
+    def set_params(self, params):
+
+        x = params["x"] 
+        y = params["y"] 
+        if "nbins" in params:
+            self.nbins = int(params["nbins"])
+        if "line_width" in params:
+            self.tolerance = params["line_width"]
+        self.set_cursor(x, y)
+        
Index: guiframe/local_perspectives/plotting/Plotter1D.py
===================================================================
--- guiframe/local_perspectives/plotting/Plotter1D.py	(revision ab8f9362c44262da9c2214f86b1311efb77a535f)
+++ guiframe/local_perspectives/plotting/Plotter1D.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -140,6 +140,7 @@
       
         # Set the view scale for all plots
+       
         self._onEVT_FUNC_PROPERTY()
-      
+    
         self.graph.render(self)
         self.subplot.figure.canvas.draw_idle()
Index: guiframe/local_perspectives/plotting/Plotter2D.py
===================================================================
--- guiframe/local_perspectives/plotting/Plotter2D.py	(revision ab8f9362c44262da9c2214f86b1311efb77a535f)
+++ guiframe/local_perspectives/plotting/Plotter2D.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -29,5 +29,5 @@
 DEFAULT_QSTEP = 0.001
 DEFAULT_BEAM = 0.005
-BIN_WIDTH =1
+BIN_WIDTH = 1.0
 import pylab
 from Plotter1D import PanelMenu
@@ -81,5 +81,6 @@
         #self.radius = math.sqrt(data2d.)
         self.qstep = DEFAULT_QSTEP
-        print "panel2D qmax",self.qmax,
+        #print "panel2D qmax",self.qmax,
+        
         self.x = pylab.arange(-1*self.qmax, self.qmax+self.qstep*0.01, self.qstep)
         self.y = pylab.arange(-1*self.imax, self.imax+self.qstep*0.01, self.qstep)
@@ -112,7 +113,7 @@
         if hasattr(event, "reset"):
             self._reset()
-        print "model2 d event",event.plot.name, event.plot.id, event.plot.group_id
-        print "plottable list ",self.plots.keys()
-        print self.plots
+        #print "model2 d event",event.plot.name, event.plot.id, event.plot.group_id
+        #print "plottable list ",self.plots.keys()
+        #print self.plots
         is_new = True
         if event.plot.name in self.plots.keys():
@@ -129,5 +130,5 @@
         if is_new:
             # a new plottable overwrites a plotted one  using the same id
-            print "went here",self.plots.itervalues()
+            #print "went here",self.plots.itervalues()
             for plottable in self.plots.itervalues():
                 if event.plot.id==plottable.id :
@@ -195,9 +196,9 @@
         
         id = wx.NewId()
-        slicerpop.Append(id, '&Sector Q')
+        slicerpop.Append(id, '&Sector [Q view]')
         wx.EVT_MENU(self, id, self.onSectorQ) 
         
         id = wx.NewId()
-        slicerpop.Append(id, '&Sector Phi')
+        slicerpop.Append(id, '&Annulus [Phi view ]')
         wx.EVT_MENU(self, id, self.onSectorPhi) 
       
@@ -306,6 +307,11 @@
         
         from DataLoader.manipulations import CircularAverage
-        Circle = CircularAverage( r_min= 0, r_max= self.qmax, bin_width=BIN_WIDTH )
+        import math
+        self.radius= math.sqrt( math.pow(self.qmax,2)+math.pow(self.qmax,2)) 
+        print "radius?",self.radius
+        Circle = CircularAverage( r_min=0, r_max=self.radius, bin_width=0.001)
+        #Circle = CircularAverage( r_min=0, r_max=13705.0, bin_width=BIN_WIDTH )
         #Circle = CircularAverage( r_min= -1, r_max= 1, bin_width=0.001 )
+        #Circle = CircularAverage( r_min= -1*self.radius, r_max= self.radius, bin_width=0.001 )
         circ = Circle(self.data2D)
         from sans.guiframe.dataFitting import Data1D
@@ -318,5 +324,5 @@
         else:
             dxw= None
-            
+        
         new_plot = Data1D(x=circ.x,y=circ.y,dy=circ.dy,dxl=dxl,dxw=dxw)
         new_plot.name = "Circ avg "+ self.data2D.name
@@ -332,7 +338,7 @@
         new_plot.group_id = "Circ avg "+ self.data2D.name
         self.scale = 'log'
+       
         wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title=new_plot.name))
-        
-        
+       
     def _onEditSlicer(self, event):
         if self.slicer !=None:
@@ -349,7 +355,7 @@
         """
         
-        from SectorSlicer import SectorInteractorQ
+        from SectorSlicer import SectorInteractor
         self.onClearSlicer(event)
-        wx.PostEvent(self.parent, InternalEvent(slicer= SectorInteractorQ))
+        wx.PostEvent(self.parent, InternalEvent(slicer= SectorInteractor))
         
     def onSectorPhi(self, event):
@@ -357,7 +363,7 @@
             Perform sector averaging on Phi
         """
-        from SectorSlicer import SectorInteractorPhi
+        from AnnulusSlicer import AnnulusInteractor
         self.onClearSlicer(event)
-        wx.PostEvent(self.parent, InternalEvent(slicer= SectorInteractorPhi))
+        wx.PostEvent(self.parent, InternalEvent(slicer= AnnulusInteractor))
         
        
Index: guiframe/local_perspectives/plotting/SectorSlicer.py
===================================================================
--- guiframe/local_perspectives/plotting/SectorSlicer.py	(revision cd84dcae89f5f702b6ad8b4626aa2531188ccf0f)
+++ guiframe/local_perspectives/plotting/SectorSlicer.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -8,10 +8,11 @@
 
 # Debug printout
-
+from sans.guicomm.events import StatusEvent 
+from sans.guicomm.events import NewPlotEvent
 from BaseInteractor import _BaseInteractor
 from copy import deepcopy
 import math
 
-from sans.guicomm.events import NewPlotEvent, StatusEvent
+
 import SlicerParameters
 import wx
@@ -31,31 +32,31 @@
         ## Number of points on the plot
         self.nbins = 20
-        theta1=math.pi/8
-        theta2=math.pi/2
-        theta1=2*math.pi/3
-        theta2=-2*math.pi/3
-        r1=self.qmax/2.0
-        r2=self.qmax/1.8
-       
+        self.theta1= math.pi/4
+        self.theta2= math.pi/3
+        self.phi=math.pi/12
+        #self.theta3= 2*self.theta2 -self.theta1
         # Inner circle
-        from Arc import ArcInteractor
-        self.inner_circle = ArcInteractor(self, self.base.subplot, zorder=zorder, r=self.qmax/2.0,theta1= theta1,
-                                           theta2=theta2)
-        self.inner_circle.qmax = self.base.qmax
-        self.outer_circle = ArcInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax/1.8,theta1= theta1,
-                                           theta2=theta2)
-        self.outer_circle.qmax = self.base.qmax*1.2
+        self.main_line = LineInteractor(self, self.base.subplot,color='blue', zorder=zorder, r=self.qmax,
+                                           theta= self.theta2)
+        self.main_line.qmax = self.base.qmax
+        #self.left_line = SectionInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax,
+        #                                   theta1= self.theta1, theta2= self.theta2)
+        #self.left_line.qmax = self.base.qmax
+        self.right_line= SideInteractor(self, self.base.subplot,color='black', zorder=zorder,
+                                     r=self.qmax,
+                                           phi= -1*self.phi,
+                                           theta2=self.theta2)
+        self.right_line.qmax = self.base.qmax
+        self.left_line= SideInteractor(self, self.base.subplot,color='green', zorder=zorder,
+                                     r=self.qmax,
+                                           phi= self.phi,
+                                           theta2=self.theta2)
+        self.left_line.qmax = self.base.qmax
         #self.outer_circle.set_cursor(self.base.qmax/1.8, 0)
-        from Edge import RadiusInteractor
-        self.right_edge= RadiusInteractor(self, self.base.subplot, zorder=zorder+1,
-                                             arc1=self.inner_circle,
-                                             arc2=self.outer_circle,
-                                            theta=theta1)
-        self.left_edge= RadiusInteractor(self, self.base.subplot, zorder=zorder+1,
-                                             arc1=self.inner_circle,
-                                             arc2=self.outer_circle,
-                                            theta=theta2)
+        
+                      
         self.update()
         self._post_data()
+        
         # Bind to slice parameter events
         self.base.parent.Bind(SlicerParameters.EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
@@ -63,5 +64,5 @@
 
     def _onEVT_SLICER_PARS(self, event):
-        #printEVT("AnnulusSlicer._onEVT_SLICER_PARS")
+        wx.PostEvent(self.base.parent, StatusEvent(status="SectorSlicer._onEVT_SLICER_PARS"))
         event.Skip()
         if event.type == self.__class__.__name__:
@@ -69,10 +70,8 @@
             self.base.update()
 
-    """
     def update_and_post(self):
         self.update()
-        self._post_data()
-
-    """
+        #self._post_data()
+
     def save_data(self, path, image, x, y):
         output = open(path, 'w')
@@ -91,8 +90,7 @@
     def clear(self):
         self.clear_markers()
-        self.outer_circle.clear()
-        self.inner_circle.clear()
-        self.right_edge.clear()
-        self.left_edge.clear()
+        self.main_line.clear()
+        self.left_line.clear()
+        self.right_line.clear()
         #self.base.connect.disconnect()
         self.base.parent.Unbind(SlicerParameters.EVT_SLICER_PARS)
@@ -103,31 +101,33 @@
         resetting the widgets.
         """
-        # Update locations   
-        if self.inner_circle.has_move:    
-            print "inner circle has moved" 
-            self.inner_circle.update()
-            r1=self.inner_circle.get_radius()
-            r2=self.outer_circle.get_radius()
-            self.right_edge.update(r1,r2)
-            self.left_edge.update(r1,r2)
-        if self.outer_circle.has_move:    
-            print "outer circle has moved" 
-            self.outer_circle.update()
-            r1=self.inner_circle.get_radius()
-            r2=self.outer_circle.get_radius()
-            self.left_edge.update(r1,r2)
-            self.right_edge.update(r1,r2)
-        if self.right_edge.has_move:
-            print "right edge has moved"
-            self.right_edge.update()
-            self.inner_circle.update(theta1=self.right_edge.get_angle(), theta2=None)
-            self.outer_circle.update(theta1=self.right_edge.get_angle(), theta2=None)
-        if  self.left_edge.has_move:
-            print "left Edge has moved"
-            self.left_edge.update()
-            self.inner_circle.update(theta1=None, theta2=self.left_edge.get_angle())
-            self.outer_circle.update(theta1=None, theta2=self.left_edge.get_angle())
-             
-        
+        # Update locations        
+        
+        #if self.main_line.has_move:
+        #self.main_line.update()   
+        #self.right_line.update()    
+        #self.left_line.update()     
+        if self.main_line.has_move:
+            self.main_line.update()
+            self.right_line.update( delta = self.main_line.get_radius(),mline= self.main_line)
+            self.left_line.update( delta = self.main_line.get_radius() ,mline= self.main_line)
+            print "Main line has moved ---> phi right",math.degrees(self.main_line.theta-self.right_line.theta)
+            print "Main line has moved ---> phi left",math.degrees(self.main_line.theta-self.left_line.theta)
+        if self.left_line.has_move:
+            print "left line has moved --->"
+            self.main_line.update()
+            self.left_line.update(phi=None,delta=None, mline=self.main_line,side=True)
+            #self.right_line.update(-1*delta,linem=self.main_line,linel=self.left_line)
+            self.right_line.update(phi=-1*self.left_line.phi,delta=None, mline=self.main_line,side=True)
+        if self.right_line.has_move:
+            print "right line has moved --->"
+           
+            self.main_line.update()
+            self.right_line.update(phi=None,delta=None, mline=self.main_line,side=True)
+            #self.right_line.update(-1*delta,linem=self.main_line,linel=self.left_line)
+            self.left_line.update(phi=-1*self.right_line.phi,delta=None, mline=self.main_line,side=True)
+   
+    
+    
+
     def save(self, ev):
         """
@@ -138,29 +138,21 @@
         self.inner_circle.save(ev)
         self.outer_circle.save(ev)
-        self.right_edge.save(ev)
-        self.left_edge.save(ev)
-        
-    def _post_data(self):
-        pass
-    
-    def post_data(self,new_sector ):
-        """ post data averaging in Q"""
-        if self.inner_circle.get_radius() < self.outer_circle.get_radius():
-            rmin=self.inner_circle.get_radius()
-            rmax=self.outer_circle.get_radius()
-        else:
-            rmin=self.outer_circle.get_radius()
-            rmax=self.inner_circle.get_radius()
-        if self.right_edge.get_angle() < self.left_edge.get_angle():
-            phimin=self.right_edge.get_angle()
-            phimax=self.left_edge.get_angle()
-        else:
-            phimin=self.left_edge.get_angle()
-            phimax=self.right_edge.get_angle()
-            
-        print "phimin, phimax, rmin ,rmax",math.degrees(phimin), math.degrees(phimax), rmin ,rmax
-        #from DataLoader.manipulations import SectorQ
-        
-        sect = new_sector(r_min=rmin, r_max=rmax, phi_min=phimin, phi_max=phimax)
+
+    def _post_data(self, nbins=None):
+        # Compute data
+        data = self.base.data2D
+        # If we have no data, just return
+        if data == None:
+            return
+
+        name = "Sector "
+        from DataLoader.manipulations import SectorQ
+        radius = math.sqrt(math.pow(self.qmax,2)+math.pow(self.qmax,2))
+        phimin = self.right_line.theta
+        phimax = self.left_line.theta
+        sect = SectorQ(r_min=-1*radius , r_max= radius , phi_min=phimin, phi_max=phimax)
+        if nbins!=None:
+            sect.nbins = nbins
+        
         sector = sect(self.base.data2D)
         
@@ -176,5 +168,5 @@
        
         new_plot = Data1D(x=sector.x,y=sector.y,dy=sector.dy,dxl=dxl,dxw=dxw)
-        new_plot.name = str(new_sector.__name__) +"("+ self.base.data2D.name+")"
+        new_plot.name = "SectorQ" +"("+ self.base.data2D.name+")"
         
        
@@ -188,18 +180,18 @@
         new_plot.xaxis("\\rm{Q}", 'rad')
         new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
-        new_plot.group_id = str(new_sector.__name__)+self.base.data2D.name
+        new_plot.group_id = "SectorQ"+self.base.data2D.name
         wx.PostEvent(self.base.parent, NewPlotEvent(plot=new_plot,
-                                                 title=str(new_sector.__name__) ))
-        
+                                                 title="SectorQ" ))
+        
+         
         
     def moveend(self, ev):
-        #self.base.thaw_axes()
-        
-         # Post paramters
-        #event = SlicerParameters.SlicerParameterEvent()
-        #event.type = self.__class__.__name__
-        #event.params = self.get_params()
-        #print "main moveend ", event.params
-        #wx.PostEvent(self.base.parent, event)
+        self.base.thaw_axes()
+        
+        # Post paramters
+        event = SlicerParameters.SlicerParameterEvent()
+        event.type = self.__class__.__name__
+        event.params = self.get_params()
+        wx.PostEvent(self.base.parent, event)
         self._post_data()
             
@@ -208,8 +200,7 @@
         Restore the roughness for this layer.
         """
-        self.inner_circle.restore()
-        self.outer_circle.restore()
-        self.right_edge.restore()
-        self.left_edge.restore()
+        self.main_line.restore()
+        self.left_line.restore()
+        self.right_line.restore()
 
     def move(self, x, y, ev):
@@ -224,25 +215,23 @@
     def get_params(self):
         params = {}
-        params["r_min"] = self.inner_circle.get_radius()
-        params["r_max"] = self.outer_circle.get_radius()
-        params["phi_min"] = self.right_edge.get_angle()
-        params["phi_max"] = self.left_edge.get_angle()
+        params["main_phi"] = self.main_line.theta
+        if math.fabs(self.left_line.phi) != math.fabs(self.right_line.phi):
+            raise ValueError,"Phi left and phi right are different %f, %f"%(self.left_line.phi, self.right_line.phi)
+        params["left_phi"] = self.left_line.phi
         params["nbins"] = self.nbins
         return params
     
     def set_params(self, params):
-        print "setparams on main slicer ",params
-        inner = params["r_min"] 
-        outer = params["r_max"] 
-        phi_min= params["phi_min"]
-        phi_max=params["phi_max"]
+        
+        main = params["main_phi"] 
+        phi = params["left_phi"] 
         self.nbins = int(params["nbins"])
-        
-        
-        self.inner_circle.set_cursor(inner, phi_min, phi_max,self.nbins)
-        self.outer_circle.set_cursor(outer,  phi_min, phi_max, self.nbins)
-        self.right_edge.set_cursor(inner, outer, phi_min)
-        self.left_edge.set_cursor(inner, outer, phi_max)
-        self._post_data()
+        self.main_line.theta= main
+        
+        self.main_line.update()
+        self.right_line.update(phi=-1*phi,delta=None, mline=self.main_line,side=True)
+        self.left_line.update(phi=phi,delta=None, mline=self.main_line,side=True)
+       
+        self._post_data(nbins=self.nbins)
         
     def freeze_axes(self):
@@ -255,22 +244,260 @@
         self.base.draw()
 
-class SectorInteractorQ(SectorInteractor):
-    def __init__(self,base,axes,color='black', zorder=3):
-        SectorInteractor.__init__(self, base, axes, color=color)
-        self.base=base
-        self._post_data()
-    def _post_data(self):
-        from DataLoader.manipulations import SectorQ
-        self.post_data(SectorQ )   
-        
-
-class SectorInteractorPhi(SectorInteractor):
-    def __init__(self,base,axes,color='black', zorder=3):
-        SectorInteractor.__init__(self, base, axes, color=color)
-        self.base=base
-        self._post_data()
-    def _post_data(self):
-        from DataLoader.manipulations import SectorPhi
-        self.post_data(SectorPhi )   
-        
-        
+        
+class SideInteractor(_BaseInteractor):
+    """
+         Select an annulus through a 2D plot
+    """
+    def __init__(self,base,axes,color='black', zorder=5, r=1.0,phi=math.pi/4, theta2= math.pi/3):
+        
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        
+        self.save_theta = theta2 + phi
+        self.theta=  theta2 + phi
+        self.theta2 = theta2
+        self.radius = r
+        self.phi = phi
+        self.scale = 10.0
+        #print "init for line side theta2, phi, theta",math.degrees(theta2),math.degrees(phi),math.degrees(self.theta) 
+        #raise "Version error", message
+          
+        # Inner circle
+        x1= self.radius*math.cos(self.theta)
+        y1= self.radius*math.sin(self.theta)
+        x2= -1*self.radius*math.cos(self.theta)
+        y2= -1*self.radius*math.sin(self.theta)
+       
+        self.line = self.axes.plot([x1,x2],[y1,y2],
+                                      linestyle='-', marker='',
+                                      color=self.color,
+                                      visible=True)[0]
+       
+        self.npts = 20
+        self.has_move=False
+        self.connect_markers([self.line])
+        #self.update()
+
+    def set_layer(self, n):
+        self.layernum = n
+        self.update()
+        
+    def clear(self):
+        self.clear_markers()
+        try:
+            
+            self.line.remove()
+        except:
+            # Old version of matplotlib
+            for item in range(len(self.axes.lines)):
+                del self.axes.lines[0]
+        
+        
+        
+    def get_radius(self):
+        
+        return self.theta - self.save_theta
+        
+    def update(self,phi=None,delta=None, mline=None,side=False):
+        """
+        Draw the new roughness on the graph.
+        """
+        #print "update left or right ", self.has_move
+        
+        if phi !=None:
+            self.phi = phi
+        if delta==None:
+            delta = 0
+        if side== True:
+            self.theta=  mline.theta + self.phi
+        if mline!=None:
+            self.theta2 = mline.theta
+        #print "U:for line side theta2, phi, theta",math.degrees(self.theta2),math.degrees(self.phi),math.degrees(self.theta) 
+        #if self.theta2 >= self.theta and self.theta>=0:
+        #    print "between 0-pi",math.degrees(self.theta) 
+        
+        x1= self.radius*math.cos(self.theta + delta)
+        y1= self.radius*math.sin(self.theta + delta)
+        x2= -1*self.radius*math.cos(self.theta + delta)
+        y2= -1*self.radius*math.sin(self.theta + delta)
+       
+        
+        self.line.set(xdata=[x1,x2], ydata=[y1,y2])  
+        
+       
+        
+        
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.save_theta= self.theta
+        self.base.freeze_axes()
+
+    def moveend(self, ev):
+        
+        self.has_move=False
+        self.base.moveend(ev)
+            
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.theta = self.save_theta
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        
+        self.theta= math.atan2(y,x)
+        self.phi= self.theta2 - self.theta
+        
+        print "move left or right phi ---theta--thetaM", self.phi, self.theta, self.theta2
+        self.has_move=True
+        self.base.base.update()
+        
+    def set_cursor(self, x, y):
+        self.move(x, y, None)
+        self.update()
+        
+        
+    def get_params(self):
+        params = {}
+        params["radius"] = self.radius
+        params["theta"] = self.theta
+        return params
+    
+    def set_params(self, params):
+
+        x = params["radius"] 
+        self.set_cursor(x, self._inner_mouse_y)
+        
+
+
+        
+        
+class LineInteractor(_BaseInteractor):
+    """
+         Select an annulus through a 2D plot
+    """
+    def __init__(self,base,axes,color='black', zorder=5, r=1.0,theta=math.pi/4):
+        
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        
+        self.save_theta = theta 
+        self.theta= theta
+        
+        self.radius = r
+      
+        self.scale = 10.0
+      
+        #raise "Version error", message
+            
+        # Inner circle
+
+           
+        x1= self.radius*math.cos(self.theta)
+        y1= self.radius*math.sin(self.theta)
+        x2= -1*self.radius*math.cos(self.theta)
+        y2= -1*self.radius*math.sin(self.theta)
+       
+        self.line = self.axes.plot([x1,x2],[y1,y2],
+                                      linestyle='-', marker='',
+                                      color=self.color,
+                                      visible=True)[0]
+      
+        self.npts = 20
+        self.has_move=False
+        self.connect_markers([self.line])
+        self.update()
+
+    def set_layer(self, n):
+        self.layernum = n
+        self.update()
+        
+    def clear(self):
+        self.clear_markers()
+        try:
+            
+            self.line.remove()
+        except:
+            # Old version of matplotlib
+            for item in range(len(self.axes.lines)):
+                del self.axes.lines[0]
+        
+        
+        
+    def get_radius(self):
+        
+        return self.theta - self.save_theta
+        
+    def update(self, theta=None):
+        """
+        Draw the new roughness on the graph.
+        """
+        print "update main line", self.theta
+        if theta !=None:
+            self.theta= theta
+        x1= self.radius*math.cos(self.theta)
+        y1= self.radius*math.sin(self.theta)
+        x2= -1*self.radius*math.cos(self.theta)
+        y2= -1*self.radius*math.sin(self.theta)
+      
+        self.line.set(xdata=[x1,x2], ydata=[y1,y2])  
+     
+        
+        
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.save_theta= self.theta
+        self.base.freeze_axes()
+
+    def moveend(self, ev):
+        
+        self.has_move=False
+        self.base.moveend(ev)
+            
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.theta = self.save_theta
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        
+        self.theta= math.atan2(y,x)
+        print "main_line previous theta --- next theta ",math.degrees(self.save_theta),math.degrees(self.theta)
+        
+        self.has_move=True
+        self.base.base.update()
+        
+    def set_cursor(self, x, y):
+        self.move(x, y, None)
+        self.update()
+        
+        
+    def get_params(self):
+        params = {}
+        params["radius"] = self.radius
+        params["theta"] = self.theta
+        return params
+    
+    def set_params(self, params):
+
+        x = params["radius"] 
+        self.set_cursor(x, self._inner_mouse_y)
+        
+
+
+        
Index: iframe/local_perspectives/plotting/SectorSlicer2.py
===================================================================
--- guiframe/local_perspectives/plotting/SectorSlicer2.py	(revision 768656ee3fc923f226cb348145fb3cfb09f09903)
+++ 	(revision )
@@ -1,515 +1,0 @@
-#TODO: the line slicer should listen to all 2DREFRESH events, get the data and slice it
-#      before pushing a new 1D data update.
-
-#
-#TODO: NEED MAJOR REFACTOR
-#
-
-
-# Debug printout
-from config import printEVT
-from BaseInteractor import _BaseInteractor
-from copy import deepcopy
-import math
-
-from Plotter1D import AddPlotEvent
-import SlicerParameters
-import wx
-
-class SectorInteractor(_BaseInteractor):
-    """
-         Select an annulus through a 2D plot
-    """
-    def __init__(self,base,axes,color='black', zorder=3):
-        
-        _BaseInteractor.__init__(self, base, axes, color=color)
-        self.markers = []
-        self.axes = axes
-        self.qmax = self.base.qmax
-        self.connect = self.base.connect
-        
-        ## Number of points on the plot
-        self.nbins = 20
-        self.theta1= math.pi/4
-        self.theta2= math.pi/3
-        self.phi=math.pi/12
-        #self.theta3= 2*self.theta2 -self.theta1
-        # Inner circle
-        self.main_line = LineInteractor(self, self.base.subplot,color='blue', zorder=zorder, r=self.qmax,
-                                           theta= self.theta2)
-        self.main_line.qmax = self.base.qmax
-        #self.left_line = SectionInteractor(self, self.base.subplot, zorder=zorder+1, r=self.qmax,
-        #                                   theta1= self.theta1, theta2= self.theta2)
-        #self.left_line.qmax = self.base.qmax
-        self.right_line= SideInteractor(self, self.base.subplot,color='black', zorder=zorder,
-                                     r=self.qmax,
-                                           phi= -1*self.phi,
-                                           theta2=self.theta2)
-        self.right_line.qmax = self.base.qmax
-        self.left_line= SideInteractor(self, self.base.subplot,color='green', zorder=zorder,
-                                     r=self.qmax,
-                                           phi= self.phi,
-                                           theta2=self.theta2)
-        self.left_line.qmax = self.base.qmax
-        #self.outer_circle.set_cursor(self.base.qmax/1.8, 0)
-        
-                      
-        #self.update()
-        self._post_data()
-        
-        # Bind to slice parameter events
-        self.base.parent.Bind(SlicerParameters.EVT_SLICER_PARS, self._onEVT_SLICER_PARS)
-
-
-    def _onEVT_SLICER_PARS(self, event):
-        printEVT("AnnulusSlicer._onEVT_SLICER_PARS")
-        event.Skip()
-        if event.type == self.__class__.__name__:
-            #self.set_params(event.params)
-            self.base.update()
-
-    def update_and_post(self):
-        self.update()
-        self._post_data()
-
-    def save_data(self, path, image, x, y):
-        output = open(path, 'w')
-        
-        data_x, data_y = self.get_data(image, x, y)
-        
-        output.write("<phi>  <average>\n")
-        for i in range(len(data_x)):
-            output.write("%g  %g\n" % (data_x[i], data_y[i]))
-        output.close()
-
-    def set_layer(self, n):
-        self.layernum = n
-        self.update()
-        
-    def clear(self):
-        self.clear_markers()
-        self.outer_circle.clear()
-        self.inner_circle.clear()
-        #self.base.connect.disconnect()
-        self.base.parent.Unbind(SlicerParameters.EVT_SLICER_PARS)
-        
-    def update(self):
-        """
-        Respond to changes in the model by recalculating the profiles and
-        resetting the widgets.
-        """
-        # Update locations        
-        
-        #if self.main_line.has_move:
-        #self.main_line.update()   
-        #self.right_line.update()    
-        #self.left_line.update()     
-        if self.main_line.has_move:
-            self.main_line.update()
-            self.right_line.update( delta = self.main_line.get_radius(),mline= self.main_line)
-            self.left_line.update( delta = self.main_line.get_radius() ,mline= self.main_line)
-            print "Main line has moved ---> phi right",math.degrees(self.main_line.theta-self.right_line.theta)
-            print "Main line has moved ---> phi left",math.degrees(self.main_line.theta-self.left_line.theta)
-        if self.left_line.has_move:
-            print "left line has moved --->"
-            self.main_line.update()
-            self.left_line.update(phi=None,delta=None, mline=self.main_line,side=True)
-            #self.right_line.update(-1*delta,linem=self.main_line,linel=self.left_line)
-            self.right_line.update(phi=-1*self.left_line.phi,delta=None, mline=self.main_line,side=True)
-        if self.right_line.has_move:
-            print "right line has moved --->"
-           
-            self.main_line.update()
-            self.right_line.update(phi=None,delta=None, mline=self.main_line,side=True)
-            #self.right_line.update(-1*delta,linem=self.main_line,linel=self.left_line)
-            self.left_line.update(phi=-1*self.right_line.phi,delta=None, mline=self.main_line,side=True)
-    def get_data(self, image, x, y):
-        """ 
-            Return a 1D vector corresponding to the slice
-            @param image: data matrix
-            @param x: x matrix
-            @param y: y matrix
-        """
-        # If we have no data, just return
-        if image == None:
-            return        
-        
-        nbins = self.nbins
-        
-        data_x = nbins*[0]
-        data_y = nbins*[0]
-        counts = nbins*[0]
-        length = len(image)
-        print "length x , y , image", len(x), len(y), length
-        
-        for i_x in range(length):
-            for i_y in range(length):
-                        
-                q = math.sqrt(x[i_x]*x[i_x] + y[i_y]*y[i_y])
-                if (q>self.inner_circle._inner_mouse_x \
-                    and q<self.outer_circle._inner_mouse_x) \
-                    or (q<self.inner_circle._inner_mouse_x \
-                    and q>self.outer_circle._inner_mouse_x):
-                            
-                    i_bin = int(math.ceil(nbins*(math.atan2(y[i_y], x[i_x])+math.pi)/(2.0*math.pi)) - 1)
-                    
-                    
-                    #data_y[i_bin] += math.exp(image[i_x][i_y])
-                    data_y[i_bin] += image[i_y][i_x]
-                    counts[i_bin] += 1.0
-                    
-        for i in range(nbins):
-            data_x[i] = (1.0*i+0.5)*2.0*math.pi/nbins
-            if counts[i]>0:
-                data_y[i] = data_y[i]/counts[i]
-        
-        return data_x, data_y
-
-    def save(self, ev):
-        """
-        Remember the roughness for this layer and the next so that we
-        can restore on Esc.
-        """
-        self.base.freeze_axes()
-        self.inner_circle.save(ev)
-        self.outer_circle.save(ev)
-
-    def _post_data(self):
-        # Compute data
-        data = self.base.get_corrected_data()
-        # If we have no data, just return
-        if data == None:
-            return
-
-        data_x, data_y = self.get_data(data, self.base.x, self.base.y)
-        
-        name = "Ring"
-        if hasattr(self.base, "name"):
-            name += " %s" % self.base.name
-        
-        wx.PostEvent(self.base.parent, AddPlotEvent(name=name,
-                                               x = data_x,
-                                               y = data_y,
-                                               qmin = self.inner_circle._inner_mouse_x,
-                                               qmax = self.outer_circle._inner_mouse_x,
-                                               yscale = 'log',
-                                               variable = 'ANGLE',
-                                               ylabel = "\\rm{Intensity} ",
-                                               yunits = "cm^{-1}",
-                                               xlabel = "\\rm{\phi}",
-                                               xunits = "rad",
-                                               parent = self.base.__class__.__name__))
-                                               
-        
-    def moveend(self, ev):
-        self.base.thaw_axes()
-        
-        # Post paramters
-        event = SlicerParameters.SlicerParameterEvent()
-        event.type = self.__class__.__name__
-        #event.params = self.get_params()
-        wx.PostEvent(self.base.parent, event)
-
-        self._post_data()
-            
-    def restore(self):
-        """
-        Restore the roughness for this layer.
-        """
-        self.inner_circle.restore()
-        self.outer_circle.restore()
-
-    def move(self, x, y, ev):
-        """
-        Process move to a new position, making sure that the move is allowed.
-        """
-        pass
-        
-    def set_cursor(self, x, y):
-        pass
-        
-    def get_params(self):
-        params = {}
-        params["main_phi"] = self.main_line.get_radius()
-        params["left_phi"] = self.left_line.get_radius()
-        
-        params["nbins"] = self.nbins
-        return params
-    
-    def set_params(self, params):
-        
-        main = params["main_phi"] 
-        left = params["left_phi"] 
-       
-        self.nbins = int(params["nbins"])
-        #self.main_line.set_cursor(inner, self.inner_circle._inner_mouse_y)
-        #self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y)
-        self._post_data()
-        
-    def freeze_axes(self):
-        self.base.freeze_axes()
-        
-    def thaw_axes(self):
-        self.base.thaw_axes()
-
-    def draw(self):
-        self.base.draw()
-
-        
-class SideInteractor(_BaseInteractor):
-    """
-         Select an annulus through a 2D plot
-    """
-    def __init__(self,base,axes,color='black', zorder=5, r=1.0,phi=math.pi/4, theta2= math.pi/3):
-        
-        _BaseInteractor.__init__(self, base, axes, color=color)
-        self.markers = []
-        self.axes = axes
-        
-        self.save_theta = theta2 + phi
-        
-        self.theta=  theta2 + phi
-        
-        self.theta2 = theta2
-        
-        self.radius = r
-        
-        self.phi = phi
-        self.scale = 10.0
-        print "init for line side theta2, phi, theta",math.degrees(theta2),math.degrees(phi),math.degrees(self.theta) 
-        #raise "Version error", message
-          
-        # Inner circle
-        x1= self.radius*math.cos(self.theta)
-        y1= self.radius*math.sin(self.theta)
-        x2= -1*self.radius*math.cos(self.theta)
-        y2= -1*self.radius*math.sin(self.theta)
-       
-        self.line = self.axes.plot([x1,x2],[y1,y2],
-                                      linestyle='-', marker='',
-                                      color=self.color,
-                                      visible=True)[0]
-       
-        self.npts = 20
-        self.has_move=False
-        self.connect_markers([self.line])
-        #self.update()
-
-    def set_layer(self, n):
-        self.layernum = n
-        self.update()
-        
-    def clear(self):
-        self.clear_markers()
-        try:
-            
-            self.line.remove()
-        except:
-            # Old version of matplotlib
-            for item in range(len(self.axes.lines)):
-                del self.axes.lines[0]
-        
-        
-        
-    def get_radius(self):
-        
-        return self.theta - self.save_theta
-        
-    def update(self,phi=None,delta=None, mline=None,side=False):
-        """
-        Draw the new roughness on the graph.
-        """
-        #print "update left or right ", self.has_move
-        
-        if phi !=None:
-            self.phi = phi
-        if delta==None:
-            delta = 0
-        if side== True:
-            self.theta=  mline.theta + self.phi
-        if mline!=None:
-            self.theta2 = mline.theta
-        print "U:for line side theta2, phi, theta",math.degrees(self.theta2),math.degrees(self.phi),math.degrees(self.theta) 
-        x1= self.radius*math.cos(self.theta + delta)
-        y1= self.radius*math.sin(self.theta + delta)
-        x2= -1*self.radius*math.cos(self.theta + delta)
-        y2= -1*self.radius*math.sin(self.theta + delta)
-       
-        
-        self.line.set(xdata=[x1,x2], ydata=[y1,y2])  
-        
-       
-        
-        
-    def save(self, ev):
-        """
-        Remember the roughness for this layer and the next so that we
-        can restore on Esc.
-        """
-        self.save_theta= self.theta
-        self.base.freeze_axes()
-
-    def moveend(self, ev):
-        
-        self.has_move=False
-        self.base.moveend(ev)
-            
-    def restore(self):
-        """
-        Restore the roughness for this layer.
-        """
-        self.theta = self.save_theta
-
-    def move(self, x, y, ev):
-        """
-        Process move to a new position, making sure that the move is allowed.
-        """
-        
-        self.theta= math.atan2(y,x)
-        self.phi= self.theta2 - self.theta
-        
-        print "move left or right phi ---theta--thetaM", self.phi, self.theta, self.theta2
-        self.has_move=True
-        self.base.base.update()
-        
-    def set_cursor(self, x, y):
-        self.move(x, y, None)
-        self.update()
-        
-        
-    def get_params(self):
-        params = {}
-        params["radius"] = self.radius
-        params["theta"] = self.theta
-        return params
-    
-    def set_params(self, params):
-
-        x = params["radius"] 
-        self.set_cursor(x, self._inner_mouse_y)
-        
-
-
-        
-        
-class LineInteractor(_BaseInteractor):
-    """
-         Select an annulus through a 2D plot
-    """
-    def __init__(self,base,axes,color='black', zorder=5, r=1.0,theta=math.pi/4):
-        
-        _BaseInteractor.__init__(self, base, axes, color=color)
-        self.markers = []
-        self.axes = axes
-        
-        self.save_theta = theta 
-        self.theta= theta
-        
-        self.radius = r
-      
-        self.scale = 10.0
-      
-        #raise "Version error", message
-            
-        # Inner circle
-
-           
-        x1= self.radius*math.cos(self.theta)
-        y1= self.radius*math.sin(self.theta)
-        x2= -1*self.radius*math.cos(self.theta)
-        y2= -1*self.radius*math.sin(self.theta)
-       
-        self.line = self.axes.plot([x1,x2],[y1,y2],
-                                      linestyle='-', marker='',
-                                      color=self.color,
-                                      visible=True)[0]
-      
-        self.npts = 20
-        self.has_move=False
-        self.connect_markers([self.line])
-        self.update()
-
-    def set_layer(self, n):
-        self.layernum = n
-        self.update()
-        
-    def clear(self):
-        self.clear_markers()
-        try:
-            
-            self.line.remove()
-        except:
-            # Old version of matplotlib
-            for item in range(len(self.axes.lines)):
-                del self.axes.lines[0]
-        
-        
-        
-    def get_radius(self):
-        
-        return self.theta - self.save_theta
-        
-    def update(self):
-        """
-        Draw the new roughness on the graph.
-        """
-        #print "update main line", self.has_move
-        
-        x1= self.radius*math.cos(self.theta)
-        y1= self.radius*math.sin(self.theta)
-        x2= -1*self.radius*math.cos(self.theta)
-        y2= -1*self.radius*math.sin(self.theta)
-      
-        self.line.set(xdata=[x1,x2], ydata=[y1,y2])  
-     
-        
-        
-    def save(self, ev):
-        """
-        Remember the roughness for this layer and the next so that we
-        can restore on Esc.
-        """
-        self.save_theta= self.theta
-        self.base.freeze_axes()
-
-    def moveend(self, ev):
-        
-        self.has_move=False
-        self.base.moveend(ev)
-            
-    def restore(self):
-        """
-        Restore the roughness for this layer.
-        """
-        self.theta = self.save_theta
-
-    def move(self, x, y, ev):
-        """
-        Process move to a new position, making sure that the move is allowed.
-        """
-        
-        self.theta= math.atan2(y,x)
-        print "main_line previous theta --- next theta ",math.degrees(self.save_theta),math.degrees(self.theta)
-        
-        self.has_move=True
-        self.base.base.update()
-        
-    def set_cursor(self, x, y):
-        self.move(x, y, None)
-        self.update()
-        
-        
-    def get_params(self):
-        params = {}
-        params["radius"] = self.radius
-        params["theta"] = self.theta
-        return params
-    
-    def set_params(self, params):
-
-        x = params["radius"] 
-        self.set_cursor(x, self._inner_mouse_y)
-        
-
-
-        
Index: guiframe/local_perspectives/plotting/SlicerParameters.py
===================================================================
--- guiframe/local_perspectives/plotting/SlicerParameters.py	(revision cd84dcae89f5f702b6ad8b4626aa2531188ccf0f)
+++ guiframe/local_perspectives/plotting/SlicerParameters.py	(revision ef0c1700493953c0ec4b1091779caf8c5177bf15)
@@ -10,10 +10,25 @@
 (SlicerParameterEvent, EVT_SLICER_PARS)   = wx.lib.newevent.NewEvent()
 
-class SlicerParameterPanel(wx.Panel):
+
+def format_number(value, high=False):
+    """
+        Return a float in a standardized, human-readable formatted string 
+    """
+    try: 
+        value = float(value)
+    except:
+        return "NaN"
+    
+    if high:
+        return "%-6.4g" % value
+    else:
+        return "%-5.3g" % value
+
+class SlicerParameterPanel(wx.Dialog):
     #TODO: show units
     #TODO: order parameters properly
     
     def __init__(self, parent, *args, **kwargs):
-        wx.Panel.__init__(self, parent, *args, **kwargs)
+        wx.Dialog.__init__(self, parent, *args, **kwargs)
         self.params = {}
         self.parent = parent
@@ -58,6 +73,6 @@
             title = wx.StaticText(self, -1, "Slicer Parameters", style=wx.ALIGN_LEFT)
             self.bck.Add(title, (0,0), (1,2), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=15)
-            
-            n = 1
+            ix = 0
+            iy = 0
             self.parameters = []
             #params = slicer.get_params()
@@ -66,18 +81,26 @@
             
             for item in keys:
-                n += 1
+                iy += 1
+                ix = 0
                 text = wx.StaticText(self, -1, item, style=wx.ALIGN_LEFT)
-                self.bck.Add(text, (n-1,0), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
+                #self.bck.Add(text, (iy,ix), flag = wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border = 15)
+                self.bck.Add(text, (iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
                 ctl = wx.TextCtrl(self, -1, size=(80,20), style=wx.TE_PROCESS_ENTER)
                 
                 ctl.SetToolTipString("Modify the value of %s to change the 2D slicer" % item)
                 
-                
-                ctl.SetValue(str(params[item]))
+                ix = 1
+                ctl.SetValue(format_number(str(params[item])))
                 self.Bind(wx.EVT_TEXT_ENTER, self.onTextEnter)
                 ctl.Bind(wx.EVT_KILL_FOCUS, self.onTextEnter)
                 self.parameters.append([item, ctl])
-                self.bck.Add(ctl, (n-1,1), flag=wx.TOP|wx.BOTTOM, border = 0)
-
+                #self.bck.Add(ctl, (iy,ix), flag=wx.TOP|wx.BOTTOM, border = 0)
+                self.bck.Add(ctl, (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+                
+                ix =3
+                self.bck.Add((20,20), (iy,ix),(1,1), wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+            iy +=1
+            ix = 1
+            self.bck.Add((20,20),(iy,ix),(1,1), wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 15)
         self.bck.Layout()
         self.bck.Fit(self)
