Index: park-1.2.1/park/fitresult.py
===================================================================
--- park-1.2.1/park/fitresult.py	(revision 3570545bb48d1a639dd12458e3c717368477e67b)
+++ park-1.2.1/park/fitresult.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -67,4 +67,5 @@
         improvements.
         """
+        #import traceback; traceback.print_stack()
         self.progress_time = time.time()
         self.progress_percent = 0
@@ -228,4 +229,5 @@
 
     def __str__(self):
+        #import traceback; traceback.print_stack()
         if self.parameters == None: return "No results"
         L = ["P%-3d %s"%(n+1,p.summarize()) for n,p in enumerate(self.parameters)]
Index: run.py
===================================================================
--- run.py	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ run.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -84,4 +84,7 @@
     except: addpath(joinpath(root, '..','periodictable'))
 
+    try: import bumps
+    except: addpath(joinpath(root, '..','bumps'))
+
     # select wx version
     #addpath(os.path.join(root, '..','wxPython-src-3.0.0.0','wxPython'))
Index: src/sans/fit/AbstractFitEngine.py
===================================================================
--- src/sans/fit/AbstractFitEngine.py	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ src/sans/fit/AbstractFitEngine.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -58,4 +58,8 @@
         Fit was aborted.
         """
+
+    # TODO: not sure how these are used, but they are needed for running the fit
+    def update_fit(self, last=False): pass
+    def set_result(self, result=None): self.result = result
 
 class Model:
@@ -217,5 +221,11 @@
         """
         return self.qmin, self.qmax
-        
+
+    def size(self):
+        """
+        Number of measurement points in data set after masking, etc.
+        """
+        return len(self.x)
+
     def residuals(self, fn):
         """
@@ -259,10 +269,7 @@
     def __init__(self, sans_data2d, data=None, err_data=None):
         Data2D.__init__(self, data=data, err_data=err_data)
-        """
-            Data can be initital with a data (sans plottable)
-            or with vectors.
-        """
+        # Data can be initialized with a sans plottable or with vectors.
         self.res_err_image = []
-        self.num_points = data.size
+        self.num_points = 0 # will be set by set_data
         self.idx = []
         self.qmin = None
@@ -306,4 +313,5 @@
         self.idx = (self.idx) & (self.mask)
         self.idx = (self.idx) & (numpy.isfinite(self.data))
+        self.num_points = numpy.sum(self.idx)
 
     def set_smearer(self, smearer):
@@ -339,5 +347,11 @@
         """
         return self.qmin, self.qmax
-     
+
+    def size(self):
+        """
+        Number of measurement points in data set after masking, etc.
+        """
+        return numpy.sum(self.idx)
+
     def residuals(self, fn):
         """
@@ -410,13 +424,13 @@
             raise ValueError, "AbstractFitEngine: Need to set model to fit"
         
-        new_model = model
         if not issubclass(model.__class__, Model):
-            new_model = Model(model, data)
-        
+            model = Model(model, data)
+
+        sasmodel = model.model
         if len(constraints) > 0:
             for constraint in constraints:
                 name, value = constraint
                 try:
-                    new_model.parameterset[str(name)].set(str(value))
+                    model.parameterset[str(name)].set(str(value))
                 except:
                     msg = "Fit Engine: Error occurs when setting the constraint"
@@ -427,5 +441,5 @@
             temp = []
             for item in pars:
-                if item in new_model.model.getParamList():
+                if item in sasmodel.getParamList():
                     temp.append(item)
                     self.param_list.append(item)
@@ -433,22 +447,22 @@
                     
                     msg = "wrong parameter %s used " % str(item)
-                    msg += "to set model %s. Choose " % str(new_model.model.name)
+                    msg += "to set model %s. Choose " % str(sasmodel.name)
                     msg += "parameter name within %s" % \
-                                str(new_model.model.getParamList())
+                                str(sasmodel.getParamList())
                     raise ValueError, msg
               
             #A fitArrange is already created but contains data_list only at id
             if self.fit_arrange_dict.has_key(id):
-                self.fit_arrange_dict[id].set_model(new_model)
+                self.fit_arrange_dict[id].set_model(model)
                 self.fit_arrange_dict[id].pars = pars
             else:
             #no fitArrange object has been create with this id
                 fitproblem = FitArrange()
-                fitproblem.set_model(new_model)
+                fitproblem.set_model(model)
                 fitproblem.pars = pars
                 self.fit_arrange_dict[id] = fitproblem
                 vals = []
                 for name in pars:
-                    vals.append(new_model.model.getParam(name))
+                    vals.append(sasmodel.getParam(name))
                 self.fit_arrange_dict[id].vals = vals
         else:
@@ -634,8 +648,9 @@
             return "No results"
 
-        pars = enumerate(self.model.model.getParamList())
+        sasmodel = self.model.model
+        pars = enumerate(sasmodel.getParamList())
         msg1 = "[Iteration #: %s ]" % self.iterations
         msg3 = "=== goodness of fit: %s ===" % (str(self.fitness))
-        msg2 = ["P%-3d  %s......|.....%s" % (i, v, self.model.model.getParam(v))
+        msg2 = ["P%-3d  %s......|.....%s" % (i, v, sasmodel.getParam(v))
                 for i,v in pars if v in self.param_list]
         msg = [msg1, msg3] + msg2
@@ -645,3 +660,3 @@
         """
         """
-        print self
+        print str(self)
Index: src/sans/fit/BumpsFitting.py
===================================================================
--- src/sans/fit/BumpsFitting.py	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ src/sans/fit/BumpsFitting.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -3,5 +3,4 @@
 """
 import sys
-import copy
 
 import numpy
@@ -13,9 +12,9 @@
 from sans.fit.AbstractFitEngine import FResult
 
-class SansAssembly(object):
+class SasProblem(object):
     """
-    Sans Assembly class a class wrapper to be call in optimizer.leastsq method
+    Wrap the SAS model in a form that can be understood by bumps.
     """
-    def __init__(self, paramlist, model=None, data=None, fitresult=None,
+    def __init__(self, param_list, model=None, data=None, fitresult=None,
                  handler=None, curr_thread=None, msg_q=None):
         """
@@ -25,5 +24,5 @@
         self.model = model
         self.data = data
-        self.paramlist = paramlist
+        self.param_list = param_list
         self.msg_q = msg_q
         self.curr_thread = curr_thread
@@ -37,24 +36,49 @@
     @property
     def dof(self):
-        return self.data.num_points - len(self.paramlist)
+        return self.data.num_points - len(self.param_list)
 
     def summarize(self):
-        return "summarize"
-
-    def nllf(self, pvec=None):
-        residuals = self.residuals(pvec)
+        """
+        Return a stylized list of parameter names and values with range bars
+        suitable for printing.
+        """
+        output = []
+        bounds = self.bounds()
+        for i,p in enumerate(self.getp()):
+            name = self.param_list[i]
+            low,high = bounds[:,i]
+            range = ",".join((("[%g"%low if numpy.isfinite(low) else "(-inf"),
+                              ("%g]"%high if numpy.isfinite(high) else "inf)")))
+            if not numpy.isfinite(p):
+                bar = "*invalid* "
+            else:
+                bar = ['.']*10
+                if numpy.isfinite(high-low):
+                    position = int(9.999999999 * float(p-low)/float(high-low))
+                    if position < 0: bar[0] = '<'
+                    elif position > 9: bar[9] = '>'
+                    else: bar[position] = '|'
+                bar = "".join(bar)
+            output.append("%40s %s %10g in %s"%(name,bar,p,range))
+        return "\n".join(output)
+
+    def nllf(self, p=None):
+        residuals = self.residuals(p)
         return 0.5*numpy.sum(residuals**2)
 
-    def setp(self, params):
-        self.model.set_params(self.paramlist, params)
+    def setp(self, p):
+        for k,v in zip(self.param_list, p):
+            self.model.setParam(k,v)
+        #self.model.set_params(self.param_list, params)
 
     def getp(self):
-        return numpy.asarray(self.model.get_params(self.paramlist))
+        return numpy.array([self.model.getParam(k) for k in self.param_list])
+        #return numpy.asarray(self.model.get_params(self.param_list))
 
     def bounds(self):
-        return numpy.array([self._getrange(p) for p in self.paramlist]).T
+        return numpy.array([self._getrange(p) for p in self.param_list]).T
 
     def labels(self):
-        return self.paramlist
+        return self.param_list
 
     def _getrange(self, p):
@@ -63,5 +87,5 @@
         return the range of parameter
         """
-        lo, hi = self.model.model.details[p][1:3]
+        lo, hi = self.model.details[p][1:3]
         if lo is None: lo = -numpy.inf
         if hi is None: hi = numpy.inf
@@ -69,9 +93,9 @@
 
     def randomize(self, n):
-        pvec = self.getp()
+        p = self.getp()
         # since randn is symmetric and random, doesn't matter
         # point value is negative.
         # TODO: throw in bounds checking!
-        return numpy.random.randn(n, len(self.paramlist))*pvec + pvec
+        return numpy.random.randn(n, len(self.param_list))*p + p
 
     def chisq(self):
@@ -84,10 +108,5 @@
 
         """
-        total = 0
-        for item in self.res:
-            total += item * item
-        if len(self.res) == 0:
-            return None
-        return total / len(self.res)
+        return numpy.sum(self.res**2)/self.dof
 
     def residuals(self, params=None):
@@ -99,8 +118,9 @@
         #import thread
         #print "params", params
-        self.res, self.theory = self.data.residuals(self.model.eval)
-
+        self.res, self.theory = self.data.residuals(self.model.evalDistribution)
+
+        # TODO: this belongs in monitor not residuals calculation
         if self.fitresult is not None:
-            self.fitresult.set_model(model=self.model)
+            #self.fitresult.set_model(model=self.model)
             self.fitresult.residuals = self.res+0
             self.fitresult.iterations += 1
@@ -109,5 +129,5 @@
             #fitness = self.chisq(params=params)
             fitness = self.chisq()
-            self.fitresult.pvec = params
+            self.fitresult.p = params
             self.fitresult.set_fitness(fitness=fitness)
             if self.msg_q is not None:
@@ -131,5 +151,5 @@
     __call__ = residuals
 
-    def check_param_range(self):
+    def _DEAD_check_param_range(self):
         """
         Check the lower and upper bound of the parameter value
@@ -142,6 +162,6 @@
         is_outofbound = False
         # loop through the fit parameters
-        model = self.model.model
-        for p in self.paramlist:
+        model = self.model
+        for p in self.param_list:
             value = model.getParam(p)
             low,high = model.details[p][1:3]
@@ -196,5 +216,5 @@
             raise RuntimeError, msg
         elif len(fitproblem) == 0 :
-            raise RuntimeError, "No Assembly scheduled for Scipy fitting."
+            raise RuntimeError, "No problem scheduled for fitting."
         model = fitproblem[0].get_model()
         if reset_flag:
@@ -203,5 +223,4 @@
                 ind = fitproblem[0].pars.index(name)
                 model.setParam(name, fitproblem[0].vals[ind])
-        listdata = []
         listdata = fitproblem[0].get_data()
         # Concatenate dList set (contains one or more data)before fitting
@@ -209,5 +228,4 @@
 
         self.curr_thread = curr_thread
-        ftol = ftol
 
         result = FResult(model=model, data=data, param_list=self.param_list)
@@ -217,13 +235,14 @@
         if handler is not None:
             handler.set_result(result=result)
-        functor = SansAssembly(paramlist=self.param_list,
-                               model=model,
-                               data=data,
-                               handler=handler,
-                               fitresult=result,
-                               curr_thread=curr_thread,
-                               msg_q=msg_q)
+        problem = SasProblem(param_list=self.param_list,
+                              model=model.model,
+                              data=data,
+                              handler=handler,
+                              fitresult=result,
+                              curr_thread=curr_thread,
+                              msg_q=msg_q)
         try:
-            run_bumps(functor, result)
+            #run_bumps(problem, result, ftol)
+            run_scipy(problem, result, ftol)
         except:
             if hasattr(sys, 'last_type') and sys.last_type == KeyboardInterrupt:
@@ -245,8 +264,11 @@
         return [result]
 
-def run_bumps(problem, result):
+def run_bumps(problem, result, ftol):
     fitopts = fitters.FIT_OPTIONS[fitters.FIT_DEFAULT]
-    fitdriver = fitters.FitDriver(fitopts.fitclass, problem=problem, 
-        abort_test=lambda: False, **fitopts.options)
+    fitclass = fitopts.fitclass
+    options = fitopts.options.copy()
+    options['ftol'] = ftol
+    fitdriver = fitters.FitDriver(fitclass, problem=problem,
+                                  abort_test=lambda: False, **options)
     mapper = SerialMapper 
     fitdriver.mapper = mapper.start_mapper(problem, None)
@@ -256,20 +278,22 @@
         import traceback; traceback.print_exc()
         raise
-    mapper.stop_mapper(fitdriver.mapper)
-    fitdriver.show()
-    #fitdriver.plot()
-    result.fitness = fbest * 2. / len(result.pars) 
-    result.stderr  = numpy.ones(len(result.pars))
-    result.pvec = best 
+    finally:
+        mapper.stop_mapper(fitdriver.mapper)
+    #print "best,fbest",best,fbest,problem.dof
+    result.fitness = 2*fbest/problem.dof
+    #print "fitness",result.fitness
+    result.stderr  = fitdriver.stderr()
+    result.pvec = best
+    # TODO: track success better
     result.success = True
     result.theory = problem.theory
 
-def run_scipy(model, result):
+def run_scipy(model, result, ftol):
     # This import must be here; otherwise it will be confused when more
     # than one thread exist.
     from scipy import optimize
 
-    out, cov_x, _, mesg, success = optimize.leastsq(functor,
-                                                    model.get_params(self.param_list),
+    out, cov_x, _, mesg, success = optimize.leastsq(model.residuals,
+                                                    model.getp(),
                                                     ftol=ftol,
                                                     full_output=1)
@@ -278,8 +302,8 @@
     else:
         stderr = []
-    result.fitness = functor.chisqr()
+    result.fitness = model.chisq()
     result.stderr  = stderr
     result.pvec = out
     result.success = success
-    result.theory = functor.theory
-
+    result.theory = model.theory
+
Index: src/sans/fit/ParkFitting.py
===================================================================
--- src/sans/fit/ParkFitting.py	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ src/sans/fit/ParkFitting.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -93,5 +93,5 @@
 
 
-class Model(park.Model):
+class ParkModel(park.Model):
     """
     PARK wrapper for SANS models.
@@ -391,5 +391,5 @@
         return fitpars
     
-    def all_results(self, result):
+    def extend_results_with_calculated_parameters(self, result):
         """
         Extend result from the fit with the calculated parameters.
@@ -439,10 +439,10 @@
                 # dividing residuals by N in order to be consistent with Scipy
                 m.chisq = numpy.sum(m.residuals**2/N) 
-                resid.append(m.weight*m.residuals/math.sqrt(N))
+                resid.append(m.weight*m.residuals)
         self.residuals = numpy.hstack(resid)
         N = len(self.residuals)
         self.degrees_of_freedom = N-k if N>k else 1
         self.chisq = numpy.sum(self.residuals**2)
-        return self.chisq
+        return self.chisq/self.degrees_of_freedom
     
 class ParkFit(FitEngine):
@@ -505,5 +505,6 @@
             return
         for item in fitproblems:
-            parkmodel = item.get_model()
+            model = item.get_model()
+            parkmodel = ParkModel(model.model, model.data)
             if reset_flag:
                 # reset the initial value; useful for batch
@@ -554,5 +555,6 @@
         localfit = SansFitSimplex()
         localfit.ftol = ftol
-        
+        localfit.xtol = 1e-6
+
         # See `park.fitresult.FitHandler` for details.
         fitter = SansFitMC(localfit=localfit, start_points=1)
@@ -563,5 +565,5 @@
         try:
             result = fit.fit(self.problem, fitter=fitter, handler=handler)
-            self.problem.all_results(result)
+            self.problem.extend_results_with_calculated_parameters(result)
             
         except LinAlgError:
@@ -592,4 +594,6 @@
                             name += '.' + name_split[2].strip()
                         small_result.param_list.append(name)
+                # normalize chisq by degrees of freedom
+                small_result.fitness /= len(small_result.residuals)-len(small_result.pvec)
             result_list.append(small_result)    
         if q != None:
Index: src/sans/fit/ScipyFitting.py
===================================================================
--- src/sans/fit/ScipyFitting.py	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ src/sans/fit/ScipyFitting.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -49,5 +49,5 @@
         if len(self.true_res) == 0:
             return None
-        return total / len(self.true_res)
+        return total / (len(self.true_res) - len(self.paramlist))
 
     def __call__(self, params):
@@ -205,5 +205,5 @@
         _check_param_range(model.model, self.param_list)
         
-        result = FResult(model=model, data=data, param_list=self.param_list)
+        result = FResult(model=model.model, data=data, param_list=self.param_list)
         result.pars = fitproblem[0].pars
         result.fitter_id = self.fitter_id
Index: st/park_integration/test/test_fit_line.py
===================================================================
--- test/park_integration/test/test_fit_line.py	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ 	(revision )
@@ -1,227 +1,0 @@
-"""
-    Unit tests for fitting module 
-    @author Gervaise Alina
-"""
-import unittest
-import math
-
-from sans.fit.AbstractFitEngine import Model
-from sans.dataloader.loader import Loader
-from sans.fit.Fitting import Fit
-from sans.models.LineModel import LineModel
-from sans.models.Constant import Constant
-
-class testFitModule(unittest.TestCase):
-    """ test fitting """
-   
-    def test1(self):
-        """ Fit 1 data (testdata_line.txt)and 1 model(lineModel) """
-        #load data
-        data = Loader().load("testdata_line.txt")
-        data.name = data.filename
-        #Importing the Fit module
-        from bumps import fitters
-        fitters.FIT_DEFAULT = 'dream'
-        print fitters.FIT_OPTIONS['dream'].__dict__
-        fitter = Fit('bumps')
-        # Receives the type of model for the fitting
-        model1  = LineModel()
-        model1.name = "M1"
-        model = Model(model1,data)
-        #fit with scipy test
-        
-        pars1= ['param1','param2']
-        fitter.set_data(data,1)
-        try:fitter.set_model(model,1,pars1)
-        except ValueError,exc:
-            #print "ValueError was correctly raised: "+str(msg)
-            assert str(exc).startswith('wrong parameter')
-        else: raise AssertionError("No error raised for scipy fitting with wrong parameters name to fit")
-        pars1= ['A','B']
-        fitter.set_model(model,1,pars1)
-        fitter.select_problem_for_fit(id=1,value=1)
-        result1, = fitter.fit()
-
-        self.assertTrue( math.fabs(result1.pvec[0]-4)/3 <= result1.stderr[0] )
-        self.assertTrue( math.fabs(result1.pvec[1]-2.5)/3 <= result1.stderr[1])
-        self.assertTrue( result1.fitness/len(data.x) < 2 )
-
-        return
-        #fit with park test
-        fitter = Fit('park')
-        fitter.set_data(data,1)
-        fitter.set_model(model,1,pars1)
-        fitter.select_problem_for_fit(id=1,value=1)
-        result2, = fitter.fit()
-        
-        self.assert_(result2)
-        self.assertTrue( math.fabs(result2.pvec[0]-4)/3 <= result2.stderr[0] ) 
-        self.assertTrue( math.fabs(result2.pvec[1]-2.5)/3 <= result2.stderr[1] )
-        self.assertTrue( result2.fitness/len(data.x) < 2)
-        # compare fit result result for scipy and park
-        self.assertAlmostEquals( result1.pvec[0], result2.pvec[0] )
-        self.assertAlmostEquals( result1.pvec[1],result2.pvec[1] )
-        self.assertAlmostEquals( result1.stderr[0],result2.stderr[0] )
-        self.assertAlmostEquals( result1.stderr[1],result2.stderr[1] )
-        self.assertAlmostEquals( result1.fitness,
-                                 result2.fitness/len(data.x),1 )
-        
-        
-    def test2(self):
-        """ fit 2 data and 2 model with no constrainst"""
-        #load data
-        l = Loader()
-        data1=l.load("testdata_line.txt")
-        data1.name = data1.filename
-      
-        data2=l.load("testdata_line1.txt")
-        data2.name = data2.filename
-     
-        #Importing the Fit module
-        fitter = Fit('scipy')
-        # Receives the type of model for the fitting
-        model11  = LineModel()
-        model11.name= "M1"
-        model22  = LineModel()
-        model11.name= "M2"
-      
-        model1 = Model(model11,data1)
-        model2 = Model(model22,data2)
-        #fit with scipy test
-        pars1= ['A','B']
-        fitter.set_data(data1,1)
-        fitter.set_model(model1,1,pars1)
-        fitter.select_problem_for_fit(id=1,value=0)
-        fitter.set_data(data2,2)
-        fitter.set_model(model2,2,pars1)
-        fitter.select_problem_for_fit(id=2,value=0)
-        
-        try: result1, = fitter.fit()
-        except RuntimeError,msg:
-           assert str(msg)=="No Assembly scheduled for Scipy fitting."
-        else: raise AssertionError,"No error raised for scipy fitting with no model"
-        fitter.select_problem_for_fit(id=1,value=1)
-        fitter.select_problem_for_fit(id=2,value=1)
-        try: result1, = fitter.fit()
-        except RuntimeError,msg:
-           assert str(msg)=="Scipy can't fit more than a single fit problem at a time."
-        else: raise AssertionError,"No error raised for scipy fitting with more than 2 models"
-
-        return
-        #fit with park test
-        fitter = Fit('park')
-        fitter.set_data(data1,1)
-        fitter.set_model(model1,1,pars1)
-        fitter.set_data(data2,2)
-        fitter.set_model(model2,2,pars1)
-        fitter.select_problem_for_fit(id=1,value=1)
-        fitter.select_problem_for_fit(id=2,value=1)
-        R1,R2 = fitter.fit()
-        
-        self.assertTrue( math.fabs(R1.pvec[0]-4)/3 <= R1.stderr[0] )
-        self.assertTrue( math.fabs(R1.pvec[1]-2.5)/3 <= R1.stderr[1] )
-        self.assertTrue( R1.fitness/(len(data1.x)+len(data2.x)) < 2)
-        
-        
-    def test3(self):
-        """ fit 2 data and 2 model with 1 constrainst"""
-        return
-        #load data
-        l = Loader()
-        data1= l.load("testdata_line.txt")
-        data1.name = data1.filename
-        data2= l.load("testdata_cst.txt")
-        data2.name = data2.filename
-       
-        # Receives the type of model for the fitting
-        model11  = LineModel()
-        model11.name= "line"
-        model11.setParam("A", 1.0)
-        model11.setParam("B",1.0)
-        
-        model22  = Constant()
-        model22.name= "cst"
-        model22.setParam("value", 1.0)
-        
-        model1 = Model(model11,data1)
-        model2 = Model(model22,data2)
-        model1.set(A=4)
-        model1.set(B=3)
-        # Constraint the constant value to be equal to parameter B (the real value is 2.5)
-        model2.set(value='line.B')
-        #fit with scipy test
-        pars1= ['A','B']
-        pars2= ['value']
-        
-        #Importing the Fit module
-        fitter = Fit('park')
-        fitter.set_data(data1,1)
-        fitter.set_model(model1,1,pars1)
-        fitter.set_data(data2,2,smearer=None)
-        fitter.set_model(model2,2,pars2)
-        fitter.select_problem_for_fit(id=1,value=1)
-        fitter.select_problem_for_fit(id=2,value=1)
-        
-        R1,R2 = fitter.fit()
-        self.assertTrue( math.fabs(R1.pvec[0]-4.0)/3. <= R1.stderr[0])
-        self.assertTrue( math.fabs(R1.pvec[1]-2.5)/3. <= R1.stderr[1])
-        self.assertTrue( R1.fitness/(len(data1.x)+len(data2.x)) < 2)
-        
-        
-    def test4(self):
-        """ fit 2 data concatenates with limited range of x and  one model """
-            #load data
-        l = Loader()
-        data1 = l.load("testdata_line.txt")
-        data1.name = data1.filename
-        data2 = l.load("testdata_line1.txt")
-        data2.name = data2.filename
-
-        # Receives the type of model for the fitting
-        model1  = LineModel()
-        model1.name= "M1"
-        model1.setParam("A", 1.0)
-        model1.setParam("B",1.0)
-        model = Model(model1,data1)
-      
-        #fit with scipy test
-        pars1= ['A','B']
-        #Importing the Fit module
-        fitter = Fit('scipy')
-        fitter.set_data(data1,1,qmin=0, qmax=7)
-        fitter.set_model(model,1,pars1)
-        fitter.set_data(data2,1,qmin=1,qmax=10)
-        fitter.select_problem_for_fit(id=1,value=1)
-        
-        result1, = fitter.fit()
-        #print(result1)
-        self.assert_(result1)
-
-        self.assertTrue( math.fabs(result1.pvec[0]-4)/3 <= result1.stderr[0] )
-        self.assertTrue( math.fabs(result1.pvec[1]-2.5)/3 <= result1.stderr[1])
-        self.assertTrue( result1.fitness/len(data1.x) < 2 )
-
-        return
-        #fit with park test
-        fitter = Fit('park')
-        fitter.set_data(data1,1,qmin=0, qmax=7)
-        fitter.set_model(model,1,pars1)
-        fitter.set_data(data2,1,qmin=1,qmax=10)
-        fitter.select_problem_for_fit(id=1,value=1)
-        result2, = fitter.fit()
-        
-        self.assert_(result2)
-        self.assertTrue( math.fabs(result2.pvec[0]-4)/3 <= result2.stderr[0] )
-        self.assertTrue( math.fabs(result2.pvec[1]-2.5)/3 <= result2.stderr[1] )
-        self.assertTrue( result2.fitness/len(data1.x) < 2)
-        # compare fit result result for scipy and park
-        self.assertAlmostEquals( result1.pvec[0], result2.pvec[0] )
-        self.assertAlmostEquals( result1.pvec[1],result2.pvec[1] )
-        self.assertAlmostEquals( result1.stderr[0],result2.stderr[0] )
-        self.assertAlmostEquals( result1.stderr[1],result2.stderr[1] )
-        self.assertTrue( result2.fitness/(len(data2.x)+len(data1.x)) < 2 )
-
-
-if __name__ == "__main__":
-    unittest.main()
-    
Index: test/park_integration/test/utest_fit_line.py
===================================================================
--- test/park_integration/test/utest_fit_line.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
+++ test/park_integration/test/utest_fit_line.py	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -0,0 +1,254 @@
+"""
+    Unit tests for fitting module 
+    @author Gervaise Alina
+"""
+import unittest
+import math
+
+from sans.fit.AbstractFitEngine import Model, FitHandler
+from sans.dataloader.loader import Loader
+from sans.fit.Fitting import Fit
+from sans.models.LineModel import LineModel
+from sans.models.Constant import Constant
+
+class testFitModule(unittest.TestCase):
+    """ test fitting """
+
+    def test_bad_pars(self):
+        fitter = Fit('bumps')
+
+        data = Loader().load("testdata_line.txt")
+        data.name = data.filename
+        fitter.set_data(data,1)
+
+        model1  = LineModel()
+        model1.name = "M1"
+        model = Model(model1, data)
+        pars1= ['param1','param2']
+        try:
+            fitter.set_model(model,1,pars1)
+        except ValueError,exc:
+            #print "ValueError was correctly raised: "+str(msg)
+            assert str(exc).startswith('wrong parameter')
+        else:
+            raise AssertionError("No error raised for scipy fitting with wrong parameters name to fit")
+
+    def fit_single(self, fitter_name, isdream=False):
+        fitter = Fit(fitter_name)
+
+        data = Loader().load("testdata_line.txt")
+        data.name = data.filename
+        fitter.set_data(data,1)
+
+        # Receives the type of model for the fitting
+        model1  = LineModel()
+        model1.name = "M1"
+        model = Model(model1,data)
+        #fit with scipy test
+
+        pars1= ['A','B']
+        fitter.set_model(model,1,pars1)
+        fitter.select_problem_for_fit(id=1,value=1)
+        result1, = fitter.fit(handler=FitHandler())
+
+        # The target values were generated from the following statements
+        p,s,fx = result1.pvec, result1.stderr, result1.fitness
+        #print "p0,p1,s0,s1,fx_ = %g, %g, %g, %g, %g"%(p[0],p[1],s[0],s[1],fx)
+        p0,p1,s0,s1,fx_ = 3.68353, 2.61004, 0.336186, 0.105244, 1.20189
+
+        if isdream:
+            # Dream is not a minimizer: just check that the fit is within
+            # uncertainty
+            self.assertTrue( abs(p[0]-p0) <= s0 )
+            self.assertTrue( abs(p[1]-p1) <= s1 )
+        else:
+            self.assertTrue( abs(p[0]-p0) <= 1e-5 )
+            self.assertTrue( abs(p[1]-p1) <= 1e-5 )
+            self.assertTrue( abs(fx-fx_) <= 1e-2 )
+
+    def fit_bumps(self, alg, **opts):
+        #Importing the Fit module
+        from bumps import fitters
+        fitters.FIT_DEFAULT = alg
+        fitters.FIT_OPTIONS[alg].options.update(opts)
+        fitters.FIT_OPTIONS[alg].options.update(monitors=[])
+        #print "fitting",alg,opts
+        #kprint "options",fitters.FIT_OPTIONS[alg].__dict__
+        self.fit_single('bumps', isdream=(alg=='dream'))
+
+    def test_bumps_de(self):
+        self.fit_bumps('de')
+
+    def test_bumps_dream(self):
+        self.fit_bumps('dream', burn=500, steps=100)
+
+    def test_bumps_amoeba(self):
+        self.fit_bumps('amoeba')
+
+    def test_bumps_newton(self):
+        self.fit_bumps('newton')
+
+    def test_scipy(self):
+        #print "fitting scipy"
+        self.fit_single('scipy')
+
+    def test_park(self):
+        #print "fitting park"
+        self.fit_single('park')
+
+        
+    def test2(self):
+        """ fit 2 data and 2 model with no constrainst"""
+        #load data
+        l = Loader()
+        data1=l.load("testdata_line.txt")
+        data1.name = data1.filename
+      
+        data2=l.load("testdata_line1.txt")
+        data2.name = data2.filename
+     
+        #Importing the Fit module
+        fitter = Fit('scipy')
+        # Receives the type of model for the fitting
+        model11  = LineModel()
+        model11.name= "M1"
+        model22  = LineModel()
+        model11.name= "M2"
+      
+        model1 = Model(model11,data1)
+        model2 = Model(model22,data2)
+        #fit with scipy test
+        pars1= ['A','B']
+        fitter.set_data(data1,1)
+        fitter.set_model(model1,1,pars1)
+        fitter.select_problem_for_fit(id=1,value=0)
+        fitter.set_data(data2,2)
+        fitter.set_model(model2,2,pars1)
+        fitter.select_problem_for_fit(id=2,value=0)
+        
+        try: result1, = fitter.fit(handler=FitHandler())
+        except RuntimeError,msg:
+           assert str(msg)=="No Assembly scheduled for Scipy fitting."
+        else: raise AssertionError,"No error raised for scipy fitting with no model"
+        fitter.select_problem_for_fit(id=1,value=1)
+        fitter.select_problem_for_fit(id=2,value=1)
+        try: result1, = fitter.fit(handler=FitHandler())
+        except RuntimeError,msg:
+           assert str(msg)=="Scipy can't fit more than a single fit problem at a time."
+        else: raise AssertionError,"No error raised for scipy fitting with more than 2 models"
+
+        #fit with park test
+        fitter = Fit('park')
+        fitter.set_data(data1,1)
+        fitter.set_model(model1,1,pars1)
+        fitter.set_data(data2,2)
+        fitter.set_model(model2,2,pars1)
+        fitter.select_problem_for_fit(id=1,value=1)
+        fitter.select_problem_for_fit(id=2,value=1)
+        R1,R2 = fitter.fit(handler=FitHandler())
+        
+        self.assertTrue( math.fabs(R1.pvec[0]-4)/3 <= R1.stderr[0] )
+        self.assertTrue( math.fabs(R1.pvec[1]-2.5)/3 <= R1.stderr[1] )
+        self.assertTrue( R1.fitness/(len(data1.x)+len(data2.x)) < 2)
+        
+        
+    def test3(self):
+        """ fit 2 data and 2 model with 1 constrainst"""
+        #load data
+        l = Loader()
+        data1= l.load("testdata_line.txt")
+        data1.name = data1.filename
+        data2= l.load("testdata_cst.txt")
+        data2.name = data2.filename
+       
+        # Receives the type of model for the fitting
+        model11  = LineModel()
+        model11.name= "line"
+        model11.setParam("A", 1.0)
+        model11.setParam("B",1.0)
+        
+        model22  = Constant()
+        model22.name= "cst"
+        model22.setParam("value", 1.0)
+        
+        model1 = Model(model11,data1)
+        model2 = Model(model22,data2)
+        model1.set(A=4)
+        model1.set(B=3)
+        # Constraint the constant value to be equal to parameter B (the real value is 2.5)
+        model2.set(value='line.B')
+        #fit with scipy test
+        pars1= ['A','B']
+        pars2= ['value']
+        
+        #Importing the Fit module
+        fitter = Fit('park')
+        fitter.set_data(data1,1)
+        fitter.set_model(model1,1,pars1)
+        fitter.set_data(data2,2,smearer=None)
+        fitter.set_model(model2,2,pars2)
+        fitter.select_problem_for_fit(id=1,value=1)
+        fitter.select_problem_for_fit(id=2,value=1)
+        
+        R1,R2 = fitter.fit(handler=FitHandler())
+        self.assertTrue( math.fabs(R1.pvec[0]-4.0)/3. <= R1.stderr[0])
+        self.assertTrue( math.fabs(R1.pvec[1]-2.5)/3. <= R1.stderr[1])
+        self.assertTrue( R1.fitness/(len(data1.x)+len(data2.x)) < 2)
+        
+        
+    def test4(self):
+        """ fit 2 data concatenates with limited range of x and  one model """
+            #load data
+        l = Loader()
+        data1 = l.load("testdata_line.txt")
+        data1.name = data1.filename
+        data2 = l.load("testdata_line1.txt")
+        data2.name = data2.filename
+
+        # Receives the type of model for the fitting
+        model1  = LineModel()
+        model1.name= "M1"
+        model1.setParam("A", 1.0)
+        model1.setParam("B",1.0)
+        model = Model(model1,data1)
+      
+        #fit with scipy test
+        pars1= ['A','B']
+        #Importing the Fit module
+        fitter = Fit('scipy')
+        fitter.set_data(data1,1,qmin=0, qmax=7)
+        fitter.set_model(model,1,pars1)
+        fitter.set_data(data2,1,qmin=1,qmax=10)
+        fitter.select_problem_for_fit(id=1,value=1)
+        
+        result1, = fitter.fit(handler=FitHandler())
+        #print(result1)
+        self.assert_(result1)
+
+        self.assertTrue( math.fabs(result1.pvec[0]-4)/3 <= result1.stderr[0] )
+        self.assertTrue( math.fabs(result1.pvec[1]-2.5)/3 <= result1.stderr[1])
+        self.assertTrue( result1.fitness/len(data1.x) < 2 )
+
+        #fit with park test
+        fitter = Fit('park')
+        fitter.set_data(data1,1,qmin=0, qmax=7)
+        fitter.set_model(model,1,pars1)
+        fitter.set_data(data2,1,qmin=1,qmax=10)
+        fitter.select_problem_for_fit(id=1,value=1)
+        result2, = fitter.fit(handler=FitHandler())
+        
+        self.assert_(result2)
+        self.assertTrue( math.fabs(result2.pvec[0]-4)/3 <= result2.stderr[0] )
+        self.assertTrue( math.fabs(result2.pvec[1]-2.5)/3 <= result2.stderr[1] )
+        self.assertTrue( result2.fitness/len(data1.x) < 2)
+        # compare fit result result for scipy and park
+        self.assertAlmostEquals( result1.pvec[0], result2.pvec[0] )
+        self.assertAlmostEquals( result1.pvec[1],result2.pvec[1] )
+        self.assertAlmostEquals( result1.stderr[0],result2.stderr[0] )
+        self.assertAlmostEquals( result1.stderr[1],result2.stderr[1] )
+        self.assertTrue( result2.fitness/(len(data2.x)+len(data1.x)) < 2 )
+
+
+if __name__ == "__main__":
+    unittest.main()
+    
Index: test/pr_inversion/test/test_output.txt
===================================================================
--- test/pr_inversion/test/test_output.txt	(revision 6fe51002a81260397b29374005fb3e465ff93b4a)
+++ test/pr_inversion/test/test_output.txt	(revision 95d58d3a800344be2703a5e297ab0e7b153c6309)
@@ -3,5 +3,5 @@
 #alpha=0.0007
 #chi2=836.797
-#elapsed=0.000168085
+#elapsed=0.00041008
 #qmin=None
 #qmax=None
