Index: park_integration/docs/Fitting.py
===================================================================
--- park_integration/docs/Fitting.py	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
+++ park_integration/docs/Fitting.py	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
@@ -0,0 +1,141 @@
+#class Fitting
+from sans.guitools.plottables import Data1D
+from Loader import Load
+from scipy import optimize
+from ScipyFitting import ScipyFit
+from ParkFitting import ParkFit
+class Fit:
+    """ 
+        Wrap class that allows to select the fitting type 
+    """  
+    def __init__(self):
+        
+        # To initialize a type of Fit
+        self._engine=None
+          
+    def fit_engine(self,word):
+        """
+            Select the type of Fit 
+            @param word: the keyword to select the fit type 
+        """
+        if word=="scipy":
+            self._engine=ScipyFit()
+        elif word=="park":
+            self._engine=ParkFit()
+        else:
+            raise ValueError, "enter the keyword scipy or park"
+    def returnEngine(self):
+        return self._engine
+    
+    def fit(self,pars, qmin=None, qmax=None):
+        """ Do the fit """
+      
+    def set_model(self,model,Uid):
+        """ Set model """
+       
+    def set_data(self,data,Uid):
+        """ Receive plottable and create a list of data to fit"""
+            
+    def get_model(self,Uid):
+        """ return list of data"""
+    
+    def set_param(self,model, pars):
+        """ Recieve a dictionary of parameter and save it """
+   
+    def add_constraint(self, constraint):
+        """ User specify contraint to fit """
+        
+    def get_constraint(self):
+        """ return the contraint value """
+  
+    def set_constraint(self,constraint):
+        """ 
+            receive a string as a constraint
+            @param constraint: a string used to constraint some parameters to get a 
+                specific value
+        """
+if __name__ == "__main__": 
+    load= Load()
+    # test scipy 
+    """test fit one data set one model with scipy """
+    #load data 
+    load.set_filename("testdata_line.txt")
+    load.set_values()
+    data1 = Data1D(x=[], y=[], dx=None,dy=None)
+    data1.name = "data1"
+    load.load_data(data1)
+    #choose a model
+    from sans.guitools.LineModel import LineModel
+    model  = LineModel()
+    #Create a Fit engine
+    fitter =Fit()
+    fitter.fit_engine('scipy')
+    engine = fitter.returnEngine()
+    
+    #set the model
+    engine.set_model(model,1)
+    engine.set_data(data1,1)
+    
+    print"fit only one data SCIPY:",engine.fit({'A':2,'B':1},None,None)
+    
+    
+    """ test fit one data set one model with park """
+    fitter.fit_engine('scipy')
+    engine = fitter.returnEngine()
+    #set the model
+    engine.set_model(model,1)
+    engine.set_data(data1,1)
+    
+    print"fit only one data PARK:",engine.fit({'A':2,'B':1},None,None)
+    
+    
+    """test fit with 2 data and one model SCIPY:"""
+    # reinitialize the fitter
+    fitter =Fit()
+    #create an engine
+    fitter.fit_engine("scipy")
+    engine=fitter.returnEngine()
+    #set the model for fit
+    engine.set_model(model,2 )
+    #load 1 st data
+    load.set_filename("testdata1.txt")
+    load.set_values()
+    data2 = Data1D(x=[], y=[], dx=None,dy=None)
+    data2.name = "data2"
+    load.load_data(data2)
+    #load  2nd data
+    load.set_filename("testdata2.txt")
+    load.set_values()
+    data3 = Data1D(x=[], y=[], dx=None,dy=None)
+    data3.name = "data2"
+    load.load_data(data3)
+    
+    #set data in the engine
+    engine.set_data(data2,2)
+    engine.set_data(data3,2)
+    print"fit two data SCIPY:",engine.fit({'A':2,'B':1},None,None)
+    
+    """ test fit with 2 data and one model PARK:"""
+    fitter.fit_engine("park")
+    engine=fitter.returnEngine()
+    #set the model for fit
+    engine.set_model(model,2 )
+    #load 1 st data
+    load.set_filename("testdata1.txt")
+    load.set_values()
+    data2 = Data1D(x=[], y=[], dx=None,dy=None)
+    data2.name = "data2"
+    load.load_data(data2)
+    #load  2nd data
+    load.set_filename("testdata2.txt")
+    load.set_values()
+    data3 = Data1D(x=[], y=[], dx=None,dy=None)
+    data3.name = "data2"
+    load.load_data(data3)
+    
+    #set data in the engine
+    engine.set_data(data2,2)
+    engine.set_data(data3,2)
+    print"fit two data PARK:",engine.fit({'A':2,'B':1},None,None)
+    
+  
Index: park_integration/docs/ParkFitting.py
===================================================================
--- park_integration/docs/ParkFitting.py	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
+++ park_integration/docs/ParkFitting.py	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
@@ -0,0 +1,297 @@
+#class Fitting
+import time
+
+import numpy
+import park
+from scipy import optimize
+from park import fit,fitresult
+from park import assembly
+
+from sans.guitools.plottables import Data1D
+#from sans.guitools import plottables
+from Loader import Load
+
+class SansParameter(park.Parameter):
+    """
+    SANS model parameters for use in the PARK fitting service.
+    The parameter attribute value is redirected to the underlying
+    parameter value in the SANS model.
+    """
+    def __init__(self, name, model):
+         self._model, self._name = model,name
+    def _getvalue(self): return self._model.getParam(self.name)
+    def _setvalue(self,value): self._model.setParam(self.name, value)
+    value = property(_getvalue,_setvalue)
+    def _getrange(self):
+        lo,hi = self._model.details[self.name][1:]
+        if lo is None: lo = -numpy.inf
+        if hi is None: hi = numpy.inf
+        return lo,hi
+    def _setrange(self,r):
+        self._model.details[self.name][1:] = r
+    range = property(_getrange,_setrange)
+
+class Model(object):
+    """
+        PARK wrapper for SANS models.
+    """
+    def __init__(self, sans_model):
+        self.model = sans_model
+        sansp = sans_model.getParamList()
+        parkp = [SansParameter(p,sans_model) for p in sansp]
+        self.parameterset = park.ParameterSet(sans_model.name,pars=parkp)
+    def eval(self,x):
+        return self.model.run(x)
+    
+class Data(object):
+    """ Wrapper class  for SANS data """
+    def __init__(self, sans_data):
+        self.x= sans_data.x
+        self.y= sans_data.y
+        self.dx= sans_data.dx
+        self.dy= sans_data.dy
+        self.qmin=None
+        self.qmax=None
+       
+    def setFitRange(self,mini=None,maxi=None):
+        """ to set the fit range"""
+        self.qmin=mini
+        self.qmax=maxi
+        
+    def residuals(self, fn):
+        
+        x,y,dy = [numpy.asarray(v) for v in (self.x,self.y,self.dy)]
+        if self.qmin==None and self.qmax==None: 
+            return (y - fn(x))/dy
+        
+        else:
+            idx = x>=self.qmin & x <= self.qmax
+            return (y[idx] - fn(x[idx]))/dy[idx]
+            
+         
+    def residuals_deriv(self, model, pars=[]):
+        """ Return residual derivatives .in this case just return empty array"""
+        return []
+    
+class FitArrange:
+    def __init__(self):
+        """
+            Store a set of data for a given model to perform the Fit
+            @param model: the model selected by the user
+            @param Ldata: a list of data what the user want to fit
+        """
+        self.model = None
+        self.dList =[]
+        
+    def set_model(self,model):
+        """ set the model """
+        self.model = model
+        
+    def add_data(self,data):
+        """ 
+            @param data: Data to add in the list
+            fill a self.dataList with data to fit
+        """
+        if not data in self.dList:
+            self.dList.append(data)
+            
+    def get_model(self):
+        """ Return the model"""
+        return self.model   
+     
+    def get_data(self):
+        """ Return list of data"""
+        return self.dList 
+      
+    def remove_data(self,data):
+        """
+            Remove one element from the list
+            @param data: Data to remove from the the lsit of data
+        """
+        if data in self.dList:
+            self.dList.remove(data)
+            
+class ParkFit:
+    """ 
+        Performs the Fit.he user determine what kind of data 
+    """
+    def __init__(self,data=[]):
+        #this is a dictionary of FitArrange elements
+        self.fitArrangeList={}
+        #the constraint of the Fit
+        self.constraint =None
+        #Specify the use of scipy or park fit
+        self.fitType =None
+        
+    def createProblem(self,pars={}):
+        """
+            Check the contraint value and specify what kind of fit to use
+            return (M1,D1)
+        """
+        mylist=[]
+        for k,value in self.fitArrangeList.iteritems():
+            couple=()
+            model=value.get_model()
+            parameters= self.set_param(model, pars)
+            model = Model(model)
+            #print "model created",model.parameterset[0].value,model.parameterset[1].value
+            # Make all parameters fitting parameters
+            for p in model.parameterset:
+                p.set([-numpy.inf,numpy.inf])
+                #p.set([-10,10])
+            Ldata=value.get_data()
+            data=self._concatenateData(Ldata)
+            #print "this data",data
+            #print "data.residuals in createProblem",Ldata[0].residuals
+            #print "data.residuals in createProblem",data.residuals
+            #couple1=(model,Ldata[0])
+            #mylist.append(couple1)
+            couple=(model,data)
+            mylist.append(couple)
+        #print mylist
+        return mylist
+        #return model,data
+    
+    def fit(self,pars, qmin=None, qmax=None):
+        """
+             Do the fit 
+        """
+        
+        modelList=self.createProblem(pars)
+        #model,data=self.createProblem()
+        #fitness=assembly.Fitness(model,data)
+        
+        problem =  park.Assembly(modelList)
+        print "problem :",problem[0].parameterset,problem[0].parameterset.fitted
+        #problem[0].parameterset['A'].set([0,1000])
+        #print "problem :",problem[0].parameterset,problem[0].parameterset.fitted
+        fit.fit(problem, handler= fitresult.ConsoleUpdate(improvement_delta=0.1))
+        #fit.fit(problem, handler= fitresult.ConsoleUpdate(improvement_delta=0.1))
+       
+    
+    def set_model(self,model,Uid):
+        """ Set model """
+        
+        if self.fitArrangeList.has_key(Uid):
+            self.fitArrangeList[Uid].set_model(model)
+        else:
+            fitproblem= FitArrange()
+            fitproblem.set_model(model)
+            self.fitArrangeList[Uid]=fitproblem
+        
+    def set_data(self,data,Uid):
+        """ Receive plottable and create a list of data to fit"""
+        data=Data(data)
+        if self.fitArrangeList.has_key(Uid):
+            self.fitArrangeList[Uid].add_data(data)
+        else:
+            fitproblem= FitArrange()
+            fitproblem.add_data(data)
+            self.fitArrangeList[Uid]=fitproblem
+            
+    def get_model(self,Uid):
+        """ return list of data"""
+        return self.fitArrangeList[Uid]
+    
+    def set_param(self,model, pars):
+        """ Recieve a dictionary of parameter and save it """
+        parameters=[]
+        if model==None:
+            raise ValueError, "Cannot set parameters for empty model"
+        else:
+            #for key ,value in pars:
+            for key, value in pars.iteritems():
+                param = Parameter(model, key, value)
+                parameters.append(param)
+        return parameters
+    
+    def add_constraint(self, constraint):
+        """ User specify contraint to fit """
+        self.constraint = str(constraint)
+        
+    def get_constraint(self):
+        """ return the contraint value """
+        return self.constraint
+   
+    def set_constraint(self,constraint):
+        """ 
+            receive a string as a constraint
+            @param constraint: a string used to constraint some parameters to get a 
+                specific value
+        """
+        self.constraint= constraint
+    def _concatenateData(self, listdata=[]):
+        """ concatenate each fields of all Data contains ins listdata
+         return data
+        """
+        if listdata==[]:
+            raise ValueError, " data list missing"
+        else:
+            xtemp=[]
+            ytemp=[]
+            dytemp=[]
+            resid=[]
+            resid_deriv=[]
+            
+            for data in listdata:
+                for i in range(len(data.x)):
+                    if not data.x[i] in xtemp:
+                        xtemp.append(data.x[i])
+                       
+                    if not data.y[i] in ytemp:
+                        ytemp.append(data.y[i])
+                        
+                    if not data.dy[i] in dytemp:
+                        dytemp.append(data.dy[i])
+                    
+                   
+            newplottable= Data1D(xtemp,ytemp,None,dytemp)
+            newdata=Data(newplottable)
+           
+            #print "this is new data",newdata.dy
+            return newdata
+class Parameter:
+    """
+        Class to handle model parameters
+    """
+    def __init__(self, model, name, value=None):
+            self.model = model
+            self.name = name
+            if not value==None:
+                self.model.setParam(self.name, value)
+           
+    def set(self, value):
+        """
+            Set the value of the parameter
+        """
+        self.model.setParam(self.name, value)
+
+    def __call__(self):
+        """ 
+            Return the current value of the parameter
+        """
+        return self.model.getParam(self.name)
+    
+
+      
+if __name__ == "__main__": 
+    load= Load()
+    
+    # test fit one data set one model
+    load.set_filename("testdata_line.txt")
+    load.set_values()
+    data1 = Data1D(x=[], y=[], dx=None,dy=None)
+    data1.name = "data1"
+    load.load_data(data1)
+    fitter =ParkFit()
+    
+    from sans.guitools.LineModel import LineModel
+    model  = LineModel()
+    fitter.set_model(model,1)
+    fitter.set_data(data1,1)
+    
+    print"PARK fit result",fitter.fit({'A':2,'B':1},None,None)
+   
+    
+   
+    
Index: park_integration/docs/ScipyFitting.py
===================================================================
--- park_integration/docs/ScipyFitting.py	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
+++ park_integration/docs/ScipyFitting.py	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
@@ -0,0 +1,282 @@
+#class Fitting
+from sans.guitools.plottables import Data1D
+from Loader import Load
+from scipy import optimize
+#from Fitting import Fit
+
+class FitArrange:
+    def __init__(self):
+        """
+            Store a set of data for a given model to perform the Fit
+            @param model: the model selected by the user
+            @param Ldata: a list of data what the user want to fit
+        """
+        self.model = None
+        self.dList =[]
+        
+    def set_model(self,model):
+        """ set the model """
+        self.model = model
+        
+    def add_data(self,data):
+        """ 
+            @param data: Data to add in the list
+            fill a self.dataList with data to fit
+        """
+        if not data in self.dList:
+            self.dList.append(data)
+            
+    def get_model(self):
+        """ Return the model"""
+        return self.model   
+     
+    def get_data(self):
+        """ Return list of data"""
+        return self.dList 
+      
+    def remove_data(self,data):
+        """
+            Remove one element from the list
+            @param data: Data to remove from the the lsit of data
+        """
+        if data in self.dList:
+            self.dList.remove(data)
+            
+class ScipyFit:
+    """ 
+        Performs the Fit.he user determine what kind of data 
+    """
+    def __init__(self,data=[]):
+        #this is a dictionary of FitArrange elements
+        self.fitArrangeList={}
+        #the constraint of the Fit
+        self.constraint =None
+        #Specify the use of scipy or park fit
+        self.fitType =None
+        
+  
+    
+    def fit(self,pars, qmin=None, qmax=None):
+        """
+             Do the fit 
+        """
+        #for item in self.fitArrangeList.:
+        
+        fitproblem=self.fitArrangeList.values()[0]
+        listdata=[]
+        model = fitproblem.get_model()
+        listdata = fitproblem.get_data()
+        
+        parameters = self.set_param(model,pars)
+       
+        # Do the fit with  data set (contains one or more data) and one model 
+        xtemp,ytemp,dytemp=self._concatenateData( listdata)
+        if qmin==None:
+            qmin= min(xtemp)
+        if qmax==None:
+            qmax= max(xtemp)  
+        chisqr, out, cov = fitHelper(model,parameters, xtemp,ytemp, dytemp ,qmin,qmax)
+        return chisqr, out, cov
+    
+    def _concatenateData(self, listdata=[]):
+        """ concatenate each fields of all data contains ins listdata"""
+        if listdata==[]:
+            raise ValueError, " data list missing"
+        else:
+            xtemp=[]
+            ytemp=[]
+            dytemp=[]
+               
+            for data in listdata:
+                for i in range(len(data.x)):
+                    if not data.x[i] in xtemp:
+                        xtemp.append(data.x[i])
+                       
+                    if not data.y[i] in ytemp:
+                        ytemp.append(data.y[i])
+                        
+                    if not data.dy[i] in dytemp:
+                        dytemp.append(data.dy[i])
+            return xtemp, ytemp,dytemp
+        
+    def set_model(self,model,Uid):
+        """ Set model """
+        if self.fitArrangeList.has_key(Uid):
+            self.fitArrangeList[Uid].set_model(model)
+        else:
+            fitproblem= FitArrange()
+            fitproblem.set_model(model)
+            self.fitArrangeList[Uid]=fitproblem
+        
+    def set_data(self,data,Uid):
+        """ Receive plottable and create a list of data to fit"""
+        
+        if self.fitArrangeList.has_key(Uid):
+            self.fitArrangeList[Uid].add_data(data)
+        else:
+            fitproblem= FitArrange()
+            fitproblem.add_data(data)
+            self.fitArrangeList[Uid]=fitproblem
+            
+    def get_model(self,Uid):
+        """ return list of data"""
+        return self.fitArrangeList[Uid]
+    
+    def set_param(self,model, pars):
+        """ Recieve a dictionary of parameter and save it """
+        parameters=[]
+        if model==None:
+            raise ValueError, "Cannot set parameters for empty model"
+        else:
+            #for key ,value in pars:
+            for key, value in pars.iteritems():
+                param = Parameter(model, key, value)
+                parameters.append(param)
+        return parameters
+    
+    def add_constraint(self, constraint):
+        """ User specify contraint to fit """
+        self.constraint = str(constraint)
+        
+    def get_constraint(self):
+        """ return the contraint value """
+        return self.constraint
+   
+    def set_constraint(self,constraint):
+        """ 
+            receive a string as a constraint
+            @param constraint: a string used to constraint some parameters to get a 
+                specific value
+        """
+        self.constraint= constraint
+    
+    def createProblem(self):
+        """
+            Check the contraint value and specify what kind of fit to use
+        """
+        mylist=[]
+        for k,value in self.fitArrangeList.iteritems():
+            couple=()
+            model=value.get_model()
+            data=value.get_data()
+            couple=(model,data)
+            mylist.append(couple)
+        #print mylist
+        return mylist
+    
+                
+
+class Parameter:
+    """
+        Class to handle model parameters
+    """
+    def __init__(self, model, name, value=None):
+            self.model = model
+            self.name = name
+            if not value==None:
+                self.model.setParam(self.name, value)
+           
+    def set(self, value):
+        """
+            Set the value of the parameter
+        """
+        self.model.setParam(self.name, value)
+
+    def __call__(self):
+        """ 
+            Return the current value of the parameter
+        """
+        return self.model.getParam(self.name)
+    
+def fitHelper(model, pars, x, y, err_y ,qmin=None, qmax=None):
+    """
+        Fit function
+        @param model: sans model object
+        @param pars: list of parameters
+        @param x: vector of x data
+        @param y: vector of y data
+        @param err_y: vector of y errors 
+    """
+    def f(params):
+        """
+            Calculates the vector of residuals for each point 
+            in y for a given set of input parameters.
+            @param params: list of parameter values
+            @return: vector of residuals
+        """
+        i = 0
+        for p in pars:
+            p.set(params[i])
+            i += 1
+        
+        residuals = []
+        for j in range(len(x)):
+            if x[j]>qmin and x[j]<qmax:
+                residuals.append( ( y[j] - model.runXY(x[j]) ) / err_y[j] )
+       
+        return residuals
+        
+    def chi2(params):
+        """
+            Calculates chi^2
+            @param params: list of parameter values
+            @return: chi^2
+        """
+        sum = 0
+        res = f(params)
+        for item in res:
+            sum += item*item
+        return sum
+        
+    p = [param() for param in pars]
+    out, cov_x, info, mesg, success = optimize.leastsq(f, p, full_output=1, warning=True)
+    print info, mesg, success
+    # Calculate chi squared
+    if len(pars)>1:
+        chisqr = chi2(out)
+    elif len(pars)==1:
+        chisqr = chi2([out])
+        
+    return chisqr, out, cov_x    
+
+      
+if __name__ == "__main__": 
+    load= Load()
+    
+    # test fit one data set one model
+    load.set_filename("testdata_line.txt")
+    load.set_values()
+    data1 = Data1D(x=[], y=[], dx=None,dy=None)
+    data1.name = "data1"
+    load.load_data(data1)
+    fitter =ScipyFit()
+    from sans.guitools.LineModel import LineModel
+    model  = LineModel()
+    fitter.set_model(model,1)
+    fitter.set_data(data1,1)
+    
+    chisqr, out, cov=fitter.fit({'A':2,'B':1},None,None)
+    print "my list of param",fitter.createProblem()
+    print"fit only one data",chisqr, out, cov 
+    print "this model list of param",model.getParamList()
+    # test fit with 2 data and one model
+    fitter =ScipyFit()
+   
+    fitter.set_model(model,2 )
+    load.set_filename("testdata1.txt")
+    load.set_values()
+    data2 = Data1D(x=[], y=[], dx=None,dy=None)
+    data2.name = "data2"
+    
+    load.load_data(data2)
+    fitter.set_data(data2,2)
+    
+    load.set_filename("testdata2.txt")
+    load.set_values()
+    data3 = Data1D(x=[], y=[], dx=None,dy=None)
+    data3.name = "data2"
+    load.load_data(data3)
+    fitter.set_data(data3,2)
+    chisqr, out, cov=fitter.fit({'A':2,'B':1},None,None)
+    print"fit two data",chisqr, out, cov 
+    
Index: park_integration/docs/testdata1.txt
===================================================================
--- park_integration/docs/testdata1.txt	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
+++ park_integration/docs/testdata1.txt	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
@@ -0,0 +1,26 @@
+0  2.83954  0.6
+0.204082  3.44938  0.676531
+0.408163  5.82026  0.753061
+0.612245  5.27591  0.829592
+0.816327  5.2781  0.906122
+1.02041  5.22531  0.982653
+1.22449  7.47487  1.05918
+1.42857  7.85852  1.13571
+1.63265  10.2278  1.21224
+1.83673  8.33195  1.28878
+2.04082  9.22407  1.36531
+2.2449  7.95013  1.44184
+2.44898  10.0289  1.51837
+2.65306  11.0736  1.5949
+2.85714  12.2957  1.67143
+3.06122  12.3108  1.74796
+3.26531  12.6916  1.82449
+3.46939  12.5859  1.90102
+3.67347  14.5972  1.97755
+3.87755  10.9443  2.05408
+4.08163  11.4356  2.13061
+4.28571  19.3213  2.20714
+4.4898  14.3191  2.28367
+4.69388  14.6961  2.3602
+4.89796  19.27  2.43673
+6.12245  22.1974  2.89592
Index: park_integration/docs/testdata2.txt
===================================================================
--- park_integration/docs/testdata2.txt	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
+++ park_integration/docs/testdata2.txt	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
@@ -0,0 +1,18 @@
+6.53061  19.8174  3.04898
+6.73469  17.6186  3.12551
+6.93878  21.329  3.20204
+7.14286  20.2873  3.27857
+7.34694  23.4112  3.3551
+7.55102  26.063  3.43163
+7.7551  29.8775  3.50816
+7.95918  19.0027  3.58469
+8.16327  19.4248  3.66122
+8.36735  27.4876  3.73776
+8.57143  33.8399  3.81429
+8.77551  24.2611  3.89082
+8.97959  29.8796  3.96735
+9.18367  24.6149  4.04388
+9.38776  35.7664  4.12041
+9.59184  32.145  4.19694
+9.79592  24.8085  4.27347
+10  31.3767  4.35
Index: park_integration/docs/testdata_line.txt
===================================================================
--- park_integration/docs/testdata_line.txt	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
+++ park_integration/docs/testdata_line.txt	(revision 37016209ffd0148fb919b1b4fb8e701408c44e0f)
@@ -0,0 +1,53 @@
+#y=A*x+B
+#A=2.5
+#B=4
+0  2.83954  0.6
+0.204082  3.44938  0.676531
+0.408163  5.82026  0.753061
+0.612245  5.27591  0.829592
+0.816327  5.2781  0.906122
+1.02041  5.22531  0.982653
+1.22449  7.47487  1.05918
+1.42857  7.85852  1.13571
+1.63265  10.2278  1.21224
+1.83673  8.33195  1.28878
+2.04082  9.22407  1.36531
+2.2449  7.95013  1.44184
+2.44898  10.0289  1.51837
+2.65306  11.0736  1.5949
+2.85714  12.2957  1.67143
+3.06122  12.3108  1.74796
+3.26531  12.6916  1.82449
+3.46939  12.5859  1.90102
+3.67347  14.5972  1.97755
+3.87755  10.9443  2.05408
+4.08163  11.4356  2.13061
+4.28571  19.3213  2.20714
+4.4898  14.3191  2.28367
+4.69388  14.6961  2.3602
+4.89796  19.27  2.43673
+5.10204  12.1831  2.51327
+5.30612  21.4745  2.5898
+5.5102  20.0393  2.66633
+5.71429  13.2472  2.74286
+5.91837  14.9428  2.81939
+6.12245  22.1974  2.89592
+6.32653  17.3418  2.97245
+6.53061  19.8174  3.04898
+6.73469  17.6186  3.12551
+6.93878  21.329  3.20204
+7.14286  20.2873  3.27857
+7.34694  23.4112  3.3551
+7.55102  26.063  3.43163
+7.7551  29.8775  3.50816
+7.95918  19.0027  3.58469
+8.16327  19.4248  3.66122
+8.36735  27.4876  3.73776
+8.57143  33.8399  3.81429
+8.77551  24.2611  3.89082
+8.97959  29.8796  3.96735
+9.18367  24.6149  4.04388
+9.38776  35.7664  4.12041
+9.59184  32.145  4.19694
+9.79592  24.8085  4.27347
+10  31.3767  4.35
