Index: DataLoader/manipulations.py
===================================================================
--- DataLoader/manipulations.py	(revision 095ab1b354785ed6a70300456365c222e1701c6b)
+++ DataLoader/manipulations.py	(revision c6f95bb4edfab8543cb8df2aee08afaaccfc1d85)
@@ -132,9 +132,9 @@
         
         # Get data 
-        data = data2D.data 
-        q_data = data2D.q_data 
-        err_data = data2D.err_data
-        qx_data = data2D.qx_data  
-        qy_data = data2D.qy_data 
+        data = data2D.data[numpy.isfinite(data2D.data)]
+        q_data = data2D.q_data[numpy.isfinite(data2D.data)]
+        err_data = data2D.err_data[numpy.isfinite(data2D.data)]
+        qx_data = data2D.qx_data[numpy.isfinite(data2D.data)] 
+        qy_data = data2D.qy_data[numpy.isfinite(data2D.data)]
              
         # Build array of Q intervals
@@ -195,5 +195,6 @@
             
             if err_data == None or err_data[npts]==0.0:
-                err_y[i_q] += frac * frac * math.fabs(data[npts])
+                if data[npts] <0: data[npts] = -data[npts]
+                err_y[i_q] += frac * frac * data[npts]
             else:
                 err_y[i_q] += frac * frac * err_data[npts] * err_data[npts]
@@ -280,9 +281,9 @@
         
         # Get data 
-        data = data2D.data 
-        q_data = data2D.q_data 
-        err_data = data2D.err_data
-        qx_data = data2D.qx_data  
-        qy_data = data2D.qy_data 
+        data = data2D.data[numpy.isfinite(data2D.data)]
+        q_data = data2D.q_data[numpy.isfinite(data2D.data)]
+        err_data = data2D.err_data[numpy.isfinite(data2D.data)]
+        qx_data = data2D.qx_data[numpy.isfinite(data2D.data)] 
+        qy_data = data2D.qy_data[numpy.isfinite(data2D.data)]
    
         y  = 0.0
@@ -312,5 +313,6 @@
             y += frac * data[npts]
             if err_data == None or err_data[npts]==0.0:
-                err_y += frac * frac * math.fabs(data[npts])
+                if data[npts] <0: data[npts] = -data[npts]
+                err_y += frac * frac * data[npts]
             else:
                 err_y += frac * frac * err_data[npts] * err_data[npts]
@@ -389,7 +391,7 @@
         """
         # Get data
-        data = data2D.data 
-        err_data = data2D.err_data 
-        q_data = data2D.q_data 
+        data = data2D.data[numpy.isfinite(data2D.data)]
+        q_data = data2D.q_data[numpy.isfinite(data2D.data)]
+        err_data = data2D.err_data[numpy.isfinite(data2D.data)]
    
         q_data_max = numpy.max(q_data)
@@ -432,5 +434,6 @@
 
             if err_data == None or err_data[npt]==0.0:
-                err_y[i_q] += frac * frac * math.fabs(data_n)
+                if data_n <0: data_n = -data_n
+                err_y[i_q] += frac * frac * data_n
             else:
                 err_y[i_q] += frac * frac * err_data[npt] * err_data[npt]
@@ -442,4 +445,5 @@
         # Average the sums       
         for n in range(nbins):
+            if err_y[n] <0: err_y[n] = -err_y[n]
             err_y[n] = math.sqrt(err_y[n])
                       
@@ -495,10 +499,10 @@
  
         # Get data
-        data = data2D.data 
-        err_data = data2D.err_data 
-        q_data = data2D.q_data 
-        qx_data = data2D.qx_data
-        qy_data = data2D.qy_data  
-     
+        data = data2D.data[numpy.isfinite(data2D.data)]
+        q_data = data2D.q_data[numpy.isfinite(data2D.data)]
+        err_data = data2D.err_data[numpy.isfinite(data2D.data)]
+        qx_data = data2D.qx_data[numpy.isfinite(data2D.data)] 
+        qy_data = data2D.qy_data[numpy.isfinite(data2D.data)]
+        
         q_data_max = numpy.max(q_data)
         
@@ -534,4 +538,5 @@
             
             if err_data == None or err_data[npt] ==0.0:
+                if data_n <0: data_n = -data_n
                 phi_err[i_phi] += frac * frac * math.fabs(data_n)
             else:
@@ -680,11 +685,11 @@
             raise RuntimeError, "Ring averaging only take plottable_2D objects"
         Pi = math.pi
-         
+
         # Get the all data & info
-        data = data2D.data 
-        err_data = data2D.err_data
-        qx_data = data2D.qx_data  
-        qy_data = data2D.qy_data 
-        q_data = data2D.q_data 
+        data = data2D.data[numpy.isfinite(data2D.data)]
+        q_data = data2D.q_data[numpy.isfinite(data2D.data)]
+        err_data = data2D.err_data[numpy.isfinite(data2D.data)]
+        qx_data = data2D.qx_data[numpy.isfinite(data2D.data)] 
+        qy_data = data2D.qy_data[numpy.isfinite(data2D.data)]
         
         #set space for 1d outputs
@@ -757,5 +762,6 @@
 
                 if err_data == None or err_data[n] ==0.0:
-                    y_err[i_bin] += frac * frac * math.fabs(data_n)
+                    if data_n<0: data_n= -data_n
+                    y_err[i_bin] += frac * frac * data_n
                 else:
                     y_err[i_bin] += frac * frac * err_data[n]*err_data[n]
@@ -797,4 +803,5 @@
             @return: Data1D object
         """
+
         return self._agv(data2D, 'phi')
     
@@ -816,4 +823,112 @@
         """
         return self._agv(data2D, 'q2')
+
+class Boxcut(object):
+    """
+        Find a rectangular 2D region of interest.
+    """
+    def __init__(self, x_min=0.0, x_max=0.0, y_min=0.0, y_max=0.0):
+        # Minimum Qx value [A-1]
+        self.x_min = x_min
+        # Maximum Qx value [A-1]
+        self.x_max = x_max
+        # Minimum Qy value [A-1]
+        self.y_min = y_min
+        # Maximum Qy value [A-1]
+        self.y_max = y_max
+
+    def __call__(self, data2D):
+        """
+           Find a rectangular 2D region of interest.
+             
+           @param data2D: Data2D object
+           @return: mask, 1d array (len = len(data)) 
+               with Trues where the data points are inside ROI, otherwise False
+        """
+        mask = self._find(data2D)
+        
+        return mask
+        
+    def _find(self, data2D):
+        """
+             Find a rectangular 2D region of interest. 
+             @param data2D: Data2D object
+             @return: out, 1d array (length = len(data)) 
+               with Trues where the data points are inside ROI, otherwise Falses
+        """
+        if data2D.__class__.__name__ not in ["Data2D", "plottable_2D"]:
+            raise RuntimeError, "Boxcut take only plottable_2D objects"
+        # Get qx_ and qy_data 
+        qx_data = data2D.qx_data
+        qy_data = data2D.qy_data
+        
+        # check whether or not the data point is inside ROI
+        outx = [self.x_min <= qx_data & self.x_max > qx_data]
+        outy = [self.y_min <= qy_data & self.y_max > qy_data]
+
+        return (outx & outy)
+
+class Sectorcut(object):
+    """
+        Defines a sector (major + minor) region on a 2D data set.
+        The sector is defined by phi_min, phi_max,
+        where phi_min and phi_max are defined by the right and left lines wrt central line. 
+       
+        Phi_min and phi_max are given in units of radian 
+        and (phi_max-phi_min) should not be larger than pi
+    """
+    def __init__(self,phi_min=0, phi_max=math.pi):
+        self.phi_min = phi_min
+        self.phi_max = phi_max
+              
+    def __call__(self, data2D):
+        """
+           Perform sector averaging.
+            
+           @param data2D: Data2D object
+           @return: mask, 1d array (len = len(data)) 
+               with Trues where the data points are inside ROI, otherwise False
+        """
+        mask = self._find(data2D)
+        
+        return mask
+        
+    def _find(self, data2D):
+        """
+             Find a rectangular 2D region of interest. 
+             @param data2D: Data2D object
+             @return: out, 1d array (length = len(data)) 
+               with Trues where the data points are inside ROI, otherwise Falses
+        """
+        if data2D.__class__.__name__ not in ["Data2D", "plottable_2D"]:
+            raise RuntimeError, "Sectorcut take only plottable_2D objects" 
+        Pi = math.pi
+        # Get data 
+        qx_data = data2D.qx_data
+        qy_data = data2D.qy_data        
+        phi_data = numpy.zeros(len(qx_data))
+
+        # get phi from data
+        phi_data = numpy.arctan2(qy_data, qy_data)
+        # check for major sector
+        if self.phi_min > self.phi_max:
+            out_major = (self.phi_min <= phi_data) or (self.phi_max > phi_data)
+        else:
+            out_major = (self.phi_min <= phi_data) & (self.phi_max > phi_data)
+            
+        # minor sector
+        # Get the min and max into the region: -pi <= phi < Pi
+        phi_min_minor = flip_phi(self.phi_min)-Pi
+        phi_max_minor = flip_phi(self.phi_max)-Pi
+              
+        # check for minor sector
+        if phi_min_minor > phi_max_minor:
+            out_minor= (phi_min_minor <= phi_data) or (phi_max_minor> phi_data) 
+        else:
+            out_minor = (phi_min_minor <= phi_data) & (phi_max_minor > phi_data) 
+        out = out_major + out_minor
+
+        return out
+
 if __name__ == "__main__": 
 
