diff --git a/App/inc/FitSuiteHelper.h b/App/inc/FitSuiteHelper.h
index 7000380a897ee34dea4a40310a259fd0ef758e19..c807db9ad6416abc4e1302e4a5d5353678e64529 100644
--- a/App/inc/FitSuiteHelper.h
+++ b/App/inc/FitSuiteHelper.h
@@ -19,6 +19,18 @@
 #include <string>
 
 
+//- -------------------------------------------------------------------
+//! @class FitSuiteObserverPrint
+//! @brief Print fit progress at the end of each FitSuite's iteration
+//- -------------------------------------------------------------------
+class FitSuiteObserverPrint : public IObserver
+{
+public:
+    FitSuiteObserverPrint() { }
+    void update(IObservable *subject);
+};
+
+
 //- -------------------------------------------------------------------
 //! @class FitSuiteObserverDraw
 //! @brief Draw fit progress at the end of each FitSuite's iteration
@@ -26,10 +38,9 @@
 class FitSuiteObserverDraw : public IObserver
 {
 public:
-    FitSuiteObserverDraw(std::string canvas_name) : m_ncall(0), m_canvas_name(canvas_name) {}
+    FitSuiteObserverDraw( const std::string &canvas_name = std::string("FitSuiteObserverDraw_c1") ) : m_canvas_name(canvas_name) {}
     void update(IObservable *subject);
 private:
-    int m_ncall; //! number of call of given observer
     std::string m_canvas_name; //! canvas name were to draw
 };
 
@@ -42,10 +53,9 @@ private:
 class FitSuiteObserverWriteTree : public IObserver
 {
 public:
-    FitSuiteObserverWriteTree(std::string file_name) : m_ncall(0), m_file_name(file_name) {}
+    FitSuiteObserverWriteTree(const std::string &file_name = std::string("fitsuite.root")) : m_file_name(file_name) {}
     void update(IObservable *subject);
 private:
-    int m_ncall;
     std::string m_file_name; //! canvas name were to draw
 };
 
diff --git a/App/inc/IsGISAXSTools.h b/App/inc/IsGISAXSTools.h
index 0df776a757277819f48c673fafca2930df1f0167..1015ba0bee3c5a42e89e439f2208773f78e3ca8a 100644
--- a/App/inc/IsGISAXSTools.h
+++ b/App/inc/IsGISAXSTools.h
@@ -40,7 +40,10 @@ public:
     static void drawOutputDataDifference1D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string());
 
     //! draw relative difference of two 2D OutputData sets
-    static void drawOutputDataDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string());
+    static void drawOutputDataRelativeDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string());
+
+    //! draw relative difference of two 2D OutputData sets
+    static void drawOutputDataChi2Difference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title = std::string());
 
     //! write output data (1D or 2D) in ASCII file
     static void writeOutputDataToFile(const OutputData<double> &output, const std::string &filename, int precision=10);
diff --git a/App/inc/ROOTMinimizer.h b/App/inc/ROOTMinimizer.h
index 3d7d86717eda6940771cda97cc8c4f92616fad9b..8c2c3ba262c50b41ec47848359c83655ae973adb 100644
--- a/App/inc/ROOTMinimizer.h
+++ b/App/inc/ROOTMinimizer.h
@@ -41,15 +41,27 @@ public:
     //! return pointer to created minimizer
     ROOT::Math::Minimizer *getROOTMinimizer() { return m_root_minimizer; }
 
+    //! get number of variables to fit
+    virtual size_t getNumberOfVariables() const { return m_root_minimizer->NDim(); }
+
     //! return minimum function value
-    virtual double getMinValue() { return m_root_minimizer->MinValue(); }
+    virtual double getMinValue() const { return m_root_minimizer->MinValue(); }
 
     //! return value of variable corresponding the minimum of the function
-    virtual double getValueOfVariableAtMinimum(size_t i) {
-        if(i >= m_root_minimizer->NDim() ) throw OutOfBoundsException("ROOTMinimizer::getVariableAtMinimum() -> Wrong number of the variable");
+    virtual double getValueOfVariableAtMinimum(size_t i) const {
+        if(i >= getNumberOfVariables() ) throw OutOfBoundsException("ROOTMinimizer::getValueOfVariableAtMinimum() -> Wrong number of the variable");
         return m_root_minimizer->X()[i];
     }
 
+    //! return value of variable corresponding the minimum of the function
+    virtual double getErrorOfVariable(size_t i) const {
+        if(i >= getNumberOfVariables() ) throw OutOfBoundsException("ROOTMinimizer::getErrorOfVariable() -> Wrong number of the variable");
+        return m_root_minimizer->Errors()[i];
+    }
+
+    //! printing results
+    virtual void printResults() const;
+
 private:
     ROOT::Math::Minimizer *m_root_minimizer;
     ROOT::Math::Functor *m_fcn;
diff --git a/App/inc/TestPerformance.h b/App/inc/TestPerformance.h
index 6c78d35a76159164e9ad27bf5870a208a6d33489..a75bbc8cd8f16f9a0cd8e6d467624a4ff443e1f6 100644
--- a/App/inc/TestPerformance.h
+++ b/App/inc/TestPerformance.h
@@ -56,9 +56,6 @@ private:
     //! return delimeter between columns
     std::string get_delimeter() { return std::string(" | "); }
 
-    //! adjust string length to requested
-    std::string adjust_string_length(std::string name, int length);
-
     std::map<std::string, std::string > m_performance_info; //!< holds system information
     performance_tests_t m_tests; //!< list of tests for performance measurements
 
diff --git a/App/src/FitSuiteHelper.cpp b/App/src/FitSuiteHelper.cpp
index 29bd1f5b4ea422456939a742295c3a53b84b1444..a2416de7bfd28abd1d8587d7ddc77f077b0d1d91 100644
--- a/App/src/FitSuiteHelper.cpp
+++ b/App/src/FitSuiteHelper.cpp
@@ -2,6 +2,7 @@
 #include "FitSuiteHelper.h"
 #include "TreeEventStructure.h"
 #include "IsGISAXSTools.h"
+#include "ROOTMinimizer.h"
 
 #include "TCanvas.h"
 #include "TPaveText.h"
@@ -9,36 +10,85 @@
 #include "TROOT.h"
 #include "TFile.h"
 #include "TTree.h"
+#include "Utils.h"
 
+#include <iomanip>
 
 /* ************************************************************************* */
-// draw results of fit iteration in ROOT's canvas
+// print results of fit iteration
 /* ************************************************************************* */
-void FitSuiteObserverDraw::update(IObservable *subject)
+void FitSuiteObserverPrint::update(IObservable *subject)
 {
     FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject);
-    if( !fitSuite ) throw NullPointerException("FitSuiteObserverDraw::update() -> Error! Can't cast FitSuite");
+    if( !fitSuite ) throw NullPointerException("FitSuiteObserverPrint::update() -> Error! Can't cast FitSuite");
 
-    std::cout << "FitObserver: " << " ncall" << m_ncall << " chi2:" << fitSuite->getChiSquaredModule()->getValue();
     // printing parameter values
-    for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) {
-        std::cout << " " << (*it)->getName() << " " << (*it)->getValue();
-        //            std::cout << *(*it);
+    std::cout << "FitSuiteObserverPrint::update() -> Info."
+              << " NumberOfVariables:" << fitSuite->getMinimizer()->getNumberOfVariables()
+              << " NCall:" << fitSuite->getNCall()
+              << " Chi2:" << std::scientific << std::setprecision(8) << fitSuite->getChiSquaredModule()->getValue() << std::endl;
+
+    int npar(0);
+    for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it, ++npar) {
+        std::cout << "   # "<< npar << " ";
+        std::cout << Utils::AdjustStringLength((*it)->getName(), 30)
+                  << " value:" << std::scientific << std::setprecision(8) << (*it)->getValue()
+                  << std::endl;
     }
-    std::cout << std::endl;
+
+    if(fitSuite->isLastIteration()) {
+        fitSuite->getMinimizer()->printResults();
+    }
+}
+
+
+/* ************************************************************************* */
+// draw results of fit iteration in ROOT's canvas
+/* ************************************************************************* */
+void FitSuiteObserverDraw::update(IObservable *subject)
+{
+    FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject);
+    if( !fitSuite ) throw NullPointerException("FitSuiteObserverDraw::update() -> Error! Can't cast FitSuite");
 
     TCanvas *c1 = dynamic_cast<TCanvas *>( gROOT->FindObject(m_canvas_name.c_str()) );
-    if(!c1) throw NullPointerException("FitSuiteObserverDraw::update() -> No access to canvas");
-    c1->cd(3);
+    if(!c1) {
+        std::cout << " FitSuiteObserverDraw::update() -> Info. No canvas with name '" << m_canvas_name << "', creating one" << std::endl;
+        c1 = new TCanvas(m_canvas_name.c_str(), m_canvas_name.c_str(), 768, 1024);
+        c1->Divide(2,3);
+    }
+    IsGISAXSTools::resetMinimumAndMaximum();
+    // drawing real data
+    c1->cd(1);
+    gPad->SetLogz();
+    gPad->SetLeftMargin(0.12);
+    gPad->SetRightMargin(0.12);
+    IsGISAXSTools::drawOutputDataInPad(*fitSuite->getChiSquaredModule()->getRealData(), "CONT4 Z", "Real data");
+    // drawing simulated data
+    c1->cd(2);
     gPad->SetLogz();
+    gPad->SetLeftMargin(0.12);
+    gPad->SetRightMargin(0.12);
     IsGISAXSTools::drawOutputDataInPad(*fitSuite->getChiSquaredModule()->getSimulationData(), "CONT4 Z", "current simulated data");
+    // simple difference
+    c1->cd(3);
+    gPad->SetLogz();
+    gPad->SetLeftMargin(0.12);
+    gPad->SetRightMargin(0.12);
+    IsGISAXSTools::setMinimum(10.);
+    IsGISAXSTools::drawOutputDataRelativeDifference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "COLZ", "relative difference");
+    // chi2 difference
     c1->cd(4);
-    IsGISAXSTools::drawOutputDataDifference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "CONT4 Z", "difference");
-    c1->cd(5);
+    gPad->SetLogz();
+    gPad->SetLeftMargin(0.12);
+    gPad->SetRightMargin(0.12);
+    IsGISAXSTools::setMinimum(0.0000001);
+    IsGISAXSTools::setMaximum(1.0);
+    IsGISAXSTools::drawOutputDataChi2Difference2D(*fitSuite->getChiSquaredModule()->getSimulationData(), *fitSuite->getChiSquaredModule()->getRealData(), "COLZ", "relative chi2 difference");
 
+    c1->cd(5);
     TPaveText *pt = new TPaveText(.05,.1,.95,.8);
     char str[256];
-    sprintf(str,"Iteration %d",m_ncall);
+    sprintf(str,"Iteration %d", fitSuite->getNCall());
     pt->AddText(str);
     sprintf(str,"chi2 %e",fitSuite->getChiSquaredModule()->getValue());
     pt->AddText(str);
@@ -49,7 +99,6 @@ void FitSuiteObserverDraw::update(IObservable *subject)
     }
     pt->Draw();
 
-    m_ncall++;
 }
 
 
@@ -63,7 +112,6 @@ void FitSuiteObserverWriteTree::update(IObservable *subject)
     FitSuite *fitSuite = dynamic_cast<FitSuite *>(subject);
     if( !fitSuite ) throw NullPointerException("FitSuiteObserverWriteTree::update() -> Error! Can't cast FitSuite");
 
-    std::cout << "FitObserver: " << " ncall" << m_ncall << " chi2:" << fitSuite->getChiSquaredModule()->getValue();
     // printing parameter values
     for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) {
         std::cout << " " << (*it)->getName() << " " << (*it)->getValue();
@@ -73,7 +121,7 @@ void FitSuiteObserverWriteTree::update(IObservable *subject)
     // preparing root file for writing
     // if it is first call the file will be opened in 'recreate' mode, otherwise in 'update' mode
     TFile *top(0);
-    if(m_ncall == 0) {
+    if(fitSuite->getNCall() == 0) {
         top = new TFile(m_file_name.c_str(),"RECREATE");
     } else {
         top = new TFile(m_file_name.c_str(),"UPDATE");
@@ -82,7 +130,6 @@ void FitSuiteObserverWriteTree::update(IObservable *subject)
         throw RuntimeErrorException("FitSuiteObserverWriteTree::update() -> Can't open file "+ m_file_name + " for writing");
     }
 
-
     // data object to write in the tree
     TreeEventFitData *event = new TreeEventFitData();
 
@@ -107,7 +154,7 @@ void FitSuiteObserverWriteTree::update(IObservable *subject)
         event->parvalues.push_back( (*it)->getValue() );
         event->parnames.push_back( (*it)->getName().c_str() );
     }
-    event->niter = m_ncall;
+    event->niter = fitSuite->getNCall();
 
     // appending data to the tree
     tree->Fill();
@@ -115,7 +162,5 @@ void FitSuiteObserverWriteTree::update(IObservable *subject)
     top->Close();
     delete top; // there is no need to delete tree since ROOT file takes care about all objects opened afterwards
     delete event;
-
-    m_ncall++;
 }
 
diff --git a/App/src/IsGISAXSTools.cpp b/App/src/IsGISAXSTools.cpp
index c58db4b532ca104c6f308dd6c7f17cb59326ce5f..ddedfbf3ebb9e3f517a3a18935ef7b831e226996 100644
--- a/App/src/IsGISAXSTools.cpp
+++ b/App/src/IsGISAXSTools.cpp
@@ -241,7 +241,7 @@ void IsGISAXSTools::drawOutputDataDifference1D(const OutputData<double> &left, c
 /* ************************************************************************* */
 // draw relative difference of two 2D OutputData sets
 /* ************************************************************************* */
-void IsGISAXSTools::drawOutputDataDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title)
+void IsGISAXSTools::drawOutputDataRelativeDifference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title)
 {
     if(!gPad) {
         throw NullPointerException("IsGISAXSTools::drawOutputDataDifference2D -> Error! No canvas exists.");
@@ -260,6 +260,31 @@ void IsGISAXSTools::drawOutputDataDifference2D(const OutputData<double> &left, c
 }
 
 
+/* ************************************************************************* */
+// draw relative chi2 difference of two 2D OutputData sets
+/* ************************************************************************* */
+void IsGISAXSTools::drawOutputDataChi2Difference2D(const OutputData<double> &left, const OutputData<double> &right, const std::string &draw_options, const std::string &histogram_title)
+{
+    if(!gPad) {
+        throw NullPointerException("IsGISAXSTools::drawOutputDataDifference2D -> Error! No canvas exists.");
+    }
+    OutputData<double> *left_clone = left.clone();
+    OutputData<double> *right_clone = right.clone();
+
+    *left_clone -= *right_clone;
+    OutputData<double> *tmp = left_clone->clone();
+
+    *left_clone *= *tmp;
+    left_clone->scaleAll(1./left_clone->totalSum());
+
+    IsGISAXSTools::drawOutputDataInPad(*left_clone, draw_options, histogram_title);
+
+    delete left_clone;
+    delete right_clone;
+    delete tmp;
+}
+
+
 /* ************************************************************************* */
 // write output data (1D or 2D) in ASCII file
 /* ************************************************************************* */
diff --git a/App/src/ROOTMinimizer.cpp b/App/src/ROOTMinimizer.cpp
index fc3c092b239db068b0557bd53f63effc2fbd0e5b..0970467a40646da4b980c388b691d9f802c3a414 100644
--- a/App/src/ROOTMinimizer.cpp
+++ b/App/src/ROOTMinimizer.cpp
@@ -1,6 +1,7 @@
 #include "ROOTMinimizer.h"
 #include "Exceptions.h"
-
+#include "Utils.h"
+#include <iomanip>
 
 ROOTMinimizer::ROOTMinimizer(const std::string &minimizer_name, const std::string &algo_type) : m_fcn(0)
 {
@@ -50,3 +51,24 @@ void ROOTMinimizer::setFunction(boost::function<double(const double *)> fcn, int
     m_root_minimizer->SetFunction(*m_fcn);
 }
 
+
+/* ************************************************************************* */
+// print results
+/* ************************************************************************* */
+void ROOTMinimizer::printResults() const
+{
+    std::cout << "ROOTMinimizer::printResults() -> "
+    << " NumberOfVariables:" << getNumberOfVariables()
+    << " NCall:" << m_root_minimizer->NCalls()
+    << " Chi2:" << std::scientific << std::setprecision(8) << getMinValue() << std::endl;
+
+    for(size_t i=0; i<getNumberOfVariables(); ++i) {
+        std::cout << "   #" << i
+                  << " '" << Utils::AdjustStringLength(m_root_minimizer->VariableName(i), 30) << "' "
+                  << " value:" << getValueOfVariableAtMinimum(i)
+                  << " error:" << getErrorOfVariable(i) << std::endl;
+    }
+//    m_root_minimizer->PrintResults();
+}
+
+
diff --git a/App/src/TestFittingModule.cpp b/App/src/TestFittingModule.cpp
index 51c3c99bcb61bb6ff11224244583687f6c9467d0..4d1b8b620a6cd2f4ccc6d42e81e1ca5e1b7dbfc4 100644
--- a/App/src/TestFittingModule.cpp
+++ b/App/src/TestFittingModule.cpp
@@ -25,8 +25,6 @@
 #include "TPaveText.h"
 
 
-
-
 TestFittingModule::TestFittingModule()
 : mp_exact_data(0)
 , mp_real_data(0)
@@ -49,28 +47,16 @@ TestFittingModule::~TestFittingModule()
 
 void TestFittingModule::execute()
 {
-
     // initializing data
     initializeSample();
     initializeExperiment();
     generateRealData(0.1);
 
-//    mp_sample->print_structure();
-//    ParameterPool *pool = mp_sample->createParameterTree();
-//    std::cout << *pool << std::endl;
-//    return;
-
     // drawing initial data
     std::string canvas_name("TestFittingModule_c1");
-    TCanvas *c1 = new TCanvas(canvas_name.c_str(), "Test of the fitting suite", 768, 1024);
-    c1->Divide(2,3);
-    IsGISAXSTools::setMinimum(1.);
-    // exact data
-    c1->cd(1); gPad->SetLogz();
+    TCanvas *c1 = new TCanvas(canvas_name.c_str(), "Test of the fitting suite", 800, 600);
+    c1->cd(); gPad->SetLogz();
     IsGISAXSTools::drawOutputDataInPad(*mp_exact_data, "CONT4 Z", "exact data");
-    // real data
-    c1->cd(2); gPad->SetLogz();
-    IsGISAXSTools::drawOutputDataInPad(*mp_real_data, "CONT4 Z", "real data");
 \
     // setting fitSuite
     FitSuite *fitSuite = new FitSuite();
@@ -80,39 +66,40 @@ void TestFittingModule::execute()
     fitSuite->addFitParameter("*/MultiLayer/Layer0/thickness", 12*Units::nanometer, 2*Units::nanometer, TRange<double>(1.0, 20.0) );
     fitSuite->addFitParameter("*/FormFactorCylinder/radius", 2*Units::nanometer, 2*Units::nanometer, TRange<double>(1.0, 20.0) );
 
-    FitSuiteObserverDraw *drawObserver = new FitSuiteObserverDraw(canvas_name);
-    fitSuite->attachObserver(drawObserver);
-    FitSuiteObserverWriteTree *writeObserver = new FitSuiteObserverWriteTree("fitsuite.root");
-    fitSuite->attachObserver(writeObserver);
+    fitSuite->attachObserver( new FitSuiteObserverPrint() );
+    fitSuite->attachObserver( new FitSuiteObserverDraw() );
+    fitSuite->attachObserver( new FitSuiteObserverWriteTree() );
 
     fitSuite->runFit();
-    delete drawObserver;
-    delete writeObserver;
 
-    std::cout << "------ RESULTS ---------" << std::endl;
-    std::cout << "FitSuite > MinValue:" << fitSuite->getMinimizer()->getMinValue() << " " << fitSuite->getMinimizer()->getValueOfVariableAtMinimum(0) << std::endl;
-    for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) {
-        std::cout << *(*it) << std::endl;
-    }
-    // another way to get results
-    std::cout << "ROOTMinimizer >" << std::endl;
-    ROOTMinimizer *min = dynamic_cast<ROOTMinimizer *>(fitSuite->getMinimizer());
-    std::cout << min->getROOTMinimizer()->MinValue() << " " << min->getROOTMinimizer()->NCalls() << std::endl;
-    std::cout << min->getROOTMinimizer()->X()[0] << std::endl;
-    min->getROOTMinimizer()->PrintResults();
-
-    c1->cd(6);
-    TPaveText *pt = new TPaveText(.05,.1,.95,.8);
-    char str[256];
-    sprintf(str,"Results");
-    pt->AddText(str);
-    sprintf(str,"chi2 %e",fitSuite->getMinimizer()->getMinValue());
-    pt->AddText(str);
-    for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) {
-        sprintf(str,"%s %f", (*it)->getName().c_str(),  (*it)->getValue());
-        pt->AddText(str);
-    }
-    pt->Draw();
+    //    FitSuiteObserverWriteTree *writeObserver = new FitSuiteObserverWriteTree("fitsuite.root");
+//    delete drawObserver;
+//    delete writeObserver;
+
+//    std::cout << "------ RESULTS ---------" << std::endl;
+//    std::cout << "FitSuite > MinValue:" << fitSuite->getMinimizer()->getMinValue() << " " << fitSuite->getMinimizer()->getValueOfVariableAtMinimum(0) << std::endl;
+//    for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) {
+//        std::cout << *(*it) << std::endl;
+//    }
+//    // another way to get results
+//    std::cout << "ROOTMinimizer >" << std::endl;
+//    ROOTMinimizer *min = dynamic_cast<ROOTMinimizer *>(fitSuite->getMinimizer());
+//    std::cout << min->getROOTMinimizer()->MinValue() << " " << min->getROOTMinimizer()->NCalls() << std::endl;
+//    std::cout << min->getROOTMinimizer()->X()[0] << std::endl;
+//    min->getROOTMinimizer()->PrintResults();
+
+//    c1->cd(6);
+//    TPaveText *pt = new TPaveText(.05,.1,.95,.8);
+//    char str[256];
+//    sprintf(str,"Results");
+//    pt->AddText(str);
+//    sprintf(str,"chi2 %e",fitSuite->getMinimizer()->getMinValue());
+//    pt->AddText(str);
+//    for(FitSuite::fitparameters_t::iterator it = fitSuite->fitparams_begin(); it!=fitSuite->fitparams_end(); ++it) {
+//        sprintf(str,"%s %f", (*it)->getName().c_str(),  (*it)->getValue());
+//        pt->AddText(str);
+//    }
+//    pt->Draw();
 
 
 //    IsGISAXSTools::drawLogOutputData(*mp_exact_data, "c1_test_fitting", "fitting", "CONT4 Z", "fitting");
diff --git a/App/src/TestIsGISAXS1.cpp b/App/src/TestIsGISAXS1.cpp
index 4ed14c531fee23f9281eda511fc1dce8ddaed872..ae6450ba01b621c32fc6e3cd3117f620242ead8a 100644
--- a/App/src/TestIsGISAXS1.cpp
+++ b/App/src/TestIsGISAXS1.cpp
@@ -53,7 +53,7 @@ void TestIsGISAXS1::finalise()
     c1->cd(3);
     IsGISAXSTools::setMinimum(-0.0001);
     IsGISAXSTools::setMaximum(0.0001);
-    IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
+    IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
 
     // difference
     c1->cd(4);
diff --git a/App/src/TestIsGISAXS10.cpp b/App/src/TestIsGISAXS10.cpp
index 89f50ea0bd6f31836338c8971a139bad800e153c..c533ff4cf65339c800e0f23b73cc09a6b413fc3c 100644
--- a/App/src/TestIsGISAXS10.cpp
+++ b/App/src/TestIsGISAXS10.cpp
@@ -55,7 +55,7 @@ void TestIsGISAXS10::finalise()
     c1->cd(3);
     IsGISAXSTools::setMinimum(-0.0001);
     IsGISAXSTools::setMaximum(0.0001);
-    IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
+    IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
 
     // difference
     c1->cd(4);
diff --git a/App/src/TestIsGISAXS11.cpp b/App/src/TestIsGISAXS11.cpp
index c6e229a4900716acee43de3a6c969f51c5e4c7f9..69bfe8352d962a444108b41ebfb6251473280340 100644
--- a/App/src/TestIsGISAXS11.cpp
+++ b/App/src/TestIsGISAXS11.cpp
@@ -46,7 +46,7 @@ void TestIsGISAXS11::finalise()
     c1->cd(3);
     IsGISAXSTools::setMinimum(-0.0001);
     IsGISAXSTools::setMaximum(0.0001);
-    IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
+    IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
 
     // difference
     c1->cd(4);
diff --git a/App/src/TestIsGISAXS2.cpp b/App/src/TestIsGISAXS2.cpp
index 09d7912e4aa9e9d94d4fc71eb54be8703a7533a8..d29c37618f1c28fdef299c68831b559b8e087c81 100644
--- a/App/src/TestIsGISAXS2.cpp
+++ b/App/src/TestIsGISAXS2.cpp
@@ -62,7 +62,7 @@ void TestIsGISAXS2::finalise()
     c1->cd(3);
     IsGISAXSTools::setMinimum(-0.0001);
     IsGISAXSTools::setMaximum(0.0001);
-    IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
+    IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
 
     // difference
     c1->cd(4);
diff --git a/App/src/TestIsGISAXS3.cpp b/App/src/TestIsGISAXS3.cpp
index 7be9e00a4edfe8f4c47f9c22e61958b7471289f0..f272b359928b1412a1c7015b24a8488fffb51f82 100644
--- a/App/src/TestIsGISAXS3.cpp
+++ b/App/src/TestIsGISAXS3.cpp
@@ -76,7 +76,7 @@ void TestIsGISAXS3::finalise()
         c1->cd(3);
         IsGISAXSTools::setMinimum(-0.0001);
         IsGISAXSTools::setMaximum(0.0001);
-        IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
+        IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
 
         // difference
         c1->cd(4);
diff --git a/App/src/TestIsGISAXS9.cpp b/App/src/TestIsGISAXS9.cpp
index 631a638e96144d663a20b9b17fd0054dab6b4d77..ca0dd1b30f0ded742be933ad4935b72d52393c05 100644
--- a/App/src/TestIsGISAXS9.cpp
+++ b/App/src/TestIsGISAXS9.cpp
@@ -93,7 +93,7 @@ void TestIsGISAXS9::finalise()
         c1->cd(3);
         IsGISAXSTools::setMinimum(-0.0001);
         IsGISAXSTools::setMaximum(0.0001);
-        IsGISAXSTools::drawOutputDataDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
+        IsGISAXSTools::drawOutputDataRelativeDifference2D(*our_data, *isgi_data, "CONT4 Z", "2D Difference map");
 
         // difference
         c1->cd(4);
diff --git a/App/src/TestMesoCrystal1.cpp b/App/src/TestMesoCrystal1.cpp
index 957084a2d7b2b87125533c59b5b2bbdccacabdd3..61830b640ee20debfb4da1acb8d540994f8b5c21 100644
--- a/App/src/TestMesoCrystal1.cpp
+++ b/App/src/TestMesoCrystal1.cpp
@@ -53,10 +53,10 @@ void TestMesoCrystal1::execute()
     std::cout << (*p_param_pool) << std::endl;
 
     experiment.runSimulation();
-    double count_before_normalize = experiment.getOutputData()->total();
+    double count_before_normalize = experiment.getOutputData()->totalSum();
     experiment.normalize();
     mp_intensity_output = experiment.getOutputDataClone();
-    double total_count = mp_intensity_output->total();
+    double total_count = mp_intensity_output->totalSum();
     std::cout << "Total count in detector: " << total_count << std::endl;
     std::cout << "Scattered percentage in detector: " << 100*total_count/experiment.getBeam().getIntensity() << std::endl;
     std::cout << "Total count in detector before normalize: " << count_before_normalize << std::endl;
diff --git a/App/src/TestPerformance.cpp b/App/src/TestPerformance.cpp
index 4f03db5edc7fad42c8cc1de74a48ea109538f64a..5ec0a58e05316f9441b58a56ffa87a4aa12aedf9 100644
--- a/App/src/TestPerformance.cpp
+++ b/App/src/TestPerformance.cpp
@@ -103,11 +103,11 @@ void TestPerformance::write_performance()
     }
 
     file << m_performance_info["datime"] << get_delimeter();
-    file << std::left << adjust_string_length(m_performance_info["hostname"],10) << get_delimeter();
-    file << std::left << adjust_string_length(m_performance_info["sysinfo"],23) << get_delimeter();
+    file << std::left << Utils::AdjustStringLength(m_performance_info["hostname"],10) << get_delimeter();
+    file << std::left << Utils::AdjustStringLength(m_performance_info["sysinfo"],23) << get_delimeter();
     for(performance_tests_t::iterator it=m_tests.begin(); it!= m_tests.end(); it++) {
         std::string test_name = (*it)->m_test->getName();
-        file << std::left << adjust_string_length(m_performance_info[test_name],7) << get_delimeter();
+        file << std::left << Utils::AdjustStringLength(m_performance_info[test_name],7) << get_delimeter();
     }
     file<<std::endl;
 
@@ -117,18 +117,6 @@ void TestPerformance::write_performance()
 }
 
 
-/* ************************************************************************* */
-// adjust length of string
-/* ************************************************************************* */
-std::string TestPerformance::adjust_string_length(std::string name, int length)
-{
-    std::string newstring = name;
-    newstring.resize(length,' ');
-    return newstring;
-}
-
-
-
 /* ************************************************************************* */
 // fill system information
 /* ************************************************************************* */
diff --git a/Core/Algorithms/inc/ISquaredFunction.h b/Core/Algorithms/inc/ISquaredFunction.h
index 8d36ea8005d5a8165c4380bf82d0f3b1501268fc..fb97e0206e0bb347f3860b181f419aebd26bef1a 100644
--- a/Core/Algorithms/inc/ISquaredFunction.h
+++ b/Core/Algorithms/inc/ISquaredFunction.h
@@ -42,7 +42,8 @@ inline double DefaultSquaredFunction::calculateSquaredDifference(
 {
     double diff_squared = (simulated_value-real_value)*(simulated_value-real_value);
     if (diff_squared < Numeric::double_epsilon) return 0.0;
-    double normalization = std::max(std::abs(real_value), 1.0);
+    //double normalization = std::max(std::abs(real_value), 1.0);
+    double normalization = 1.0;
     return diff_squared/normalization;
 }
 
diff --git a/Core/Algorithms/src/ChiSquaredModule.cpp b/Core/Algorithms/src/ChiSquaredModule.cpp
index a7216f32a70e8fea79a0e8ec9d1cf2ee5745d4f9..9a279b07e54f53df7f473e4ce6cd837038aafe22 100644
--- a/Core/Algorithms/src/ChiSquaredModule.cpp
+++ b/Core/Algorithms/src/ChiSquaredModule.cpp
@@ -1,4 +1,5 @@
 #include "ChiSquaredModule.h"
+#include <iostream>
 
 ChiSquaredModule::ChiSquaredModule(const OutputData<double>& real_data)
     : mp_simulation_data(0), m_chi2_value(0)
diff --git a/Core/Tools/inc/FitSuite.h b/Core/Tools/inc/FitSuite.h
index d32224c6f40dcb76f7407b81a672a847a9693219..59bc5a1d8e68017b91fd4685101b717836a9a8f8 100644
--- a/Core/Tools/inc/FitSuite.h
+++ b/Core/Tools/inc/FitSuite.h
@@ -35,9 +35,13 @@ class FitSuite : public IObservable
 {
 public:
     typedef std::vector<FitMultiParameter *> fitparameters_t;
+
     FitSuite();
     virtual ~FitSuite();
 
+    //! clear all and prepare for the next fit
+    void clear();
+
     //! set experiment
     void setExperiment(Experiment *experiment) { m_experiment = experiment; }
 
@@ -71,11 +75,19 @@ public:
     //! get chi2 module
     const ChiSquaredModule *getChiSquaredModule() const { return m_chi2_module; }
 
+    //! if the last iteration is done
+    bool isLastIteration() { return m_is_last_iteration; }
+
+    //! get number of call
+    int getNCall() { return m_n_call; }
+
 private:
     Experiment *m_experiment; //! experiment with sample description
     IMinimizer  *m_minimizer; //! minimization engine
     ChiSquaredModule *m_chi2_module; //! module providing chi2 calculations
     fitparameters_t m_fit_params; //! vector of parameters to minimize
+    bool m_is_last_iteration;
+    int m_n_call;
 };
 
 #endif // FITSUITE_H
diff --git a/Core/Tools/inc/IMinimizer.h b/Core/Tools/inc/IMinimizer.h
index 622a06331696c5b33e28b098a576b6adc4156fa3..e18240d4a53847c57d64ba92c0606ea537459cde 100644
--- a/Core/Tools/inc/IMinimizer.h
+++ b/Core/Tools/inc/IMinimizer.h
@@ -38,11 +38,21 @@ public:
     //! run minimization
     virtual void minimize() = 0;
 
+    //! get number of variables to fit
+    virtual size_t getNumberOfVariables() const = 0;
+
     //! return minimum function value
-    virtual double getMinValue() = 0;
+    virtual double getMinValue() const = 0;
+
+    //! return pointer to the parameters values at the minimum
+    virtual double getValueOfVariableAtMinimum(size_t i) const = 0;
 
     //! return pointer to the parameters values at the minimum
-    virtual double getValueOfVariableAtMinimum(size_t i) = 0;
+    virtual double getErrorOfVariable(size_t i) const = 0;
+
+    //! print fit results
+    virtual void printResults() const = 0;
+
 };
 
 #endif // IMINIMIZER_H
diff --git a/Core/Tools/inc/OutputData.h b/Core/Tools/inc/OutputData.h
index c421bbb6eb795a64eb95f40ef9e8385ac0c2b011..e200848566e44ca82236b0bc52b34fd7827eded5 100644
--- a/Core/Tools/inc/OutputData.h
+++ b/Core/Tools/inc/OutputData.h
@@ -136,7 +136,7 @@ public:
     template <class U> U getCurrentValueOfAxis(std::string axis_name) const;
 
     //! get sum of all values in the data structure
-    T total() const;
+    T totalSum() const;
 
     // ---------
     // modifiers
@@ -183,6 +183,9 @@ const OutputData<double> &operator-=(OutputData<double> &left, const OutputData<
 //! division-assignment operator for two output data
 const OutputData<double> &operator/=(OutputData<double> &left, const OutputData<double> &right);
 
+//! multiplication-assignment operator for two output data
+const OutputData<double> &operator*=(OutputData<double> &left, const OutputData<double> &right);
+
 //! double the bin size for each dimension
 OutputData<double> *doubleBinSize(const OutputData<double> &source);
 
@@ -369,7 +372,7 @@ template <class U> inline U OutputData<T>::getCurrentValueOfAxis(std::string axi
 
 
 template<class T>
-inline T OutputData<T>::total() const
+inline T OutputData<T>::totalSum() const
 {
     T total = 0;
     for (size_t i=0; i<m_data_size; ++i) {
diff --git a/Core/Tools/inc/Utils.h b/Core/Tools/inc/Utils.h
index 0dcf7681dafdc5df524441c4e454b7393275314a..ca3e752c53c7b51b08162548ae6a89cc630ead3f 100644
--- a/Core/Tools/inc/Utils.h
+++ b/Core/Tools/inc/Utils.h
@@ -99,64 +99,15 @@ private:
 };
 
 
-
-////- -------------------------------------------------------------------
-////! @class StringSampleHelper
-////! @brief Definition of StringSampleHelper to build the string representing
-////! path in ISample parameter tree
-////!
-////! See example in ICompositeSample::getParameterTree()
-////- -------------------------------------------------------------------
-//class StringSampleHelper
-//{
-//public:
-//    typedef std::vector<StringUsageMap > nstringmap_t;
-//    typedef nstringmap_t::iterator iterator_t;
-
-//    StringSampleHelper(){}
-//    ~StringSampleHelper(){}
-
-//    void add(std::string name, int dirlevel) {
-
-//        while(dirlevel > (int)m_stringstack.size()-1) {
-//            m_stringstack.push_back(StringUsageMap());
-//        }
-
-//        while(dirlevel < (int)m_stringstack.size()-1) {
-//            m_stringstack.pop_back();
-//        }
-
-//        m_stringstack[dirlevel].add(name);
-//    }
-
-//    //! return current path in parameter tree, like /multilayer/interface3/roughness/sigma
-//    std::string get_path()
-//    {
-//        std::string result;
-//        for(size_t i_level=0; i_level<m_stringstack.size(); i_level++) {
-//            std::string currentLevelName = m_stringstack[i_level].get_current();
-//            StringUsageMap &strUsageMap = m_stringstack[i_level];
-//            // if such name has been already used on that level, built the level name using index number
-//            std::ostringstream os;
-//            int nOfUsage = strUsageMap[currentLevelName];
-//            result += std::string("/") + currentLevelName;
-//            if(nOfUsage != 1) {
-//                os<<nOfUsage;
-//                result += os.str();
-//            }
-//        }
-//        return result;
-//    }
-
-//    iterator_t begin() { return m_stringstack.begin(); }
-//    iterator_t end() { return m_stringstack.end(); }
-//    size_t size() const { return m_stringstack.size(); }
-//    StringUsageMap &operator[](size_t i) { return m_stringstack[i]; }
-//    StringUsageMap const &operator[](size_t i) const { return m_stringstack[i]; }
-
-//protected:
-//    std::vector<StringUsageMap > m_stringstack;
-//};
+//- -------------------------------------------------------------------
+//! @brief adjust length of the string
+//- -------------------------------------------------------------------
+inline std::string AdjustStringLength(std::string name, int length)
+{
+    std::string newstring = name;
+    newstring.resize(length,' ');
+    return newstring;
+}
 
 
 }
diff --git a/Core/Tools/src/FitSuite.cpp b/Core/Tools/src/FitSuite.cpp
index 22518f148fb1dd78ff8f33efa47cdc891463c3a4..5b828416c8095ff3a48d97d4dc057886acfd825a 100644
--- a/Core/Tools/src/FitSuite.cpp
+++ b/Core/Tools/src/FitSuite.cpp
@@ -7,18 +7,28 @@
 #include "ChiSquaredModule.h"
 
 
-FitSuite::FitSuite() : m_experiment(0), m_minimizer(0), m_chi2_module(0)
+FitSuite::FitSuite() : m_experiment(0), m_minimizer(0), m_chi2_module(0), m_is_last_iteration(false), m_n_call(0)
 {
 }
 
 
 FitSuite::~FitSuite()
+{
+    clear();
+}
+
+
+/* ************************************************************************* */
+// clear all and prepare for the next fit
+/* ************************************************************************* */
+void FitSuite::clear()
 {
     for(fitparameters_t::iterator it = m_fit_params.begin(); it!= m_fit_params.end(); ++it) {
         delete (*it);
     }
     delete m_minimizer;
     delete m_chi2_module;
+    m_is_last_iteration = false;
 }
 
 
@@ -102,6 +112,7 @@ void FitSuite::runFit()
     // seting parameters to the optimum values found by the minimizer
     for(size_t i=0; i<m_fit_params.size(); ++i) m_fit_params[i]->setValue(m_minimizer->getValueOfVariableAtMinimum(i));
 
+    m_is_last_iteration = true;
     notifyObservers();
 }
 
@@ -111,6 +122,10 @@ void FitSuite::runFit()
 /* ************************************************************************* */
 double FitSuite::functionToMinimize(const double *pars_current_values)
 {
+    if( m_fit_params.size() != m_minimizer->getNumberOfVariables() ) {
+        throw RuntimeErrorException("FitSuite::functionToMinimize() -> Error! Wrong number of parameters (probably missed FitSuite's initialization).");
+    }
+
     // set fitting parameters to values suggested by the minimizer
     for(size_t i=0; i<m_fit_params.size(); ++i) m_fit_params[i]->setValue(pars_current_values[i]);
 
@@ -120,9 +135,8 @@ double FitSuite::functionToMinimize(const double *pars_current_values)
     const OutputData<double> *p_simulated_data = m_experiment->getOutputData();
     double chi_squared = m_chi2_module->calculateChiSquared(p_simulated_data);
 
-    std::cout << "chi squared = " << chi_squared << std::endl;
-
     notifyObservers();
+    m_n_call++;
     return chi_squared;
 }
 
diff --git a/Core/Tools/src/OutputData.cpp b/Core/Tools/src/OutputData.cpp
index 53dfbf8af35b74e209dbe2540be0f94415b63d56..57f69930c8780ea5d0e5af9e15a2338b9b2e9e28 100644
--- a/Core/Tools/src/OutputData.cpp
+++ b/Core/Tools/src/OutputData.cpp
@@ -231,6 +231,8 @@ void MultiIndex::clear()
 /* ************************************************************************* */
 const OutputData<double> &operator+=(OutputData<double> &left, const OutputData<double> &right)
 {
+    if( &left == &right) throw LogicErrorException("OutputData &operator+=() -> Error. Left And right can't be the same");
+
     size_t total_size = left.getAllocatedSize();
     if (right.getAllocatedSize()!= total_size) {
         throw LogicErrorException("OutputData<double> &operator+=() -> Error! Cannot add OutputData objects of different size.");
@@ -250,6 +252,8 @@ const OutputData<double> &operator+=(OutputData<double> &left, const OutputData<
 /* ************************************************************************* */
 const OutputData<double> &operator-=(OutputData<double> &left, const OutputData<double> &right)
 {
+    if( &left == &right) throw LogicErrorException("OutputData &operator-=() -> Error. Left And right can't be the same");
+
     size_t total_size = left.getAllocatedSize();
     if (right.getAllocatedSize()!= total_size) {
         throw LogicErrorException("OutputData<double> &operator-=() -> Error! Cannot substract OutputData objects of different size.");
@@ -269,6 +273,8 @@ const OutputData<double> &operator-=(OutputData<double> &left, const OutputData<
 /* ************************************************************************* */
 const OutputData<double> &operator/=(OutputData<double> &left, const OutputData<double> &right)
 {
+    if( &left == &right) throw LogicErrorException("OutputData &operator/=() -> Error. Left And right can't be the same");
+
     size_t total_size = left.getAllocatedSize();
     if (right.getAllocatedSize()!= total_size) {
         throw LogicErrorException("OutputData<double> &operator/=() -> Error! Cannot substract OutputData objects of different size.");
@@ -292,6 +298,28 @@ const OutputData<double> &operator/=(OutputData<double> &left, const OutputData<
     return left;
 }
 
+/* ************************************************************************* */
+// multiplication-assignment operator for two output data
+/* ************************************************************************* */
+const OutputData<double> &operator*=(OutputData<double> &left, const OutputData<double> &right)
+{
+    if( &left == &right) throw LogicErrorException("OutputData &operator*=() -> Error. Left And right can't be the same");
+
+    size_t total_size = left.getAllocatedSize();
+    if (right.getAllocatedSize()!= total_size) {
+        throw LogicErrorException("OutputData<double> &operator/=() -> Error! Cannot substract OutputData objects of different size.");
+    }
+    left.resetIndex();
+    right.resetIndex();
+    while ( right.hasNext() ) {
+        double xleft = left.currentValue();
+        double xright = right.currentValue();
+        left.currentValue() = xleft*xright;
+        left.next(); right.next();
+    }
+    return left;
+}
+
 /* ************************************************************************* */
 // double the bin size for each dimension
 /* ************************************************************************* */