Index: Invariant/invariant.py
===================================================================
--- Invariant/invariant.py	(revision 4d270706a911c1f44ade04ced249fad41d170e08)
+++ Invariant/invariant.py	(revision 46d50ca838f57a7da14de1864353361c4f32e681)
@@ -7,5 +7,5 @@
 import numpy
 
-from sans.guiframe.dataFitting import Data1D as LoaderData1D
+from DataLoader.data_info import Data1D as LoaderData1D
 from DataLoader.qsmearing import smear_selection
 
@@ -66,26 +66,17 @@
         """
         self.data  = data
-        x_len = len(self.data.x) -1
-        #fitting range 
-        self.qmin =  self.data.x[0]    
-        if self.qmin == 0:
-            self.qmin = Q_MINIMUM 
-    
-        self.qmax = self.data.x[x_len]
-        #Unsmeared q range
-        self._qmin_unsmeared = 0
-        self._qmax_unsmeared = self.data.x[x_len]
-        
-        #bin for smear data
-        self._first_unsmeared_bin = 0
-        self._last_unsmeared_bin  = x_len
-        
-        # Identify the bin range for the unsmeared and smeared spaces
-        self.idx = (self.data.x >= self.qmin) & (self.data.x <= self.qmax)
-        self.idx_unsmeared = (self.data.x >= self._qmin_unsmeared) \
-                            & (self.data.x <= self._qmax_unsmeared)
-  
+        
+        # Set qmin as the lowest non-zero value
+        self.qmin = Q_MINIMUM
+        for q_value in self.data.x:
+            if q_value>0: 
+                self.qmin = q_value
+                break
+        self.qmax = max(self.data.x)
+       
         #get the smear object of data
         self.smearer = smear_selection( self.data )
+        # Set the q-range information to allow smearing
+        self.set_fit_range()
       
     def set_fit_range(self ,qmin=None, qmax=None):
@@ -101,8 +92,5 @@
         self._qmax_unsmeared = self.qmax    
         
-        self._first_unsmeared_bin = 0
-        self._last_unsmeared_bin  = len(self.data.x)-1
-        
-        if self.smearer!=None:
+        if self.smearer is not None:
             self._first_unsmeared_bin, self._last_unsmeared_bin = self.smearer.get_bin_range(self.qmin, self.qmax)
             self._qmin_unsmeared = self.data.x[self._first_unsmeared_bin]
@@ -119,18 +107,14 @@
            @param power = a fixed, otherwise None
         """
-        power = power
         fx = numpy.zeros(len(self.data.x))
-        one = numpy.ones(len(self.data.x))
-
-        #define dy^2
-        try:
-            sigma = self.data.dy[self.idx_unsmeared ]
-        except:
-            print "The dy data for Invariant calculation should be prepared before get to FitFunctor.fit()..."
-            sigma = one[self.idx_unsmeared ]
-        sigma2 = sigma * sigma
+
+        # Uncertainty
+        if type(self.data.y)==numpy.ndarray and len(self.data.y)==len(self.data.x):
+            sigma = self.data.y
+        else:
+            sigma = numpy.ones(len(self.data.x))
 
         # Compute theory data f(x)
-        fx = self.data.y[self.idx_unsmeared ]/sigma
+        fx[self.idx_unsmeared] = self.data.y[self.idx_unsmeared]/sigma[self.idx_unsmeared]
         ## Smear theory data
         if self.smearer is not None:
@@ -139,12 +123,13 @@
         ##power is given only for function = power_law    
         if power != None:
+            sigma2 = sigma * sigma
             a = -(power)
-            b = (numpy.sum(fx/sigma) - a*numpy.sum(self.data.x[self.idx]/sigma2))/numpy.sum(numpy.ones(len(sigma2))/sigma2)
+            b = (numpy.sum(fx[self.idx]/sigma[self.idx]) - a*numpy.sum(self.data.x[self.idx]/sigma2[self.idx]))/numpy.sum(numpy.ones(len(sigma2[self.idx]))/sigma2[self.idx])
             return a, b
         else:
-            A = numpy.vstack([ self.data.x[self.idx]/sigma,
-                               numpy.ones(len(self.data.x[self.idx]))/sigma]).T
+            A = numpy.vstack([ self.data.x[self.idx]/sigma[self.idx],
+                               numpy.ones(len(self.data.x[self.idx]))/sigma[self.idx]]).T
            
-            a, b = numpy.linalg.lstsq(A, fx)[0]
+            a, b = numpy.linalg.lstsq(A, fx[self.idx])[0]
             return a, b
 
@@ -165,6 +150,6 @@
             Initialize variables
             @param data: data must be of type DataLoader.Data1D
-            @param contrast: contrast value of type float
-            @param pConst: Porod Constant of type float
+            @param background: Background value. The data will be corrected before processing
+            @param scale: Scaling factor for I(q). The data will be corrected before processing
         """
         # Background and scale should be private data member if the only way to
@@ -202,15 +187,11 @@
             #Process only data that inherited from DataLoader.Data_info.Data1D
             raise ValueError,"Data must be of type DataLoader.Data1D"
-        new_data = self._scale * data - self._background
-        try:
-            #All data should pass here.
-            new_data.dy = data.dy
-            new_data.dxl = data.dxl
-            new_data.dxw = data.dxw        
-        except:
-            #in case...
-            new_data.dy = numpy.ones(len(data.x))
-            new_data.dxl = numpy.zeros(len(data.x))
-            new_data.dxw = numpy.zeros(len(data.x))       
+            
+        new_data = (self._scale * data) - self._background
+        
+        # Copy data that is not copied by the operations
+        #TODO: fix this in DataLoader
+        new_data.dxl = data.dxl
+        new_data.dxw = data.dxw        
 
         return new_data
@@ -410,7 +391,4 @@
             note: if data doesn't contain dy assume dy= math.sqrt(data.y)
         """
-        if data is None:
-            data = self.data
-            
         if len(data.x) <= 1 or len(data.y) <= 1 or \
             len(self.data.x) != len(self.data.y):
@@ -548,13 +526,11 @@
         qmin = self._data.x[0]
         qmax = self._data.x[self._low_extrapolation_npts - 1]
-        try:
-            # fit the data with a model to get the appropriate parameters
-            a, b = self._fit(function=self._low_extrapolation_function,
-                              qmin=qmin,
-                              qmax=qmax,
-                              power=self._low_extrapolation_power)
-        except:
-            #raise
-            return None
+        
+        # Extrapolate the low-Q data
+        #TODO: this fit fails. Fix it.
+        a, b = self._fit(function=self._low_extrapolation_function,
+                          qmin=qmin,
+                          qmax=qmax,
+                          power=self._low_extrapolation_power)
         
         #q_start point
Index: Invariant/test/utest_data_handling.py
===================================================================
--- Invariant/test/utest_data_handling.py	(revision 46d50ca838f57a7da14de1864353361c4f32e681)
+++ Invariant/test/utest_data_handling.py	(revision 46d50ca838f57a7da14de1864353361c4f32e681)
@@ -0,0 +1,102 @@
+"""
+This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2010, University of Tennessee
+"""
+import unittest
+import numpy
+from DataLoader.loader import  Loader
+from DataLoader.data_info import Data1D
+from sans.invariant import invariant
+    
+class TestLinearFit(unittest.TestCase):
+    """
+        Test Line fit 
+    """
+    def setUp(self):
+        x = numpy.asarray([1.,2.,3.,4.,5.,6.,7.,8.,9.])
+        y = numpy.asarray([1.,2.,3.,4.,5.,6.,7.,8.,9.])
+        dy = y/10.0
+        
+        self.data = Data1D(x=x,y=y,dy=dy)
+        
+    def test_fit_linear_data(self):
+        """ 
+            Simple linear fit
+        """
+        
+        # Create invariant object. Background and scale left as defaults.
+        fit = invariant.FitFunctor(data=self.data)
+        a,b = fit.fit()
+
+        # Test results
+        self.assertAlmostEquals(a, 1.0, 5)
+        self.assertAlmostEquals(b, 0.0, 5)
+
+    def test_fit_linear_data_with_noise(self):
+        """ 
+            Simple linear fit with noise
+        """
+        import random, math
+        
+        for i in range(len(self.data.y)):
+            self.data.y[i] = self.data.y[i]+.1*random.random()
+            
+        # Create invariant object. Background and scale left as defaults.
+        fit = invariant.FitFunctor(data=self.data)
+        a,b = fit.fit()
+
+        # Test results
+        self.assertTrue(math.fabs(a-1.0)<0.05)
+        self.assertTrue(math.fabs(b)<0.05)        
+    
+    
+class TestInvariantCalculator(unittest.TestCase):
+    """
+        Test Line fit 
+    """
+    def setUp(self):
+        self.data = Loader().load("latex_smeared.xml")[0]
+        
+    def test_initial_data_processing(self):
+        """ 
+            Test whether the background and scale are handled properly 
+            when creating an InvariantCalculator object
+        """
+        length = len(self.data.x)
+        self.assertEqual(length, len(self.data.y))
+        inv = invariant.InvariantCalculator(self.data)
+        
+        self.assertEqual(length, len(inv._data.x))
+        self.assertEqual(inv._data.x[0], self.data.x[0])
+
+        # Now the same thing with a background value
+        bck = 0.1
+        inv = invariant.InvariantCalculator(self.data, background=bck)
+        self.assertEqual(inv._background, bck)
+        
+        self.assertEqual(length, len(inv._data.x))
+        self.assertEqual(inv._data.y[0]+bck, self.data.y[0])
+        
+        # Now the same thing with a scale value
+        scale = 0.1
+        inv = invariant.InvariantCalculator(self.data, scale=scale)
+        self.assertEqual(inv._scale, scale)
+        
+        self.assertEqual(length, len(inv._data.x))
+        self.assertAlmostEqual(inv._data.y[0]/scale, self.data.y[0],7)
+        
+    
+    def test_incompatible_data_class(self):
+        """
+            Check that only classes that inherit from Data1D are allowed as data.
+        """
+        class Incompatible():
+            pass
+        self.assertRaises(ValueError, invariant.InvariantCalculator, Incompatible())
+    
+    
Index: Invariant/test/utest_use_cases.py
===================================================================
--- Invariant/test/utest_use_cases.py	(revision b345c45be108e270cff6dcb0797675590e2a9097)
+++ Invariant/test/utest_use_cases.py	(revision 46d50ca838f57a7da14de1864353361c4f32e681)
@@ -96,17 +96,7 @@
     def test_wrong_data(self):
         """ test receiving Data1D not of type loader"""
-        # That just doesn;t make sense
-        
-        wrong_data= Data1D()
-        invariant.InvariantCalculator(wrong_data)
-        
-        try:
-            self.assertRaises(ValueError,invariant.InvariantCalculator(wrong_data))
-        except ValueError, msg:
-            print "test pass "+ str(msg)
-        else: raise ValueError, "fail to raise exception when expected"
-    
-        print "test"
-        self.assertRaises(ValueError,invariant.InvariantCalculator, wrong_data )
+
+
+        self.assertRaises(ValueError,invariant.InvariantCalculator, Data1D())
         
     def test_use_case_1(self):
