diff --git a/App/inc/ROOTMinimizer.h b/App/inc/ROOTMinimizer.h
index 5bb0683365fcbccff18bf39378040facd6912a4d..3c7fe5c0492827d3b08b32f01a2f45ce0d90da5e 100644
--- a/App/inc/ROOTMinimizer.h
+++ b/App/inc/ROOTMinimizer.h
@@ -14,10 +14,12 @@
 //! @author Scientific Computing Group at FRM II
 //! @date   05.10.2012
 
+
 #include "IMinimizer.h"
 #include "OutputData.h"
 #include "Exceptions.h"
 #include "ROOTMinimizerFunction.h"
+#include "FitSuiteParameters.h"
 #include <string>
 // from ROOT
 #include "Math/Minimizer.h"
@@ -35,14 +37,15 @@ public:
     ROOTMinimizer(const std::string &minimizer_name, const std::string &algo_type=std::string());
     virtual ~ROOTMinimizer();
 
-    virtual void setVariable(int index, const FitParameter *par) ;
+    virtual void setParameter(size_t index, const FitParameter *par);
+    virtual void setParameters(const FitSuiteParameters &parameters);
+
 
-    virtual void setFunction(function_t fcn, int ndims, element_function_t element_fcn, int nelements);
-//    virtual void setElementFunction(element_function_t element_fcn, int ndims, int nelements) { m_element_fcn = element_fcn, m_ndims = ndims; m_nelements = nelements; }
+    virtual void setFunction(function_chi2_t fun_chi2, size_t nparameters, function_gradient_t fun_gradient, size_t ndatasize);
 
     virtual void minimize();
 
-    //! return pointer to created minimizer
+    //! return created minimizer
     ROOT::Math::Minimizer *getROOTMinimizer() { return m_root_minimizer; }
 
     //! get number of variables to fit
diff --git a/App/inc/ROOTMinimizerFunction.h b/App/inc/ROOTMinimizerFunction.h
index 8b25d21d045ff9b1fb5762aed13e89294847f149..26e69a76e47f9eb7230356127e5d4fefdbedc2c0 100644
--- a/App/inc/ROOTMinimizerFunction.h
+++ b/App/inc/ROOTMinimizerFunction.h
@@ -29,9 +29,9 @@
 class ROOTMinimizerFunction : public ROOT::Math::Functor
 {
 public:
-    ROOTMinimizerFunction(IMinimizer::function_t fcn, int ndims ) : ROOT::Math::Functor(fcn, ndims), m_fcn(fcn) {}
+    ROOTMinimizerFunction(IMinimizer::function_chi2_t fcn, int ndims ) : ROOT::Math::Functor(fcn, ndims), m_fcn(fcn) {}
     virtual ~ROOTMinimizerFunction(){}
-    IMinimizer::function_t m_fcn;
+    IMinimizer::function_chi2_t m_fcn;
 };
 
 
@@ -45,7 +45,7 @@ class ROOTMinimizerElementFunction : public ROOT::Math::FitMethodFunction
 public:
     typedef ROOT::Math::BasicFitMethodFunction<ROOT::Math::IMultiGenFunction>::Type_t  Type_t;
 
-    ROOTMinimizerElementFunction(IMinimizer::function_t fcn, size_t ndims, IMinimizer::element_function_t element_fcn, size_t nelements)
+    ROOTMinimizerElementFunction(IMinimizer::function_chi2_t fcn, size_t ndims, IMinimizer::function_gradient_t element_fcn, size_t nelements)
         : ROOT::Math::FitMethodFunction(ndims, nelements)
         , m_fcn(fcn)
         , m_element_fcn(element_fcn)
@@ -105,8 +105,8 @@ public:
 
 private:
 
-    IMinimizer::function_t m_fcn;
-    IMinimizer::element_function_t m_element_fcn;
+    IMinimizer::function_chi2_t m_fcn;
+    IMinimizer::function_gradient_t m_element_fcn;
     size_t m_ndims;
     size_t m_nelements;
     mutable std::vector<double > m_parameter_values;
diff --git a/App/src/ROOTMinimizer.cpp b/App/src/ROOTMinimizer.cpp
index 5881a8aac375c47437985915565d98fa73b713ba..5ad39ab83b7bec5003a68a49495e8aad9b6c8716 100644
--- a/App/src/ROOTMinimizer.cpp
+++ b/App/src/ROOTMinimizer.cpp
@@ -1,5 +1,6 @@
 #include "ROOTMinimizer.h"
 #include "Exceptions.h"
+#include "FitSuiteParameters.h"
 #include "Utils.h"
 #include "ROOTMinimizerFunction.h"
 #include <iomanip>
@@ -20,8 +21,12 @@ ROOTMinimizer::ROOTMinimizer(const std::string &minimizer_name, const std::strin
 
     if( !isValidNames(m_minimizer_name, m_algo_type) ) throw LogicErrorException("ROOTMinimizer::ROOTMinimizer() -> Error! Wrong minimizer initialization parameters.");
 
-//    m_root_minimizer = ROOT::Math::Factory::CreateMinimizer(minimizer_name, algo_type );
+    // see http://root.cern.ch/phpBB3/viewtopic.php?f=15&t=14230&p=61216&hilit=minimizer+precision#p61216
+    // see http://root.cern.ch/phpBB3/viewtopic.php?f=3&t=9181&hilit=precision+tolerance
+    //ROOT::Math::MinimizerOptions::SetDefaultTolerance(0.1);
+
     if( m_minimizer_name == "GSLMultiFit") {
+        // hacked version of ROOT's GSL Levenberg-Marquardt minimizer
         m_root_minimizer = new ROOT::Patch::GSLNLSMinimizer();
     } else {
         m_root_minimizer = ROOT::Math::Factory::CreateMinimizer(minimizer_name, algo_type );
@@ -30,6 +35,9 @@ ROOTMinimizer::ROOTMinimizer(const std::string &minimizer_name, const std::strin
 
     m_root_minimizer->SetMaxFunctionCalls(20000);
     m_root_minimizer->SetMaxIterations(20000);
+//    m_root_minimizer->SetPrintLevel(4);
+//    m_root_minimizer->SetTolerance(0.01);
+//    m_root_minimizer->SetPrecision(1e-6);
 }
 
 
@@ -57,13 +65,11 @@ bool ROOTMinimizer::isValidNames(const std::string &minimizer_name, const std::s
     algoTypes["GSLSimAn"]    = boost::assign::list_of("");
     algoTypes["Genetic"]     = boost::assign::list_of("");
 
-    // check if given minimizer names are valid
+    // check minimizers names
     algotypes_t::iterator it = algoTypes.find(minimizer_name);
     if(it != algoTypes.end() ) {
-        // if algo type exists
-        for(size_t i=0; i<it->second.size(); ++i ) {
-            if(it->second[i] == algo_type ) return true;
-        }
+        // check minimizer's algorithm type
+        for(size_t i=0; i<it->second.size(); ++i ) if(it->second[i] == algo_type ) return true;
     }
 
     // if not, print complaining and return false
@@ -93,7 +99,22 @@ bool ROOTMinimizer::isGradientBasedAgorithm()
 }
 
 
-void ROOTMinimizer::setVariable(int index, const FitParameter *par)
+void ROOTMinimizer::setParameters(const FitSuiteParameters &parameters)
+{
+    size_t index(0);
+    for(FitSuiteParameters::const_iterator it=parameters.begin(); it!=parameters.end(); ++it) {
+        setParameter(index++, (*it) );
+    }
+    if( parameters.size() != getNumberOfVariables())  {
+        std::ostringstream ostr;
+        ostr << "ROOTMinimizer::setParameters() -> Error! Number of variables defined in minimizer (" << getNumberOfVariables() << ") ";
+        ostr << "doesn't coincide with number of FitSuite's parameters (" << parameters.size() << ")";
+        throw LogicErrorException(ostr.str());
+    }
+}
+
+
+void ROOTMinimizer::setParameter(size_t index, const FitParameter *par)
 {
     bool success;
     if( par->isFixed() ) {
@@ -129,18 +150,18 @@ void ROOTMinimizer::minimize()
 // set fcn function for minimizer
 /* ************************************************************************* */
 // FIXME ROOTMinimizer::setFunction Implement Multiple inheretiance in ROOTMinimizerElementFunction ;)
-void ROOTMinimizer::setFunction(function_t fcn, int ndims, element_function_t element_fcn, int nelements)
+void ROOTMinimizer::setFunction(function_chi2_t fun_chi2, size_t nparameters, function_gradient_t fun_gradient, size_t ndatasize)
 {
     if( isGradientBasedAgorithm() ) {
         std::cout << " ROOTMinimizer::setFunction() -> XXX 1.1 making ROOTMinimizerElementFunction " << std::endl;
         delete m_minfunc_element;
-        m_minfunc_element = new ROOTMinimizerElementFunction(fcn, ndims, element_fcn, nelements);
+        m_minfunc_element = new ROOTMinimizerElementFunction(fun_chi2, nparameters, fun_gradient, ndatasize);
         m_root_minimizer->SetFunction(*m_minfunc_element);
 
     } else {
         std::cout << " ROOTMinimizer::setFunction() -> XXX 1.2 making ROOTMinimizerFunction" << std::endl;
         delete m_minfunc;
-        m_minfunc = new ROOTMinimizerFunction(fcn, ndims);
+        m_minfunc = new ROOTMinimizerFunction(fun_chi2, nparameters);
         m_root_minimizer->SetFunction(*m_minfunc);
     }
 }
diff --git a/App/src/ROOTMinimizerFunction.cpp b/App/src/ROOTMinimizerFunction.cpp
index e16c5f641f0c016e0692df5ee53f2ea076646e2d..f0c5c65bdfa0a5920eab38c60424c1227e7f7233 100644
--- a/App/src/ROOTMinimizerFunction.cpp
+++ b/App/src/ROOTMinimizerFunction.cpp
@@ -33,26 +33,6 @@ double ROOTMinimizerElementFunction::DataElement(const double *pars, unsigned in
         std::cout << " gradient " << std::endl;
         if(i_selected_element == 0 || parameters_changed) {
             std::cout << "g!=0 parameters_changed " << parameters_changed << std::endl;
-            const double kEps = 1.0E-4;
-            for(size_t i_par=0; i_par<m_ndims; ++i_par ) {
-                std::vector<double > pars_deriv; // values of parameters for derivative calculation
-                pars_deriv.resize(m_ndims);
-                std::copy(pars, pars+m_ndims, pars_deriv.begin());
-                pars_deriv[i_par] += kEps;
-                m_fcn(&pars_deriv.front());
-                for(size_t j=0; j<pars_deriv.size(); ++j) {
-                    std::cout << "i_par:" << i_par << " j:" << j << " " << pars[j] << " " << pars_deriv[j] << std::endl;
-                }
-                std::vector<double> m_residuals2;
-                m_residuals2.resize(m_nelements);
-                for(size_t i_element=0; i_element<m_nelements; ++i_element) {
-                    m_residuals2[i_element] = m_element_fcn(&pars_deriv.front(), i_element, gradient);
-                }
-
-                for(size_t i_element=0; i_element <m_nelements; ++i_element) {
-                    m_gradients[i_par][i_element] = (m_residuals2[i_element] - m_residuals[i_element])/kEps;
-                }
-            }
         }
         for(size_t i_par=0; i_par<m_ndims; ++i_par) {
             gradient[i_par] = m_gradients[i_par][i_selected_element];
diff --git a/App/src/TestToyExperiment.cpp b/App/src/TestToyExperiment.cpp
index 5fe84ee96cf6c214884b5c10f8d1eb195e5d2b28..77deb9e8e7238f48ed97ae8e6b3ae9c59a1733eb 100644
--- a/App/src/TestToyExperiment.cpp
+++ b/App/src/TestToyExperiment.cpp
@@ -97,12 +97,12 @@ void TestToyExperiment::execute()
 
     // setting up fitSuite
     FitSuite *m_fitSuite = new FitSuite();
-    //m_fitSuite->setMinimizer( new ROOTMinimizer("Minuit2", "Migrad") );
+    m_fitSuite->setMinimizer( new ROOTMinimizer("Minuit2", "Migrad") );
     //m_fitSuite->setMinimizer( new ROOTMinimizer("Minuit2", "Fumili") );
+    //m_fitSuite->setMinimizer( new ROOTMinimizer("GSLMultiFit") );
 
-    m_fitSuite->setMinimizer( new ROOTMinimizer("GSLMultiFit") );
     m_fitSuite->attachObserver( new FitSuiteObserverPrint() );
-    m_fitSuite->attachObserver( new FitSuiteObserverDraw() );
+//    m_fitSuite->attachObserver( new FitSuiteObserverDraw() );
 
     m_fitSuite->addFitParameter("*/par0",  1.0, 0.01);
     m_fitSuite->addFitParameter("*/par1",  0.0, 0.01);
diff --git a/Core/Algorithms/inc/ISquaredFunction.h b/Core/Algorithms/inc/ISquaredFunction.h
index 9c2c28bd37a7b3cfb7696742e0d920f233df0570..8696daf492761564b7a3bd92e16cb3f0c16e813f 100644
--- a/Core/Algorithms/inc/ISquaredFunction.h
+++ b/Core/Algorithms/inc/ISquaredFunction.h
@@ -15,6 +15,7 @@
 //! @date   Jul 20, 2012
 
 #include "Numeric.h"
+#include "Exceptions.h"
 
 #include <cmath>
 #include <iostream>
@@ -27,6 +28,7 @@ public:
     virtual ISquaredFunction *clone() const=0;
 
     virtual double calculateSquaredDifference(double real_value, double simulated_value) const=0;
+    virtual double calculateSquaredError(double real_value, double simulated_value = 0.0) const { (void)real_value; (void)simulated_value; throw NotImplementedException("ISquaredFunction::calculateError() -> Error! Not implemented."); }
 };
 
 
@@ -43,9 +45,15 @@ public:
         if (diff_squared < Numeric::double_epsilon) {
             return 0.0;
         }
-        double sigma = std::max(real_value,1.0);
-        return diff_squared/sigma;
+        double sigma_squared = std::max(real_value,1.0);
+        return diff_squared/sigma_squared;
+    }
+
+    virtual inline double calculateSquaredError(double real_value, double /* simulated_value */) const
+    {
+        return std::max(real_value,1.0);
     }
+
 };
 
 
@@ -85,6 +93,11 @@ public:
         sigma_squared = std::max(sigma_squared, 1.0);
         return diff_squared/sigma_squared;
     }
+    virtual inline double calculateSquaredError(double real_value, double /* simulated_value */) const
+    {
+        return std::max(std::fabs(real_value) + (m_epsilon*real_value)*(m_epsilon*real_value),1.0);
+    }
+
 private:
     double m_epsilon;
 };
@@ -103,6 +116,11 @@ public:
         double sigma_squared = m_sigma*m_sigma;
         return diff_squared/sigma_squared;
     }
+    virtual inline double calculateSquaredError(double /* real_value */, double /* simulated_value */) const
+    {
+        return m_sigma*m_sigma;
+    }
+
 private:
     double m_sigma;
 };
diff --git a/Core/Core.pro b/Core/Core.pro
index 07bf98a14df574d47929a353964fcdceb047b8c4..991b9f2eeea2ec13e50e4dc5557e1cfc53e146b6 100644
--- a/Core/Core.pro
+++ b/Core/Core.pro
@@ -117,7 +117,8 @@ SOURCES += \
     Tools/src/StochasticGaussian.cpp \
     Tools/src/StochasticSampledParameter.cpp \
     Tools/src/Types.cpp \
-    Tools/src/Utils.cpp
+    Tools/src/Utils.cpp \
+    Tools/src/FitSuiteFunctions.cpp
 
 HEADERS += \
     Algorithms/inc/Beam.h \
@@ -264,7 +265,8 @@ HEADERS += \
     Tools/inc/Types.h \
     Tools/inc/Units.h \
     Tools/inc/Utils.h \
-    Tools/inc/CoreOptionsDescription.h
+    Tools/inc/CoreOptionsDescription.h \
+    Tools/inc/FitSuiteFunctions.h
 
 INCLUDEPATH += ./Algorithms/inc ./FormFactors/inc ./Geometry/inc ./Samples/inc ./Tools/inc
 DEPENDPATH  += ./Algorithms/inc ./FormFactors/inc ./Geometry/inc ./Samples/inc ./Tools/inc
diff --git a/Core/Tools/inc/FitObject.h b/Core/Tools/inc/FitObject.h
index 16516287facbded668cca87aac964a8ee7b01d20..50cf2477fd896e27e67c6d6ce4ed70b7347defdb 100644
--- a/Core/Tools/inc/FitObject.h
+++ b/Core/Tools/inc/FitObject.h
@@ -60,6 +60,9 @@ public:
     //! return weight of data set in chi2 calculations
     double getWeight() const { return m_weight; }
 
+    //! return size of data
+    size_t getSizeOfData() const { return m_real_data->getAllocatedSize(); }
+
 protected:
     //! initialize pool parameters, i.e. register some of class members for later access via parameter pool
     virtual void init_parameters();
diff --git a/Core/Tools/inc/FitParameter.h b/Core/Tools/inc/FitParameter.h
index d9415908ff142c5300b7453938875fcdd3e1cf7f..a7cf10be3094f8d9c78961dfa082fe2127a6cb8e 100644
--- a/Core/Tools/inc/FitParameter.h
+++ b/Core/Tools/inc/FitParameter.h
@@ -29,7 +29,7 @@ class FitParameter : public INamed, public AttLimits
 public:
     FitParameter();
     FitParameter(const AttLimits &limits);
-    FitParameter(const std::string &name, double value, double step=0.0, const AttLimits &limits=AttLimits::limitless());
+    FitParameter(const std::string &name, double value, double step=0.0, const AttLimits &limits=AttLimits::limitless(), double error=0.0);
     virtual ~FitParameter(){}
 
     //! set value of parameter
diff --git a/Core/Tools/inc/FitParameterLinked.h b/Core/Tools/inc/FitParameterLinked.h
index bff3515ed1afae82ea2d77178f980b0e9dbd2b38..2482ed781f031bc3c3257a379ae50c919c7f2849 100644
--- a/Core/Tools/inc/FitParameterLinked.h
+++ b/Core/Tools/inc/FitParameterLinked.h
@@ -33,7 +33,7 @@ public:
     typedef std::vector<ParameterPool::parameter_t > PoolParameterColl_t;
 
     FitParameterLinked();
-    FitParameterLinked(const std::string &name, double value, double step, const AttLimits &attlim=AttLimits::limitless());
+    FitParameterLinked(const std::string &name, double value, double step, const AttLimits &attlim=AttLimits::limitless(), double error=0.0);
     virtual ~FitParameterLinked(){}
 
     //! set given value for all binded parameters
diff --git a/Core/Tools/inc/FitSuite.h b/Core/Tools/inc/FitSuite.h
index f55fba07feba3153632092514906b8b80f337ec9..b27a1c4df5038b1d0fcb337ac76fe717bf76dde2 100644
--- a/Core/Tools/inc/FitSuite.h
+++ b/Core/Tools/inc/FitSuite.h
@@ -24,6 +24,7 @@
 #include "FitSuiteParameters.h"
 #include "IMinimizer.h"
 #include "ChiSquaredModule.h"
+#include "FitSuiteFunctions.h"
 #include <string>
 
 class Experiment;
@@ -50,7 +51,7 @@ public:
     void addExperimentAndRealData(const Experiment &experiment, const OutputData<double > &real_data, const IChiSquaredModule &chi2_module=ChiSquaredModule());
 
     //! add fit parameter
-    void addFitParameter(const std::string &name, double value, double step, const AttLimits &attlim=AttLimits::limitless());
+    void addFitParameter(const std::string &name, double value, double step, const AttLimits &attlim=AttLimits::limitless(), double error=0.0);
 
     //! add fit strategy
     void addFitStrategy(IFitSuiteStrategy *strategy);
@@ -70,10 +71,10 @@ public:
     virtual void runFit();
 
     //! function to minimize
-    double functionToMinimize(const double *pars_current_values);
+    double fittingChiSquaredFunction(const double *pars_current_values);
 
     //! provides minimizer with gradients wrt parameters for single data element
-    double elementFunction(const double *pars_current_values, unsigned int index, double *deriv);
+    double fittingGradientFunction(const double *pars_current_values, unsigned int index, double *deriv);
 
     //! return reference to the kit with data
     FitSuiteObjects *getFitObjects() { return &m_fit_objects; }
@@ -85,7 +86,8 @@ public:
     bool isLastIteration() { return m_is_last_iteration; }
 
     //! get current number of minimization function calls
-    int getNCall() { return m_n_call; }
+    //int getNCall() { return m_n_call; }
+    int getNCall() { return m_function_chi2.getNCall(); }
 
     //! get the number of current strategy
     int getNStrategy() { return m_n_strategy; }
@@ -106,6 +108,8 @@ private:
     bool m_is_last_iteration; //! set to true after last iteration complete
     int m_n_call; //! current number of minimization function call
     int m_n_strategy; //! current number of fit strategy
+
+    FitSuiteChiSquaredFunction m_function_chi2;
 };
 
 #endif // FITSUITE_H
diff --git a/Core/Tools/inc/FitSuiteFunctions.h b/Core/Tools/inc/FitSuiteFunctions.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d75c61ac586c08f0bdd04fed111e548c723c910
--- /dev/null
+++ b/Core/Tools/inc/FitSuiteFunctions.h
@@ -0,0 +1,80 @@
+#ifndef FITSUITEFUNCTIONS_H
+#define FITSUITEFUNCTIONS_H
+// ********************************************************************
+// * The BornAgain project                                            *
+// * Simulation of neutron and x-ray scattering at grazing incidence  *
+// *                                                                  *
+// * LICENSE AND DISCLAIMER                                           *
+// * Lorem ipsum dolor sit amet, consectetur adipiscing elit.  Mauris *
+// * eget quam orci. Quisque  porta  varius  dui,  quis  posuere nibh *
+// * mollis quis. Mauris commodo rhoncus porttitor.                   *
+// ********************************************************************
+//! @file   FitSuiteFunctions.h
+//! @brief  Definition of FitSuiteFunctions classes
+//! @author Scientific Computing Group at FRM II
+//! @date   20.12.2012
+
+
+#include <vector>
+
+class FitSuite;
+
+//- -------------------------------------------------------------------
+//! @class IFitSuiteFunction
+//! @brief Fitting functions interface to be used by Minimizer.
+//- -------------------------------------------------------------------
+class IFitSuiteFunction
+{
+public:
+    IFitSuiteFunction() : m_fit_suite(0), m_ncall(0) {}
+    virtual ~IFitSuiteFunction(){}
+    virtual void init(FitSuite *fit_suite) { m_fit_suite = fit_suite; }
+    virtual size_t getNCall() const { return m_ncall; }
+protected:
+    FitSuite *m_fit_suite;
+    size_t m_ncall;
+};
+
+
+
+//- -------------------------------------------------------------------
+//! @class FitSuiteChiSquaredFunction
+//! @brief Chi squared fitting function for minimizer
+//- -------------------------------------------------------------------
+class FitSuiteChiSquaredFunction : public IFitSuiteFunction
+{
+public:
+    FitSuiteChiSquaredFunction(){}
+    virtual ~FitSuiteChiSquaredFunction(){}
+    //! evaluate method for chi2 value called directly from the minimizer
+    double evaluate(const double *pars);
+};
+
+
+//- -------------------------------------------------------------------
+//! @class FitSuiteChiSquaredFunction
+//! @brief Gradient fitting function for minimizer
+//- -------------------------------------------------------------------
+class FitSuiteGradientFunction : public IFitSuiteFunction
+{
+public:
+    FitSuiteGradientFunction() : m_npars(0), m_ndatasize(0), m_prev_index(-1) {}
+    virtual ~FitSuiteGradientFunction(){}
+    //! evaluate method for gradients and residuals called directly from the minimizer
+    double evaluate(const double *pars, unsigned int index, double *deriv);
+private:
+    void verify_arrays();
+    void verify_minimizer_logic(bool parameters_have_changed, int current_index);
+    void calculate_residuals(const double *pars);
+    void calculate_gradients(const double *pars);
+
+    size_t m_npars;
+    size_t m_ndatasize;
+    int m_prev_index;
+    std::vector<double > m_residuals; // [m_ndatasize]
+    std::vector<std::vector<double> > m_gradients; // [m_npars][m_ndatasize]
+};
+
+
+
+#endif // FITSUITEFUNCTIONS_H
diff --git a/Core/Tools/inc/FitSuiteObjects.h b/Core/Tools/inc/FitSuiteObjects.h
index bf8be6a2d3fb2f8705eda63a7c2efcbbb92fa0f3..26221a887781f2f7fdf97943e1f694ff09220849 100644
--- a/Core/Tools/inc/FitSuiteObjects.h
+++ b/Core/Tools/inc/FitSuiteObjects.h
@@ -38,7 +38,7 @@ public:
     //! clear all data
     void clear();
 
-    //! return number of items
+    //! return number of fit items
     size_t size() const { return m_fit_objects.size(); }
 
     //! add to kit pair of (experiment, real data) for consecutive simulation and chi2 module
@@ -47,11 +47,15 @@ public:
     //! loop through all defined experiments and run they simulation
     void runSimulation();
 
+    //! get total number of data points
+    size_t getSizeOfDataSet() const;
+
     //! get sum of chi squared values for all fit objects
     double getChiSquaredValue(int n_free_fit_parameters = 0);
 
     //! get residuals for single data element
-    double getResidualValue(int index);
+    //! @pars global_index index accross all OutputData defined
+    double getResidualValue(int global_index);
 
     //! get experiment
     const Experiment *getExperiment(size_t i_item = 0) const { return m_fit_objects[check_index(i_item)]->getExperiment(); }
@@ -86,6 +90,9 @@ protected:
     //! calculate maximum intensity in simulated data
     double getSimulationMaxIntensity();
 
+    //! return object and calculate index of data element for given global data element index
+    const FitObject *getObjectForGlobalDataIndex(size_t global_index, size_t &local_index);
+
 private:
     //! disabled copy constructor and assignment operator
     FitSuiteObjects &operator=(const FitSuiteObjects &);
diff --git a/Core/Tools/inc/FitSuiteParameters.h b/Core/Tools/inc/FitSuiteParameters.h
index 6a0a3711da7e963b1132c2bd46d64d66f4a9ef48..d1bb7407912361534ea1b3a6167462012ceb0bf8 100644
--- a/Core/Tools/inc/FitSuiteParameters.h
+++ b/Core/Tools/inc/FitSuiteParameters.h
@@ -39,7 +39,7 @@ public:
     void clear();
 
     //! add fit parameter
-    void addParameter(const std::string &name, double value, double step, const AttLimits &attlim);
+    void addParameter(const std::string &name, double value, double step, const AttLimits &attlim, double error=0.0);
 
     //! return fit parameter with given name
     const FitParameter *getParameter(const std::string &name) const;
@@ -75,6 +75,9 @@ public:
     //! return number of free parameters
     size_t getNfreeParameters() const;
 
+    //! return true if parameters have already given values
+    bool valuesAreDifferrent(const double *pars_valuers, double tolerance_factor=1.0) const;
+
 private:
     //! disabled copy constructor and assignment operator
     FitSuiteParameters &operator=(const FitSuiteParameters &other);
@@ -82,6 +85,8 @@ private:
 
     inline size_t check_index(size_t index) const { return (index < m_parameters.size() ? index : throw  OutOfBoundsException("FitSuiteParameters::check_index() -> Index out of bounds") ); }
     parameters_t m_parameters; //! collection of fit parameters
+
+    static double m_default_parameter_error;
 };
 
 #endif // FITSUITEPARAMETERS_H
diff --git a/Core/Tools/inc/IMinimizer.h b/Core/Tools/inc/IMinimizer.h
index 7df17f8678ff098e121528e3af44c6b68a56e952..885a8ff8d810c14fd16cb2a25d41f0b1032e2f5a 100644
--- a/Core/Tools/inc/IMinimizer.h
+++ b/Core/Tools/inc/IMinimizer.h
@@ -16,6 +16,7 @@
 
 
 #include "FitParameter.h"
+#include "FitSuiteParameters.h"
 #include <boost/function.hpp>
 #include <map>
 #include "Exceptions.h"
@@ -29,20 +30,19 @@ class IMinimizer
 {
 public:
     //! signature of function to minimize
-    typedef boost::function<double(const double *)> function_t;
-    //! signature of function to minimize with acess to single element residual
-    typedef boost::function<double(const double *, unsigned int, double *)> element_function_t;
+    typedef boost::function<double(const double *)> function_chi2_t;
+    //! signature of function to minimize with acess to single element residual and gradient
+    typedef boost::function<double(const double *, unsigned int, double *)> function_gradient_t;
 
     IMinimizer(){}
     virtual ~IMinimizer(){}
 
-    //! set variable
-    virtual void setVariable(int index, const FitParameter *par) = 0;
+    //! set parameter
+    virtual void setParameter(size_t index, const FitParameter *par) = 0;
+    virtual void setParameters(const FitSuiteParameters &parameters) = 0;
 
     //! set function to minimize
-//    virtual void setFunction(function_t fcn, int ndims) = 0;
-//    virtual void setElementFunction(element_function_t fcn, int ndims, int nelements) = 0;
-    virtual void setFunction(function_t fcn, int ndims, element_function_t element_fcn = element_function_t(), int nelements = 0) = 0;
+    virtual void setFunction(function_chi2_t fun_chi2, size_t nparameters, function_gradient_t fun_gradient = function_gradient_t(), size_t ndatasize = 0) = 0;
 
     //! run minimization
     virtual void minimize() = 0;
@@ -80,13 +80,11 @@ public:
     virtual ~TestMinimizer(){}
 
     //! set variable
-    virtual void setVariable(int index, const FitParameter *par) { m_values[index] = par->getValue(); }
+    virtual void setParameter(size_t index, const FitParameter *par) { m_values[index] = par->getValue(); }
+    virtual void setParameters(const FitSuiteParameters  &/*parameters */) { throw NotImplementedException("TestMinimizer::setParameters() -> Error! Not implemented."); }
 
     //! set function to minimize
-    //virtual void setFunction(function_t fcn, int ndims) { m_fcn = fcn; (void)ndims; }
-    virtual void setFunction(function_t fcn, int /* ndims */, element_function_t /* element_fcn */, int /* nelements */ ) { m_fcn = fcn; }
-
-//    virtual void setElementFunction(element_function_t /* fcn */, int /* ndims */, int /* nelements */) { throw NotImplementedException("TestMinimizer::setGradientFunction"); }
+    virtual void setFunction(function_chi2_t fun_chi2, size_t /* nparameters */, function_gradient_t /* fun_gradient */, size_t /* ndatasize */ ) { m_fcn = fun_chi2; }
 
     //! run minimization
     virtual void minimize()
@@ -129,7 +127,7 @@ public:
 
 private:
     std::map<int, double > m_values;
-    function_t m_fcn;
+    function_chi2_t m_fcn;
 };
 
 
diff --git a/Core/Tools/inc/Numeric.h b/Core/Tools/inc/Numeric.h
index 33864f1871be15340a4903e4c7cce24f5ba7c028..0ede1834387d1d8c2f3657b3a95e70acb4a29aef 100644
--- a/Core/Tools/inc/Numeric.h
+++ b/Core/Tools/inc/Numeric.h
@@ -16,6 +16,7 @@
 //! @date   10.05.2012
 
 #include <limits>
+#include <cmath>
 
 namespace Numeric {
 
@@ -26,6 +27,9 @@ static double double_min = std::numeric_limits<double>::min();
 
 static const double probthreshold = 0.0000000001; //!< threshold on probability value during calculation of weighted form factor
 
+//! compare two doubles
+inline bool areAlmostEqual(double a, double b, double tolerance_factor=1.0) { return std::abs(a-b) < tolerance_factor*Numeric::double_epsilon; }
+
 }
 
 #endif /* NUMERIC_H_ */
diff --git a/Core/Tools/src/FitObject.cpp b/Core/Tools/src/FitObject.cpp
index 1ceb4844f05156705f496c949ed480929df16a46..66b178e13731e30e3577074209633492dba78ef0 100644
--- a/Core/Tools/src/FitObject.cpp
+++ b/Core/Tools/src/FitObject.cpp
@@ -22,6 +22,9 @@ FitObject::FitObject(const Experiment &experiment, const OutputData<double > &re
 
 FitObject::~FitObject()
 {
+    delete m_experiment;
+    delete m_real_data;
+    delete m_chi2_module;
 }
 
 
diff --git a/Core/Tools/src/FitParameter.cpp b/Core/Tools/src/FitParameter.cpp
index 00ac4cc8914d8f35201b4dd1f2d283b5becbb620..19b2911c544e93b291dc923de666cdcc24daa1cc 100644
--- a/Core/Tools/src/FitParameter.cpp
+++ b/Core/Tools/src/FitParameter.cpp
@@ -3,21 +3,15 @@
 #include <iomanip>
 
 FitParameter::FitParameter() : m_value(0), m_step(0), m_error(0)
-{
-
-}
-
+{ }
 
-FitParameter::FitParameter(const std::string &name, double value, double step, const AttLimits &attlimits)
+FitParameter::FitParameter(const std::string &name, double value, double step, const AttLimits &attlimits, double error)
     : INamed(name)
     , AttLimits(attlimits)
     , m_value(value)
     , m_step(step)
-    , m_error(0.0)
-{
-
-}
-
+    , m_error(error)
+{ }
 
 void FitParameter::print(std::ostream &ostr) const
 {
diff --git a/Core/Tools/src/FitParameterLinked.cpp b/Core/Tools/src/FitParameterLinked.cpp
index ae1944e1c0dc4e9237e63c0ea915c9f92b74dce9..27d4382e781949cf97b8d812f482aacae1cba88e 100644
--- a/Core/Tools/src/FitParameterLinked.cpp
+++ b/Core/Tools/src/FitParameterLinked.cpp
@@ -8,7 +8,7 @@ FitParameterLinked::FitParameterLinked()
 }
 
 
-FitParameterLinked::FitParameterLinked(const std::string &name, double value, double step, const AttLimits &attlim) : FitParameter(name, value, step, attlim)
+FitParameterLinked::FitParameterLinked(const std::string &name, double value, double step, const AttLimits &attlim, double error) : FitParameter(name, value, step, attlim, error)
 {
 
 }
diff --git a/Core/Tools/src/FitSuite.cpp b/Core/Tools/src/FitSuite.cpp
index 7ebdbcab1913717673fb9a3b437631f9aea8c4e7..7cb7753081b3af1eca246ef6f9f65438a4759dfa 100644
--- a/Core/Tools/src/FitSuite.cpp
+++ b/Core/Tools/src/FitSuite.cpp
@@ -10,6 +10,7 @@
 
 FitSuite::FitSuite() : m_minimizer(0), m_is_last_iteration(false), m_n_call(0), m_n_strategy(0)
 {
+    m_function_chi2.init(this);
 }
 
 
@@ -48,9 +49,9 @@ void FitSuite::addExperimentAndRealData(const Experiment &experiment, const Outp
 /* ************************************************************************* */
 // add fit parameter
 /* ************************************************************************* */
-void FitSuite::addFitParameter(const std::string &name, double value, double step, const AttLimits &attlim)
+void FitSuite::addFitParameter(const std::string &name, double value, double step, const AttLimits &attlim, double error)
 {
-    m_fit_parameters.addParameter(name, value, step, attlim);
+    m_fit_parameters.addParameter(name, value, step, attlim, error);
 }
 
 
@@ -83,25 +84,15 @@ void FitSuite::link_fit_parameters()
 /* ************************************************************************* */
 void FitSuite::minimize()
 {
-    // initializing minimizer with fcn function belonging to given class
-    IMinimizer::function_t fcn = boost::bind(&FitSuite::functionToMinimize, this, _1);
-    //m_minimizer->setFunction( fcn, (int)m_fit_parameters.size() );
-    // FIXME: FitSuite::minimize() where to get number of elements?
-    int nelements = m_fit_objects.getRealData()->getAllocatedSize();
-    IMinimizer::element_function_t element_fcn = boost::bind(&FitSuite::elementFunction, this, _1, _2, _3);
-    m_minimizer->setFunction( fcn, (int)m_fit_parameters.size(), element_fcn, nelements );
-
-    // propagating values of local fit parameters to the minimizer's internal parameters
-    for(size_t i_par = 0; i_par<m_fit_parameters.size(); i_par++) {
-        std::cout << " i_par " << i_par << std::endl;
-        m_minimizer->setVariable((int)i_par, m_fit_parameters[i_par] );
-    }
-    if( m_fit_parameters.size() != m_minimizer->getNumberOfVariables())  {
-        std::ostringstream ostr;
-        ostr << "FitSuite::minimize() -> Error! Number of variables defined in minimizer (" << m_minimizer->getNumberOfVariables() << ") ";
-        ostr << "doesn't coincide with number of FitSuite's parameters (" << m_fit_parameters.size() << ")";
-        throw LogicErrorException(ostr.str());
-    }
+    // initializing minimizer with fitting functions
+    //IMinimizer::function_chi2_t fun_chi2 = boost::bind(&FitSuite::fittingChiSquaredFunction, this, _1);
+    IMinimizer::function_chi2_t fun_chi2 = boost::bind(&FitSuiteChiSquaredFunction::evaluate, &m_function_chi2, _1);
+
+    IMinimizer::function_gradient_t fun_gradient = boost::bind(&FitSuite::fittingGradientFunction, this, _1, _2, _3);
+    m_minimizer->setFunction( fun_chi2, m_fit_parameters.size(), fun_gradient, m_fit_objects.getSizeOfDataSet() );
+
+    // initializing minimizer's parameters with the list of local fit parameters
+    m_minimizer->setParameters(m_fit_parameters);
 
     // minimizing
     m_minimizer->minimize();
@@ -158,7 +149,7 @@ void FitSuite::runFit()
 /* ************************************************************************* */
 // function to minimize
 /* ************************************************************************* */
-double FitSuite::functionToMinimize(const double *pars_current_values)
+double FitSuite::fittingChiSquaredFunction(const double *pars_current_values)
 {
     std::cout << "FitSuite::functionToMinimize() -> Info" << std::endl;
     // set fitting parameters to values suggested by the minimizer
@@ -179,8 +170,11 @@ double FitSuite::functionToMinimize(const double *pars_current_values)
 /* ************************************************************************* */
 // provides minimizer with gradients wrt parameters for single data element
 /* ************************************************************************* */
-double FitSuite::elementFunction(const double *pars_current_values, unsigned int index, double *deriv)
+double FitSuite::fittingGradientFunction(const double *pars_current_values, unsigned int index, double *deriv)
 {
+//    bool parameters_changed = m_fit_parameters.parametersDiffer(pars_current_values);
+
+    throw 1;
     (void)pars_current_values;
     (void) deriv;
 //    if(index % 10 == 0) std::cout << " elementFunction " << index << std::endl;
diff --git a/Core/Tools/src/FitSuiteFunctions.cpp b/Core/Tools/src/FitSuiteFunctions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..377354c21207602568c54266fd9adc88101691f9
--- /dev/null
+++ b/Core/Tools/src/FitSuiteFunctions.cpp
@@ -0,0 +1,123 @@
+#include "FitSuiteFunctions.h"
+#include "FitSuite.h"
+
+
+/* ************************************************************************* */
+// evaluate chi squared value
+/* ************************************************************************* */
+double FitSuiteChiSquaredFunction::evaluate(const double *pars)
+{
+    std::cout << "FitSuiteChiSquaredFunction::evaluate() -> Info" << std::endl;
+    assert(m_fit_suite != NULL);
+
+    // set fitting parameters to values suggested by the minimizer
+    m_fit_suite->getFitParameters()->setValues(pars);
+
+    // run simulations
+    m_fit_suite->getFitObjects()->runSimulation();
+
+    // caclulate chi2 value
+    int n_free_pars = m_fit_suite->getFitParameters()->getNfreeParameters();
+    double chi_squared = m_fit_suite->getFitObjects()->getChiSquaredValue(n_free_pars);
+
+    m_fit_suite->notifyObservers();
+    m_ncall++;
+    return chi_squared;
+}
+
+
+/* ************************************************************************* */
+// evaluate residual and derivative for given data element
+/* ************************************************************************* */
+double FitSuiteGradientFunction::evaluate(const double *pars, unsigned int index, double *deriv)
+{
+    std::cout << "FitSuiteGradientFunction::evaluate() -> Info" << std::endl;
+    assert(m_fit_suite != NULL);
+
+    bool parameters_changed = m_fit_suite->getFitParameters()->valuesAreDifferrent(pars);
+    verify_arrays();
+    verify_minimizer_logic(parameters_changed, (int)index);
+
+    if(parameters_changed) calculate_residuals(pars);
+
+    if(deriv) {
+        if(index == 0 || parameters_changed ) calculate_gradients(pars);
+        for(size_t i_par=0; i_par<m_npars; ++i_par) {
+            deriv[i_par] = m_gradients[i_par][index];
+        }
+    }
+
+    m_ncall++;
+    return m_residuals[index];
+}
+
+void FitSuiteGradientFunction::verify_arrays()
+{
+    if( m_npars != m_fit_suite->getFitParameters()->size() || m_ndatasize != m_fit_suite->getFitObjects()->getSizeOfDataSet() ) {
+        std::cout << "FitSuiteGradientFunction::verify_arrays() -> Info. " << std::endl;
+        m_npars = m_fit_suite->getFitParameters()->size();
+        m_ndatasize = m_fit_suite->getFitObjects()->getSizeOfDataSet();
+        m_residuals.clear();
+        m_residuals.resize(m_ndatasize, 0.0);
+        m_gradients.clear();
+        m_gradients.resize(m_npars);
+        for(size_t i_par=0; i_par<m_npars; ++i_par) {
+            m_gradients[i_par].resize(m_ndatasize, 0.0);
+        }
+    }
+}
+
+void FitSuiteGradientFunction::verify_minimizer_logic(bool parameters_have_changed, int current_index)
+{
+    int index_difference = current_index - m_prev_index;
+    if(index_difference != 1 && (current_index!=0 && int(m_prev_index)!= int(m_ndatasize-1) ) ) {
+        std::cout << "FitSuiteGradientFunction::verify_minimizer_logic() -> Warning! Non sequential access to elements.";
+        std::cout << " current_index:" << current_index << " prev_index:" << m_prev_index << std::endl;
+    }
+    if(parameters_have_changed && current_index != 0) {
+        std::cout << "FitSuiteGradientFunction::verify_minimizer_logic() -> Warning! Parameters have changed while current_index!=0" << std::endl;
+        std::cout << " current_index:" << current_index << " prev_index:" << m_prev_index << std::endl;
+    }
+    if(parameters_have_changed && current_index == m_prev_index) {
+        std::cout << "FitSuiteGradientFunction::verify_minimizer_logic() -> Warning! Parameters have changed while index remained the same"  << std::endl;
+        std::cout << " current_index:" << current_index << " prev_index:" << m_prev_index << std::endl;
+    }
+}
+
+void FitSuiteGradientFunction::calculate_residuals(const double *pars)
+{
+    std::cout << " FitSuiteGradientFunction::calculate_residuals() -> Info. " << std::endl;
+    m_fit_suite->getFitParameters()->setValues(pars);
+    m_fit_suite->getFitObjects()->runSimulation();
+    for(size_t i_data=0; i_data<m_ndatasize; ++i_data) {
+        m_residuals[i_data] = m_fit_suite->getFitObjects()->getResidualValue(i_data);
+    }
+
+}
+
+void FitSuiteGradientFunction::calculate_gradients(const double *pars)
+{
+    std::cout << " FitSuiteGradientFunction::calculate_gradients() -> Info. " << std::endl;
+    const double kEps = 1.0E-4;
+    for(size_t i_par=0; i_par<m_npars; ++i_par ) {
+        std::vector<double > pars_deriv; // values of parameters for derivative calculation
+        pars_deriv.resize(m_npars);
+        std::copy(pars, pars+m_npars, pars_deriv.begin());
+        pars_deriv[i_par] += kEps;
+
+        m_fit_suite->getFitParameters()->setValues(pars_deriv);
+        m_fit_suite->getFitObjects()->runSimulation();
+
+        std::vector<double> residuals2;
+        residuals2.resize(m_ndatasize);
+        for(size_t i_data=0; i_data<m_ndatasize; ++i_data) {
+            residuals2[i_data] = m_fit_suite->getFitObjects()->getResidualValue(i_data);
+        }
+
+        for(size_t i_data=0; i_data <m_ndatasize; ++i_data) {
+            m_gradients[i_par][i_data] = (m_residuals[i_data] - residuals2[i_data])/kEps;
+        }
+    }
+
+}
+
diff --git a/Core/Tools/src/FitSuiteObjects.cpp b/Core/Tools/src/FitSuiteObjects.cpp
index 393e7043f22997f4e00a6ec070059c916b2fd92b..8ee0fc980d70f72d9ecfd0a507fd29fd7de97486 100644
--- a/Core/Tools/src/FitSuiteObjects.cpp
+++ b/Core/Tools/src/FitSuiteObjects.cpp
@@ -41,6 +41,19 @@ void FitSuiteObjects::runSimulation()
 }
 
 
+/* ************************************************************************* */
+// get total number of data points
+/* ************************************************************************* */
+size_t FitSuiteObjects::getSizeOfDataSet() const
+{
+    size_t result(0);
+    for(FitObjects_t::const_iterator it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it) {
+        result += (*it)->getSizeOfData();
+    }
+    return result;
+}
+
+
 /* ************************************************************************* */
 // get sum of chi squared values for all fit objects
 // FIXME: refactor FitSuiteObjects::getChiSquaredValue() (the main problem is duplication calculateChiSquared() for ChiSquaredModule and FitObject)
@@ -66,22 +79,30 @@ double FitSuiteObjects::getChiSquaredValue(int n_free_fit_parameters)
 }
 
 
-double FitSuiteObjects::getResidualValue(int index)
+const FitObject *FitSuiteObjects::getObjectForGlobalDataIndex(size_t global_index, size_t &local_index)
 {
-    double residual_sum(0);
-    for(FitObjects_t::iterator it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it) {
-        IChiSquaredModule *chi = (*it)->getChiSquaredModule();
-        const OutputData<double> *data_real = (*it)->getRealData();
-        const OutputData<double> *data_simu = (*it)->getSimulationData();
-        double value_real = (*data_real)[index];
-        double value_simu = (*data_simu)[index];
-        double squared_difference = chi->getSquaredFunction()->calculateSquaredDifference(value_real, value_simu);
-        double weight = (*it)->getWeight()/m_total_weight;
-        double residual(0);
-        (squared_difference > 0 ? residual = weight*std::sqrt(squared_difference) : 0.0);
-        residual_sum += residual;
+    local_index = global_index;
+    for(FitObjects_t::const_iterator it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it) {
+        if(local_index < (*it)->getSizeOfData() ) {
+            //std::cout << "FitSuiteObjects::getObjectForGlobalDataIndex() -> Found index " << global_index << " " << local_index << std::endl;
+            return (*it);
+        } else if(local_index == (*it)->getSizeOfData() ) {
+            local_index -= (*it)->getSizeOfData();
+        }
     }
-    return residual_sum;
+    throw LogicErrorException("FitSuiteObjects::getObjectForGlobalDataIndex() -> Error! Can't find fit object for given data index");
+}
+
+
+double FitSuiteObjects::getResidualValue(int global_index)
+{
+    size_t index(0);
+    const FitObject *fitObject = getObjectForGlobalDataIndex(global_index, index);
+    double value_real = (*fitObject->getRealData())[index];
+    double value_simu = (*fitObject->getSimulationData())[index];
+    double squared_error = fitObject->getChiSquaredModule()->getSquaredFunction()->calculateSquaredError(value_real, value_simu);
+    double residual = (value_real - value_simu)*(fitObject->getWeight()/m_total_weight)/std::sqrt(squared_error);
+    return residual;
 }
 
 
@@ -91,13 +112,13 @@ double FitSuiteObjects::getResidualValue(int index)
 /* ************************************************************************* */
 double FitSuiteObjects::getSimulationMaxIntensity()
 {
-    double max_intensity(0);
+    double result(0);
     for(FitObjects_t::iterator it = m_fit_objects.begin(); it!= m_fit_objects.end(); ++it) {
         const OutputData<double > *data = (*it)->getExperiment()->getOutputData();
         OutputData<double >::const_iterator cit = std::max_element(data->begin(), data->end());
-        max_intensity = std::max(max_intensity, *cit);
+        result = std::max(result, *cit);
     }
-    return max_intensity;
+    return result;
 }
 
 
@@ -109,7 +130,7 @@ std::string FitSuiteObjects::addParametersToExternalPool(std::string path,
 {
     (void)copy_number;
     // add own parameters
-    // so far it is top object in our chain, and its without parameters, lets exclude its name from path
+    // so far it is top object in our chain, and its without parameters, lets not include its name in path
     //std::string  new_path = IParameterized::addParametersToExternalPool(path, external_pool, copy_number);
     std::string new_path = path;
 
diff --git a/Core/Tools/src/FitSuiteParameters.cpp b/Core/Tools/src/FitSuiteParameters.cpp
index 7543a1f52a9c2403216ce960f1eca4a490e8dee7..645b291dce6870c5570d7eaa8f05b0e1d0a5ad70 100644
--- a/Core/Tools/src/FitSuiteParameters.cpp
+++ b/Core/Tools/src/FitSuiteParameters.cpp
@@ -2,6 +2,7 @@
 #include "Experiment.h"
 
 
+double FitSuiteParameters::m_default_parameter_error=0.001;
 
 FitSuiteParameters::FitSuiteParameters()
 {
@@ -25,12 +26,14 @@ void FitSuiteParameters::clear()
 
 
 // add fit parameter
-void FitSuiteParameters::addParameter(const std::string &name, double value, double step, const AttLimits &attlim)
+void FitSuiteParameters::addParameter(const std::string &name, double value, double step, const AttLimits &attlim, double error)
 {
     for(parameters_t::const_iterator it = m_parameters.begin(); it!=m_parameters.end(); ++it) {
         if( (*it)->getName() == name ) throw LogicErrorException("FitSuiteParameters:addtFitParameter() -> Error. Existing parameter '"+name+"'");
     }
-    m_parameters.push_back(new FitParameterLinked(name, value, step, attlim) );
+    // defining default parameter error
+    if(error == 0.0) error = value*m_default_parameter_error;
+    m_parameters.push_back(new FitParameterLinked(name, value, step, attlim, error) );
 }
 
 
@@ -54,9 +57,14 @@ FitParameter *FitSuiteParameters::getParameter(const std::string &name)
 
 
 // set values for all defined parameters
+// FIXME FitSuiteParameters::setValues  remove check for attempt to set parameter values
 void FitSuiteParameters::setValues(const double *pars_values)
 {
-    int index(0);
+    if( !valuesAreDifferrent(pars_values) ) {
+        std::cout << "FitSuiteParameters::setValues() -> Warning! Small or absent variation of parameters" << std::endl;
+        for(size_t i=0; i<m_parameters.size(); i++)  std::cout << (m_parameters[i]->getValue() -pars_values[i]) << " " << Numeric::areAlmostEqual(m_parameters[i]->getValue(), pars_values[i]) << std::endl;
+    }
+    size_t index(0);
     for(parameters_t::iterator it=m_parameters.begin(); it!=m_parameters.end(); ++it) (*it)->setValue(pars_values[index++]);
 }
 
@@ -69,24 +77,23 @@ void FitSuiteParameters::setValues(const std::vector<double> &pars_values)
 
 std::vector<double > FitSuiteParameters::getValues() const
 {
-    std::vector<double > buff;
-    buff.resize(m_parameters.size(), 0);
+    std::vector<double > result;
     for(parameters_t::const_iterator it=m_parameters.begin(); it!=m_parameters.end(); ++it)
     {
-        buff.push_back((*it)->getValue());
+        result.push_back((*it)->getValue());
     }
-    return buff;
+    return result;
 }
 
 
 size_t FitSuiteParameters::getNfreeParameters() const
 {
-    size_t n_free(0);
+    size_t result(0);
     for(parameters_t::const_iterator it=m_parameters.begin(); it!=m_parameters.end(); ++it)
     {
-        if( !(*it)->isFixed() ) n_free++;
+        if( !(*it)->isFixed() ) result++;
     }
-    return n_free;
+    return result;
 }
 
 
@@ -106,3 +113,14 @@ void FitSuiteParameters::link_to_pool(const ParameterPool *pool)
 }
 
 
+bool FitSuiteParameters::valuesAreDifferrent(const double *pars_values, double tolerance_factor) const
+{
+    size_t index(0);
+    for(parameters_t::const_iterator it=m_parameters.begin(); it!=m_parameters.end(); ++it) {
+        if( !Numeric::areAlmostEqual(pars_values[index++], (*it)->getValue(), tolerance_factor )) return true;
+    }
+    return false;
+}
+
+
+
diff --git a/UnitTests/TestCore/TestCore.pro b/UnitTests/TestCore/TestCore.pro
index 0a3d5b89534291669e5d7a531443d418b24e2cb1..5a857e7d3a54d4ae19bbc41635aecd2aa1b675fe 100644
--- a/UnitTests/TestCore/TestCore.pro
+++ b/UnitTests/TestCore/TestCore.pro
@@ -72,4 +72,4 @@ for(dep, MY_DEPENDENCY_LIB) {
 ###############################################################################
 # runs automatically tests right after linking
 ###############################################################################
-QMAKE_POST_LINK = $(TARGET) 2> /dev/null
+QMAKE_POST_LINK = $$PWD/$(TARGET) 2> /dev/null